Enable `robustness` transform by default in `tint`.

Update the `tint` command to always enable `robustness`. The
`robustness` option is removed from the list of possible transforms
which can be requested. A new `--disable-robustness` flag is added in
order to generate code with robustness disabled.

Change-Id: I8e1c5d1247738e33ffac035e5c786863f152de03
Bug: 378726537
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/216996
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 854bc70..6bf696d 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -148,11 +148,12 @@
     bool validate = false;
     bool print_hash = false;
     bool dump_inspector_bindings = false;
-    bool enable_robustness = false;
     bool emit_single_entry_point = false;
 
     bool rename_all = false;
 
+    bool enable_robustness = true;
+
     bool dump_ir = false;
     bool use_ir = false;
     bool use_ir_reader = false;
@@ -385,7 +386,6 @@
 Available transforms:
     first_index_offset
     renamer
-    robustness
     substitute_override
 )",
                                   ShortName{"t"});
@@ -397,6 +397,13 @@
         }
     });
 
+    auto& disable_robustness =
+        options.Add<BoolOption>("disable-robustness", "Disable the robustness transform");
+    TINT_DEFER({
+        auto disable = disable_robustness.value.value_or(false);
+        opts->enable_robustness = !disable;
+    });
+
 #if TINT_BUILD_HLSL_WRITER
     auto& fxc_path =
         options.Add<StringOption>("fxc", R"(Path to FXC dll, used to validate HLSL output.
@@ -694,8 +701,6 @@
             transform_manager.Add<tint::ast::transform::FirstIndexOffset>();
         } else if (name == "renamer") {
             transform_manager.Add<tint::ast::transform::Renamer>();
-        } else if (name == "robustness") {
-            options.enable_robustness = true;
         } else if (name == "substitute_override") {
             auto override_names = inspector.GetNamedOverrideIds();
 
diff --git a/test/tint/access/let/matrix.wgsl.expected.glsl b/test/tint/access/let/matrix.wgsl.expected.glsl
index e43a61e..758dcb1 100644
--- a/test/tint/access/let/matrix.wgsl.expected.glsl
+++ b/test/tint/access/let/matrix.wgsl.expected.glsl
@@ -7,7 +7,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  vec3 v = m[1];
-  float f = v[1];
+  vec3 v = m[1u];
+  float f = v[1u];
   v_1.inner = f;
 }
diff --git a/test/tint/access/let/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/access/let/matrix.wgsl.expected.ir.dxc.hlsl
index 517c2e3..cb7f63a 100644
--- a/test/tint/access/let/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/access/let/matrix.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  float3 v = m[int(1)];
+  float3 v = m[1u];
   float f = v.y;
   s.Store(0u, asuint(f));
 }
diff --git a/test/tint/access/let/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/access/let/matrix.wgsl.expected.ir.fxc.hlsl
index 517c2e3..cb7f63a 100644
--- a/test/tint/access/let/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/access/let/matrix.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  float3 v = m[int(1)];
+  float3 v = m[1u];
   float f = v.y;
   s.Store(0u, asuint(f));
 }
diff --git a/test/tint/access/let/matrix.wgsl.expected.ir.msl b/test/tint/access/let/matrix.wgsl.expected.ir.msl
index 5481c31..b2a76c5 100644
--- a/test/tint/access/let/matrix.wgsl.expected.ir.msl
+++ b/test/tint/access/let/matrix.wgsl.expected.ir.msl
@@ -8,7 +8,7 @@
 kernel void tint_symbol(device float* s [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.s=s};
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  float3 const v = m[1];
-  float const f = v[1];
+  float3 const v = m[1u];
+  float const f = v[1u];
   (*tint_module_vars.s) = f;
 }
diff --git a/test/tint/access/var/matrix.spvasm.expected.glsl b/test/tint/access/var/matrix.spvasm.expected.glsl
index b90b6a7..074e0e7 100644
--- a/test/tint/access/var/matrix.spvasm.expected.glsl
+++ b/test/tint/access/var/matrix.spvasm.expected.glsl
@@ -2,7 +2,7 @@
 
 void main_1() {
   mat3 m = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
-  float x_16 = m[1].y;
+  float x_16 = m[1u].y;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/access/var/matrix.spvasm.expected.ir.dxc.hlsl b/test/tint/access/var/matrix.spvasm.expected.ir.dxc.hlsl
index eda6d30..7e4076f 100644
--- a/test/tint/access/var/matrix.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/access/var/matrix.spvasm.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 void main_1() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float x_16 = m[int(1)].y;
+  float x_16 = m[1u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/access/var/matrix.spvasm.expected.ir.fxc.hlsl b/test/tint/access/var/matrix.spvasm.expected.ir.fxc.hlsl
index eda6d30..7e4076f 100644
--- a/test/tint/access/var/matrix.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/access/var/matrix.spvasm.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 void main_1() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float x_16 = m[int(1)].y;
+  float x_16 = m[1u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/access/var/matrix.spvasm.expected.ir.msl b/test/tint/access/var/matrix.spvasm.expected.ir.msl
index b99cec7..542f727 100644
--- a/test/tint/access/var/matrix.spvasm.expected.ir.msl
+++ b/test/tint/access/var/matrix.spvasm.expected.ir.msl
@@ -3,7 +3,7 @@
 
 void main_1() {
   float3x3 m = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
-  float const x_16 = m[1][1u];
+  float const x_16 = m[1u][1u];
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/access/var/matrix.spvasm.expected.spvasm b/test/tint/access/var/matrix.spvasm.expected.spvasm
index 9dbf0f9..c7989cf 100644
--- a/test/tint/access/var/matrix.spvasm.expected.spvasm
+++ b/test/tint/access/var/matrix.spvasm.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 23
+; Bound: 21
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -19,22 +19,20 @@
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
          %10 = OpConstantNull %mat3v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-%_ptr_Function_float = OpTypePointer Function %float
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
+%_ptr_Function_float = OpTypePointer Function %float
      %main_1 = OpFunction %void None %3
           %4 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %10
-         %11 = OpAccessChain %_ptr_Function_v3float %m %int_1
+         %11 = OpAccessChain %_ptr_Function_v3float %m %uint_1
          %15 = OpAccessChain %_ptr_Function_float %11 %uint_1
        %x_16 = OpLoad %float %15 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %3
-         %21 = OpLabel
-         %22 = OpFunctionCall %void %main_1
+         %19 = OpLabel
+         %20 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/access/var/matrix.wgsl.expected.glsl b/test/tint/access/var/matrix.wgsl.expected.glsl
index 9eb5738..4007906 100644
--- a/test/tint/access/var/matrix.wgsl.expected.glsl
+++ b/test/tint/access/var/matrix.wgsl.expected.glsl
@@ -7,7 +7,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3 m = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
-  vec3 v = m[1];
-  float f = v[1];
+  vec3 v = m[1u];
+  float f = v[1u];
   v_1.inner = f;
 }
diff --git a/test/tint/access/var/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/access/var/matrix.wgsl.expected.ir.dxc.hlsl
index 9be57b5..4a329b7 100644
--- a/test/tint/access/var/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/access/var/matrix.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float3 v = m[int(1)];
+  float3 v = m[1u];
   float f = v.y;
   s.Store(0u, asuint(f));
 }
diff --git a/test/tint/access/var/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/access/var/matrix.wgsl.expected.ir.fxc.hlsl
index 9be57b5..4a329b7 100644
--- a/test/tint/access/var/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/access/var/matrix.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float3 v = m[int(1)];
+  float3 v = m[1u];
   float f = v.y;
   s.Store(0u, asuint(f));
 }
diff --git a/test/tint/access/var/matrix.wgsl.expected.ir.msl b/test/tint/access/var/matrix.wgsl.expected.ir.msl
index 611df9e..e2b1989 100644
--- a/test/tint/access/var/matrix.wgsl.expected.ir.msl
+++ b/test/tint/access/var/matrix.wgsl.expected.ir.msl
@@ -8,7 +8,7 @@
 kernel void tint_symbol(device float* s [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.s=s};
   float3x3 m = float3x3(0.0f);
-  float3 const v = m[1];
-  float const f = v[1];
+  float3 const v = m[1u];
+  float const f = v[1u];
   (*tint_module_vars.s) = f;
 }
diff --git a/test/tint/access/var/matrix.wgsl.expected.spvasm b/test/tint/access/var/matrix.wgsl.expected.spvasm
index 9cb451e..6a2e4d7 100644
--- a/test/tint/access/var/matrix.wgsl.expected.spvasm
+++ b/test/tint/access/var/matrix.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 23
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -29,15 +29,14 @@
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
          %13 = OpConstantNull %mat3v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
        %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
        %main = OpFunction %void None %7
           %8 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function %13
-         %14 = OpAccessChain %_ptr_Function_v3float %m %int_1
+         %14 = OpAccessChain %_ptr_Function_v3float %m %uint_1
           %v = OpLoad %v3float %14 None
           %f = OpCompositeExtract %float %v 1
          %20 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
diff --git a/test/tint/array/assign_to_function_var.wgsl.expected.ir.msl b/test/tint/array/assign_to_function_var.wgsl.expected.ir.msl
index 978fdfb..fc71736 100644
--- a/test/tint/array/assign_to_function_var.wgsl.expected.ir.msl
+++ b/test/tint/array/assign_to_function_var.wgsl.expected.ir.msl
@@ -24,6 +24,9 @@
   device S* src_storage;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int4, 4> tint_symbol_1;
 };
@@ -60,6 +63,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/array/assign_to_function_var.wgsl.expected.msl b/test/tint/array/assign_to_function_var.wgsl.expected.msl
index 47d7516..872caa8 100644
--- a/test/tint/array/assign_to_function_var.wgsl.expected.msl
+++ b/test/tint/array/assign_to_function_var.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   tint_array<int4, 4> src_private;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int4, 4>* const tint_symbol_5) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_5))[i] = int4(0);
   }
diff --git a/test/tint/array/assign_to_private_var.wgsl.expected.ir.msl b/test/tint/array/assign_to_private_var.wgsl.expected.ir.msl
index 13c9933..27c0213 100644
--- a/test/tint/array/assign_to_private_var.wgsl.expected.ir.msl
+++ b/test/tint/array/assign_to_private_var.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   thread tint_array<tint_array<tint_array<int, 2>, 3>, 4>* dst_nested;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int4, 4> tint_symbol_1;
 };
@@ -60,6 +63,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/array/assign_to_private_var.wgsl.expected.msl b/test/tint/array/assign_to_private_var.wgsl.expected.msl
index 97298ab..fecfa2b 100644
--- a/test/tint/array/assign_to_private_var.wgsl.expected.msl
+++ b/test/tint/array/assign_to_private_var.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   tint_array<int4, 4> src_private;
   tint_array<int4, 4> dst;
@@ -22,6 +25,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int4, 4>* const tint_symbol_5) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_5))[i] = int4(0);
   }
diff --git a/test/tint/array/assign_to_storage_var.wgsl.expected.ir.msl b/test/tint/array/assign_to_storage_var.wgsl.expected.ir.msl
index a5d2af7..184604a 100644
--- a/test/tint/array/assign_to_storage_var.wgsl.expected.ir.msl
+++ b/test/tint/array/assign_to_storage_var.wgsl.expected.ir.msl
@@ -30,6 +30,9 @@
   device S_nested* dst_nested;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int4, 4> tint_symbol_1;
 };
@@ -64,6 +67,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/array/assign_to_storage_var.wgsl.expected.msl b/test/tint/array/assign_to_storage_var.wgsl.expected.msl
index fde2a43..7ce6ea8 100644
--- a/test/tint/array/assign_to_storage_var.wgsl.expected.msl
+++ b/test/tint/array/assign_to_storage_var.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   tint_array<int4, 4> src_private;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int4, 4>* const tint_symbol_5) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_5))[i] = int4(0);
   }
diff --git a/test/tint/array/assign_to_subexpr.wgsl.expected.glsl b/test/tint/array/assign_to_subexpr.wgsl.expected.glsl
index 044ec84..0aa0a19 100644
--- a/test/tint/array/assign_to_subexpr.wgsl.expected.glsl
+++ b/test/tint/array/assign_to_subexpr.wgsl.expected.glsl
@@ -15,11 +15,11 @@
   S dst_struct = S(int[4](0, 0, 0, 0));
   int dst_array[2][4] = int[2][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0));
   dst_struct.arr = src;
-  dst_array[1] = src;
+  dst_array[1u] = src;
   dst = src;
   dst_struct.arr = src;
-  dst_array[0] = src;
-  return ((dst[0] + dst_struct.arr[0]) + dst_array[0][0]);
+  dst_array[0u] = src;
+  return ((dst[0u] + dst_struct.arr[0u]) + dst_array[0u][0u]);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.dxc.hlsl b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.dxc.hlsl
index 72d65a4..b6a784e 100644
--- a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.dxc.hlsl
@@ -10,11 +10,11 @@
   S dst_struct = (S)0;
   int dst_array[2][4] = (int[2][4])0;
   dst_struct.arr = src;
-  dst_array[int(1)] = src;
+  dst_array[1u] = src;
   tint_symbol = src;
   dst_struct.arr = src;
-  dst_array[int(0)] = src;
-  return ((tint_symbol[int(0)] + dst_struct.arr[int(0)]) + dst_array[int(0)][int(0)]);
+  dst_array[0u] = src;
+  return ((tint_symbol[0u] + dst_struct.arr[0u]) + dst_array[0u][0u]);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.fxc.hlsl b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.fxc.hlsl
index 72d65a4..b6a784e 100644
--- a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.fxc.hlsl
@@ -10,11 +10,11 @@
   S dst_struct = (S)0;
   int dst_array[2][4] = (int[2][4])0;
   dst_struct.arr = src;
-  dst_array[int(1)] = src;
+  dst_array[1u] = src;
   tint_symbol = src;
   dst_struct.arr = src;
-  dst_array[int(0)] = src;
-  return ((tint_symbol[int(0)] + dst_struct.arr[int(0)]) + dst_array[int(0)][int(0)]);
+  dst_array[0u] = src;
+  return ((tint_symbol[0u] + dst_struct.arr[0u]) + dst_array[0u][0u]);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.msl b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.msl
index c7b0190..574832a 100644
--- a/test/tint/array/assign_to_subexpr.wgsl.expected.ir.msl
+++ b/test/tint/array/assign_to_subexpr.wgsl.expected.ir.msl
@@ -30,11 +30,11 @@
   thread S* const dst_struct_ptr = (&dst_struct);
   thread tint_array<tint_array<int, 4>, 2>* const dst_array_ptr = (&dst_array);
   dst_struct.arr = src;
-  dst_array[1] = src;
+  dst_array[1u] = src;
   (*dst_ptr) = src;
   (*dst_struct_ptr).arr = src;
-  (*dst_array_ptr)[0] = src;
-  return as_type<int>((as_type<uint>(as_type<int>((as_type<uint>((*dst_ptr)[0]) + as_type<uint>((*dst_struct_ptr).arr[0])))) + as_type<uint>((*dst_array_ptr)[0][0])));
+  (*dst_array_ptr)[0u] = src;
+  return as_type<int>((as_type<uint>(as_type<int>((as_type<uint>((*dst_ptr)[0u]) + as_type<uint>((*dst_struct_ptr).arr[0u])))) + as_type<uint>((*dst_array_ptr)[0u][0u])));
 }
 
 kernel void tint_symbol(device int* s [[buffer(0)]]) {
diff --git a/test/tint/array/assign_to_subexpr.wgsl.expected.spvasm b/test/tint/array/assign_to_subexpr.wgsl.expected.spvasm
index 2d45772..fc3f02a 100644
--- a/test/tint/array/assign_to_subexpr.wgsl.expected.spvasm
+++ b/test/tint/array/assign_to_subexpr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,11 +46,10 @@
 %_ptr_Function__arr__arr_int_uint_4_uint_2 = OpTypePointer Function %_arr__arr_int_uint_4_uint_2
          %22 = OpConstantNull %_arr__arr_int_uint_4_uint_2
      %uint_0 = OpConstant %uint 0
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
         %foo = OpFunction %int None %6
           %7 = OpLabel
@@ -59,27 +58,27 @@
   %dst_array = OpVariable %_ptr_Function__arr__arr_int_uint_4_uint_2 Function %22
          %23 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_struct %uint_0
                OpStore %23 %src None
-         %25 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %int_1
+         %25 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %uint_1
                OpStore %25 %src None
                OpStore %dst %src None
          %27 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_struct %uint_0
                OpStore %27 %src None
-         %28 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %int_0
+         %28 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %uint_0
                OpStore %28 %src None
-         %30 = OpAccessChain %_ptr_Function_int %dst %int_0
-         %32 = OpLoad %int %30 None
-         %33 = OpAccessChain %_ptr_Function_int %dst_struct %uint_0 %int_0
-         %34 = OpLoad %int %33 None
-         %35 = OpIAdd %int %32 %34
-         %36 = OpAccessChain %_ptr_Function_int %dst_array %int_0 %int_0
-         %37 = OpLoad %int %36 None
-         %38 = OpIAdd %int %35 %37
-               OpReturnValue %38
+         %29 = OpAccessChain %_ptr_Function_int %dst %uint_0
+         %31 = OpLoad %int %29 None
+         %32 = OpAccessChain %_ptr_Function_int %dst_struct %uint_0 %uint_0
+         %33 = OpLoad %int %32 None
+         %34 = OpIAdd %int %31 %33
+         %35 = OpAccessChain %_ptr_Function_int %dst_array %uint_0 %uint_0
+         %36 = OpLoad %int %35 None
+         %37 = OpIAdd %int %34 %36
+               OpReturnValue %37
                OpFunctionEnd
-       %main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %int %foo
-         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %44 %43 None
+       %main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %int %foo
+         %43 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/array/assign_to_workgroup_var.wgsl.expected.ir.msl b/test/tint/array/assign_to_workgroup_var.wgsl.expected.ir.msl
index cade83f..033a240 100644
--- a/test/tint/array/assign_to_workgroup_var.wgsl.expected.ir.msl
+++ b/test/tint/array/assign_to_workgroup_var.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   threadgroup tint_array<tint_array<tint_array<int, 2>, 3>, 4>* dst_nested;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_4 {
   tint_array<int4, 4> tint_symbol_1;
   tint_array<int4, 4> tint_symbol_2;
@@ -62,6 +65,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -78,6 +82,7 @@
     uint v_2 = 0u;
     v_2 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 24u)) {
         break;
diff --git a/test/tint/array/assign_to_workgroup_var.wgsl.expected.msl b/test/tint/array/assign_to_workgroup_var.wgsl.expected.msl
index 4d58243..63276cb 100644
--- a/test/tint/array/assign_to_workgroup_var.wgsl.expected.msl
+++ b/test/tint/array/assign_to_workgroup_var.wgsl.expected.msl
@@ -14,17 +14,22 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   tint_array<int4, 4> src_private;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int4, 4>* const tint_symbol_5, threadgroup tint_array<int4, 4>* const tint_symbol_6, threadgroup tint_array<tint_array<tint_array<int, 2>, 3>, 4>* const tint_symbol_7) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_5))[i] = int4(0);
     (*(tint_symbol_6))[i] = int4(0);
   }
   for(uint idx_1 = local_idx; (idx_1 < 24u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     uint const i_1 = (idx_1 / 6u);
     uint const i_2 = ((idx_1 % 6u) / 2u);
     uint const i_3 = (idx_1 % 2u);
diff --git a/test/tint/array/function_parameter.wgsl.expected.glsl b/test/tint/array/function_parameter.wgsl.expected.glsl
index cff411d..1d7a6a1 100644
--- a/test/tint/array/function_parameter.wgsl.expected.glsl
+++ b/test/tint/array/function_parameter.wgsl.expected.glsl
@@ -5,13 +5,13 @@
   float inner;
 } v;
 float f1(float a[4]) {
-  return a[3];
+  return a[3u];
 }
 float f2(float a[3][4]) {
-  return a[2][3];
+  return a[2u][3u];
 }
 float f3(float a[2][3][4]) {
-  return a[1][2][3];
+  return a[1u][2u][3u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/array/function_parameter.wgsl.expected.ir.dxc.hlsl b/test/tint/array/function_parameter.wgsl.expected.ir.dxc.hlsl
index d80951a..c036254 100644
--- a/test/tint/array/function_parameter.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/array/function_parameter.wgsl.expected.ir.dxc.hlsl
@@ -1,15 +1,15 @@
 
 RWByteAddressBuffer s : register(u0);
 float f1(float a[4]) {
-  return a[int(3)];
+  return a[3u];
 }
 
 float f2(float a[3][4]) {
-  return a[int(2)][int(3)];
+  return a[2u][3u];
 }
 
 float f3(float a[2][3][4]) {
-  return a[int(1)][int(2)][int(3)];
+  return a[1u][2u][3u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/array/function_parameter.wgsl.expected.ir.fxc.hlsl b/test/tint/array/function_parameter.wgsl.expected.ir.fxc.hlsl
index d80951a..c036254 100644
--- a/test/tint/array/function_parameter.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/array/function_parameter.wgsl.expected.ir.fxc.hlsl
@@ -1,15 +1,15 @@
 
 RWByteAddressBuffer s : register(u0);
 float f1(float a[4]) {
-  return a[int(3)];
+  return a[3u];
 }
 
 float f2(float a[3][4]) {
-  return a[int(2)][int(3)];
+  return a[2u][3u];
 }
 
 float f3(float a[2][3][4]) {
-  return a[int(1)][int(2)][int(3)];
+  return a[1u][2u][3u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/array/function_parameter.wgsl.expected.ir.msl b/test/tint/array/function_parameter.wgsl.expected.ir.msl
index 28a4046..5f14ed8 100644
--- a/test/tint/array/function_parameter.wgsl.expected.ir.msl
+++ b/test/tint/array/function_parameter.wgsl.expected.ir.msl
@@ -18,15 +18,15 @@
 };
 
 float f1(tint_array<float, 4> a) {
-  return a[3];
+  return a[3u];
 }
 
 float f2(tint_array<tint_array<float, 4>, 3> a) {
-  return a[2][3];
+  return a[2u][3u];
 }
 
 float f3(tint_array<tint_array<tint_array<float, 4>, 3>, 2> a) {
-  return a[1][2][3];
+  return a[1u][2u][3u];
 }
 
 kernel void tint_symbol(device float* s [[buffer(0)]]) {
diff --git a/test/tint/array/function_return_type.wgsl.expected.glsl b/test/tint/array/function_return_type.wgsl.expected.glsl
index d7e8937..68a3bdb 100644
--- a/test/tint/array/function_return_type.wgsl.expected.glsl
+++ b/test/tint/array/function_return_type.wgsl.expected.glsl
@@ -21,5 +21,5 @@
   float a1[4] = f1();
   float a2[3][4] = f2();
   float a3[2][3][4] = f3();
-  v.inner = ((a1[0] + a2[0][0]) + a3[0][0][0]);
+  v.inner = ((a1[0u] + a2[0u][0u]) + a3[0u][0u][0u]);
 }
diff --git a/test/tint/array/function_return_type.wgsl.expected.ir.dxc.hlsl b/test/tint/array/function_return_type.wgsl.expected.ir.dxc.hlsl
index 777e90a..6f67bc3 100644
--- a/test/tint/array/function_return_type.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/array/function_return_type.wgsl.expected.ir.dxc.hlsl
@@ -28,6 +28,6 @@
   float a1[4] = f1();
   float a2[3][4] = f2();
   float a3[2][3][4] = f3();
-  s.Store(0u, asuint(((a1[int(0)] + a2[int(0)][int(0)]) + a3[int(0)][int(0)][int(0)])));
+  s.Store(0u, asuint(((a1[0u] + a2[0u][0u]) + a3[0u][0u][0u])));
 }
 
diff --git a/test/tint/array/function_return_type.wgsl.expected.ir.fxc.hlsl b/test/tint/array/function_return_type.wgsl.expected.ir.fxc.hlsl
index 777e90a..6f67bc3 100644
--- a/test/tint/array/function_return_type.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/array/function_return_type.wgsl.expected.ir.fxc.hlsl
@@ -28,6 +28,6 @@
   float a1[4] = f1();
   float a2[3][4] = f2();
   float a3[2][3][4] = f3();
-  s.Store(0u, asuint(((a1[int(0)] + a2[int(0)][int(0)]) + a3[int(0)][int(0)][int(0)])));
+  s.Store(0u, asuint(((a1[0u] + a2[0u][0u]) + a3[0u][0u][0u])));
 }
 
diff --git a/test/tint/array/function_return_type.wgsl.expected.ir.msl b/test/tint/array/function_return_type.wgsl.expected.ir.msl
index be17814..d50b19d 100644
--- a/test/tint/array/function_return_type.wgsl.expected.ir.msl
+++ b/test/tint/array/function_return_type.wgsl.expected.ir.msl
@@ -37,5 +37,5 @@
   tint_array<float, 4> const a1 = f1();
   tint_array<tint_array<float, 4>, 3> const a2 = f2();
   tint_array<tint_array<tint_array<float, 4>, 3>, 2> const a3 = f3();
-  (*tint_module_vars.s) = ((a1[0] + a2[0][0]) + a3[0][0][0]);
+  (*tint_module_vars.s) = ((a1[0u] + a2[0u][0u]) + a3[0u][0u][0u]);
 }
diff --git a/test/tint/array/size.wgsl.expected.glsl b/test/tint/array/size.wgsl.expected.glsl
index 6bfec92..ed008c3 100644
--- a/test/tint/array/size.wgsl.expected.glsl
+++ b/test/tint/array/size.wgsl.expected.glsl
@@ -16,5 +16,5 @@
   signed_constant = signed_literal;
   unsigned_constant = signed_literal;
   shr_const_expr = signed_literal;
-  v.inner = ((((signed_literal[0] + unsigned_literal[0]) + signed_constant[0]) + unsigned_constant[0]) + shr_const_expr[0]);
+  v.inner = ((((signed_literal[0u] + unsigned_literal[0u]) + signed_constant[0u]) + unsigned_constant[0u]) + shr_const_expr[0u]);
 }
diff --git a/test/tint/array/size.wgsl.expected.ir.dxc.hlsl b/test/tint/array/size.wgsl.expected.ir.dxc.hlsl
index 54c2b5e..a97d7cf 100644
--- a/test/tint/array/size.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/array/size.wgsl.expected.ir.dxc.hlsl
@@ -14,6 +14,6 @@
   unsigned_constant = v_2;
   float v_3[4] = signed_literal;
   shr_const_expr = v_3;
-  s.Store(0u, asuint(((((signed_literal[int(0)] + unsigned_literal[int(0)]) + signed_constant[int(0)]) + unsigned_constant[int(0)]) + shr_const_expr[int(0)])));
+  s.Store(0u, asuint(((((signed_literal[0u] + unsigned_literal[0u]) + signed_constant[0u]) + unsigned_constant[0u]) + shr_const_expr[0u])));
 }
 
diff --git a/test/tint/array/size.wgsl.expected.ir.fxc.hlsl b/test/tint/array/size.wgsl.expected.ir.fxc.hlsl
index 54c2b5e..a97d7cf 100644
--- a/test/tint/array/size.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/array/size.wgsl.expected.ir.fxc.hlsl
@@ -14,6 +14,6 @@
   unsigned_constant = v_2;
   float v_3[4] = signed_literal;
   shr_const_expr = v_3;
-  s.Store(0u, asuint(((((signed_literal[int(0)] + unsigned_literal[int(0)]) + signed_constant[int(0)]) + unsigned_constant[int(0)]) + shr_const_expr[int(0)])));
+  s.Store(0u, asuint(((((signed_literal[0u] + unsigned_literal[0u]) + signed_constant[0u]) + unsigned_constant[0u]) + shr_const_expr[0u])));
 }
 
diff --git a/test/tint/array/size.wgsl.expected.ir.msl b/test/tint/array/size.wgsl.expected.ir.msl
index 1b592bd..6c4e445 100644
--- a/test/tint/array/size.wgsl.expected.ir.msl
+++ b/test/tint/array/size.wgsl.expected.ir.msl
@@ -28,5 +28,5 @@
   signed_constant = signed_literal;
   unsigned_constant = signed_literal;
   shr_const_expr = signed_literal;
-  (*tint_module_vars.s) = ((((signed_literal[0] + unsigned_literal[0]) + signed_constant[0]) + unsigned_constant[0]) + shr_const_expr[0]);
+  (*tint_module_vars.s) = ((((signed_literal[0u] + unsigned_literal[0u]) + signed_constant[0u]) + unsigned_constant[0u]) + shr_const_expr[0u]);
 }
diff --git a/test/tint/array/size.wgsl.expected.spvasm b/test/tint/array/size.wgsl.expected.spvasm
index 25a9638..a090616 100644
--- a/test/tint/array/size.wgsl.expected.spvasm
+++ b/test/tint/array/size.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -33,10 +33,8 @@
 %_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4
          %14 = OpConstantNull %_arr_float_uint_4
 %_ptr_Function_float = OpTypePointer Function %float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
        %main = OpFunction %void None %7
           %8 = OpLabel
 %signed_literal = OpVariable %_ptr_Function__arr_float_uint_4 Function %14
@@ -52,21 +50,21 @@
                OpStore %unsigned_constant %21 None
          %22 = OpLoad %_arr_float_uint_4 %signed_literal None
                OpStore %shr_const_expr %22 None
-         %23 = OpAccessChain %_ptr_Function_float %signed_literal %int_0
-         %27 = OpLoad %float %23 None
-         %28 = OpAccessChain %_ptr_Function_float %unsigned_literal %int_0
-         %29 = OpLoad %float %28 None
-         %30 = OpFAdd %float %27 %29
-         %31 = OpAccessChain %_ptr_Function_float %signed_constant %int_0
-         %32 = OpLoad %float %31 None
-         %33 = OpFAdd %float %30 %32
-         %34 = OpAccessChain %_ptr_Function_float %unsigned_constant %int_0
-         %35 = OpLoad %float %34 None
-         %36 = OpFAdd %float %33 %35
-         %37 = OpAccessChain %_ptr_Function_float %shr_const_expr %int_0
-         %38 = OpLoad %float %37 None
-         %39 = OpFAdd %float %36 %38
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+         %23 = OpAccessChain %_ptr_Function_float %signed_literal %uint_0
+         %26 = OpLoad %float %23 None
+         %27 = OpAccessChain %_ptr_Function_float %unsigned_literal %uint_0
+         %28 = OpLoad %float %27 None
+         %29 = OpFAdd %float %26 %28
+         %30 = OpAccessChain %_ptr_Function_float %signed_constant %uint_0
+         %31 = OpLoad %float %30 None
+         %32 = OpFAdd %float %29 %31
+         %33 = OpAccessChain %_ptr_Function_float %unsigned_constant %uint_0
+         %34 = OpLoad %float %33 None
+         %35 = OpFAdd %float %32 %34
+         %36 = OpAccessChain %_ptr_Function_float %shr_const_expr %uint_0
+         %37 = OpLoad %float %36 None
+         %38 = OpFAdd %float %35 %37
+         %39 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/array/strides.spvasm.expected.glsl b/test/tint/array/strides.spvasm.expected.glsl
index b963686..c18f961 100644
--- a/test/tint/array/strides.spvasm.expected.glsl
+++ b/test/tint/array/strides.spvasm.expected.glsl
@@ -97,11 +97,11 @@
 }
 void f_1() {
   strided_arr_1 x_19[4] = v.inner.a;
-  strided_arr x_24[3][2] = v.inner.a[3].el;
-  strided_arr x_28[2] = v.inner.a[3].el[2];
-  float x_32 = v.inner.a[3].el[2][1].el;
+  strided_arr x_24[3][2] = v.inner.a[3u].el;
+  strided_arr x_28[2] = v.inner.a[3u].el[2u];
+  float x_32 = v.inner.a[3u].el[2u][1u].el;
   tint_store_and_preserve_padding(strided_arr_1[4](strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u))), 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u))), 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u))), 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u), strided_arr_1(strided_arr[3][2](strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u)), strided_arr[2](strided_arr(0.0f, 0u), strided_arr(0.0f, 0u))), 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u)));
-  v.inner.a[3].el[2][1].el = 5.0f;
+  v.inner.a[3u].el[2u][1u].el = 5.0f;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/array/strides.spvasm.expected.ir.msl b/test/tint/array/strides.spvasm.expected.ir.msl
index d84e88c..e0de60a 100644
--- a/test/tint/array/strides.spvasm.expected.ir.msl
+++ b/test/tint/array/strides.spvasm.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct strided_arr_1 {
   /* 0x0000 */ tint_array<tint_array<strided_arr, 2>, 3> el;
   /* 0x0030 */ tint_array<int8_t, 80> tint_pad_1;
@@ -40,6 +43,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 2u)) {
         break;
@@ -58,6 +62,7 @@
     uint v_2 = 0u;
     v_2 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 3u)) {
         break;
@@ -80,6 +85,7 @@
     uint v_4 = 0u;
     v_4 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_2)
       uint const v_5 = v_4;
       if ((v_5 >= 4u)) {
         break;
@@ -95,11 +101,11 @@
 
 void f_1(tint_module_vars_struct tint_module_vars) {
   tint_array<strided_arr_1, 4> const x_19 = (*tint_module_vars.s).a;
-  tint_array<tint_array<strided_arr, 2>, 3> const x_24 = (*tint_module_vars.s).a[3].el;
-  tint_array<strided_arr, 2> const x_28 = (*tint_module_vars.s).a[3].el[2];
-  float const x_32 = (*tint_module_vars.s).a[3].el[2][1].el;
+  tint_array<tint_array<strided_arr, 2>, 3> const x_24 = (*tint_module_vars.s).a[3u].el;
+  tint_array<strided_arr, 2> const x_28 = (*tint_module_vars.s).a[3u].el[2u];
+  float const x_32 = (*tint_module_vars.s).a[3u].el[2u][1u].el;
   tint_store_and_preserve_padding((&(*tint_module_vars.s).a), tint_array<strided_arr_1, 4>{});
-  (*tint_module_vars.s).a[3].el[2][1].el = 5.0f;
+  (*tint_module_vars.s).a[3u].el[2u][1u].el = 5.0f;
 }
 
 kernel void f(device S* s [[buffer(0)]]) {
diff --git a/test/tint/array/strides.spvasm.expected.msl b/test/tint/array/strides.spvasm.expected.msl
index 5de9554..479356c 100644
--- a/test/tint/array/strides.spvasm.expected.msl
+++ b/test/tint/array/strides.spvasm.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct strided_arr {
   /* 0x0000 */ float el;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -34,13 +37,15 @@
 
 void assign_and_preserve_padding_3(device tint_array<strided_arr, 2>* const dest, tint_array<strided_arr, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    assign_and_preserve_padding_4(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_4(&((*(dest))[min(i, 1u)]), value[min(i, 1u)]);
   }
 }
 
 void assign_and_preserve_padding_2(device tint_array<tint_array<strided_arr, 2>, 3>* const dest, tint_array<tint_array<strided_arr, 2>, 3> value) {
   for(uint i = 0u; (i < 3u); i = (i + 1u)) {
-    assign_and_preserve_padding_3(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false_1);
+    assign_and_preserve_padding_3(&((*(dest))[min(i, 2u)]), value[min(i, 2u)]);
   }
 }
 
@@ -50,7 +55,8 @@
 
 void assign_and_preserve_padding(device tint_array<strided_arr_1, 4>* const dest, tint_array<strided_arr_1, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false_2);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/array/strides.spvasm.expected.spvasm b/test/tint/array/strides.spvasm.expected.spvasm
index 6219379..8b47afe 100644
--- a/test/tint/array/strides.spvasm.expected.spvasm
+++ b/test/tint/array/strides.spvasm.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 134
+; Bound: 130
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -68,163 +68,159 @@
 %_ptr_StorageBuffer__arr_strided_arr_1_uint_4 = OpTypePointer StorageBuffer %_arr_strided_arr_1_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer__arr__arr_strided_arr_uint_2_uint_3 = OpTypePointer StorageBuffer %_arr__arr_strided_arr_uint_2_uint_3
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
 %_ptr_StorageBuffer__arr_strided_arr_uint_2 = OpTypePointer StorageBuffer %_arr_strided_arr_uint_2
-      %int_2 = OpConstant %int 2
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-      %int_1 = OpConstant %int 1
-         %38 = OpConstantNull %_arr_strided_arr_1_uint_4
+     %uint_1 = OpConstant %uint 1
+         %35 = OpConstantNull %_arr_strided_arr_1_uint_4
     %float_5 = OpConstant %float 5
-         %45 = OpTypeFunction %void %_arr_strided_arr_1_uint_4
+         %42 = OpTypeFunction %void %_arr_strided_arr_1_uint_4
 %_ptr_Function__arr_strided_arr_1_uint_4 = OpTypePointer Function %_arr_strided_arr_1_uint_4
        %bool = OpTypeBool
 %_ptr_Function_strided_arr_1 = OpTypePointer Function %strided_arr_1
-     %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %70 = OpTypeFunction %void %_arr_uint_uint_1 %strided_arr_1
-         %79 = OpTypeFunction %void %_arr_uint_uint_1 %_arr__arr_strided_arr_uint_2_uint_3
+         %66 = OpTypeFunction %void %_arr_uint_uint_1 %strided_arr_1
+         %75 = OpTypeFunction %void %_arr_uint_uint_1 %_arr__arr_strided_arr_uint_2_uint_3
 %_ptr_Function__arr__arr_strided_arr_uint_2_uint_3 = OpTypePointer Function %_arr__arr_strided_arr_uint_2_uint_3
 %_ptr_Function__arr_strided_arr_uint_2 = OpTypePointer Function %_arr_strided_arr_uint_2
 %_arr_uint_uint_2 = OpTypeArray %uint %uint_2
-        %103 = OpTypeFunction %void %_arr_uint_uint_2 %_arr_strided_arr_uint_2
+         %99 = OpTypeFunction %void %_arr_uint_uint_2 %_arr_strided_arr_uint_2
 %_ptr_Function_strided_arr = OpTypePointer Function %strided_arr
 %_arr_uint_uint_3 = OpTypeArray %uint %uint_3
-        %127 = OpTypeFunction %void %_arr_uint_uint_3 %strided_arr
+        %123 = OpTypeFunction %void %_arr_uint_uint_3 %strided_arr
         %f_1 = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_1_uint_4 %1 %uint_0 %uint_0
        %x_19 = OpLoad %_arr_strided_arr_1_uint_4 %19 None
-         %23 = OpAccessChain %_ptr_StorageBuffer__arr__arr_strided_arr_uint_2_uint_3 %1 %uint_0 %uint_0 %int_3 %uint_0
+         %23 = OpAccessChain %_ptr_StorageBuffer__arr__arr_strided_arr_uint_2_uint_3 %1 %uint_0 %uint_0 %uint_3 %uint_0
        %x_24 = OpLoad %_arr__arr_strided_arr_uint_2_uint_3 %23 None
-         %28 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_uint_2 %1 %uint_0 %uint_0 %int_3 %uint_0 %int_2
-       %x_28 = OpLoad %_arr_strided_arr_uint_2 %28 None
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %int_3 %uint_0 %int_2 %int_1 %uint_0
-       %x_32 = OpLoad %float %32 None
-         %36 = OpFunctionCall %void %tint_store_and_preserve_padding %38
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %int_3 %uint_0 %int_2 %int_1 %uint_0
-               OpStore %39 %float_5 None
+         %26 = OpAccessChain %_ptr_StorageBuffer__arr_strided_arr_uint_2 %1 %uint_0 %uint_0 %uint_3 %uint_0 %uint_2
+       %x_28 = OpLoad %_arr_strided_arr_uint_2 %26 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %uint_3 %uint_0 %uint_2 %uint_1 %uint_0
+       %x_32 = OpLoad %float %29 None
+         %33 = OpFunctionCall %void %tint_store_and_preserve_padding %35
+         %36 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %uint_3 %uint_0 %uint_2 %uint_1 %uint_0
+               OpStore %36 %float_5 None
                OpReturn
                OpFunctionEnd
           %f = OpFunction %void None %17
-         %42 = OpLabel
-         %43 = OpFunctionCall %void %f_1
+         %39 = OpLabel
+         %40 = OpFunctionCall %void %f_1
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %45
+%tint_store_and_preserve_padding = OpFunction %void None %42
 %value_param = OpFunctionParameter %_arr_strided_arr_1_uint_4
+         %43 = OpLabel
+         %44 = OpVariable %_ptr_Function__arr_strided_arr_1_uint_4 Function
+               OpStore %44 %value_param
+               OpBranch %46
          %46 = OpLabel
-         %47 = OpVariable %_ptr_Function__arr_strided_arr_1_uint_4 Function
-               OpStore %47 %value_param
                OpBranch %49
          %49 = OpLabel
-               OpBranch %52
-         %52 = OpLabel
-         %54 = OpPhi %uint %uint_0 %49 %55 %51
-               OpLoopMerge %53 %51 None
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_strided_arr_1 %44 %51
+         %59 = OpLoad %strided_arr_1 %57 None
+         %61 = OpCompositeConstruct %_arr_uint_uint_1 %51
+         %62 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %61 %59
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
          %50 = OpLabel
-         %56 = OpUGreaterThanEqual %bool %54 %uint_4
-               OpSelectionMerge %58 None
-               OpBranchConditional %56 %59 %58
-         %59 = OpLabel
-               OpBranch %53
-         %58 = OpLabel
-         %60 = OpAccessChain %_ptr_Function_strided_arr_1 %47 %54
-         %62 = OpLoad %strided_arr_1 %60 None
-         %65 = OpCompositeConstruct %_arr_uint_uint_1 %54
-         %66 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %65 %62
-               OpBranch %51
-         %51 = OpLabel
-         %55 = OpIAdd %uint %54 %uint_1
-               OpBranch %52
-         %53 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %70
+%tint_store_and_preserve_padding_0 = OpFunction %void None %66
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %strided_arr_1
-         %71 = OpLabel
-         %72 = OpCompositeExtract %uint %target_indices 0
-         %73 = OpCompositeExtract %_arr__arr_strided_arr_uint_2_uint_3 %value_param_0 0
-         %74 = OpCompositeConstruct %_arr_uint_uint_1 %72
-         %75 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %74 %73
+         %67 = OpLabel
+         %68 = OpCompositeExtract %uint %target_indices 0
+         %69 = OpCompositeExtract %_arr__arr_strided_arr_uint_2_uint_3 %value_param_0 0
+         %70 = OpCompositeConstruct %_arr_uint_uint_1 %68
+         %71 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %70 %69
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %79
+%tint_store_and_preserve_padding_1 = OpFunction %void None %75
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %_arr__arr_strided_arr_uint_2_uint_3
+         %76 = OpLabel
+         %77 = OpVariable %_ptr_Function__arr__arr_strided_arr_uint_2_uint_3 Function
+               OpStore %77 %value_param_1
+         %79 = OpCompositeExtract %uint %target_indices_0 0
+               OpBranch %80
          %80 = OpLabel
-         %81 = OpVariable %_ptr_Function__arr__arr_strided_arr_uint_2_uint_3 Function
-               OpStore %81 %value_param_1
-         %83 = OpCompositeExtract %uint %target_indices_0 0
+               OpBranch %83
+         %83 = OpLabel
+         %85 = OpPhi %uint %uint_0 %80 %86 %82
+               OpLoopMerge %84 %82 None
+               OpBranch %81
+         %81 = OpLabel
+         %87 = OpUGreaterThanEqual %bool %85 %uint_3
+               OpSelectionMerge %88 None
+               OpBranchConditional %87 %89 %88
+         %89 = OpLabel
                OpBranch %84
-         %84 = OpLabel
-               OpBranch %87
-         %87 = OpLabel
-         %89 = OpPhi %uint %uint_0 %84 %90 %86
-               OpLoopMerge %88 %86 None
-               OpBranch %85
-         %85 = OpLabel
-         %91 = OpUGreaterThanEqual %bool %89 %uint_3
-               OpSelectionMerge %92 None
-               OpBranchConditional %91 %93 %92
-         %93 = OpLabel
-               OpBranch %88
-         %92 = OpLabel
-         %94 = OpAccessChain %_ptr_Function__arr_strided_arr_uint_2 %81 %89
-         %96 = OpLoad %_arr_strided_arr_uint_2 %94 None
-         %98 = OpCompositeConstruct %_arr_uint_uint_2 %83 %89
-         %99 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %98 %96
-               OpBranch %86
-         %86 = OpLabel
-         %90 = OpIAdd %uint %89 %uint_1
-               OpBranch %87
          %88 = OpLabel
+         %90 = OpAccessChain %_ptr_Function__arr_strided_arr_uint_2 %77 %85
+         %92 = OpLoad %_arr_strided_arr_uint_2 %90 None
+         %94 = OpCompositeConstruct %_arr_uint_uint_2 %79 %85
+         %95 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %94 %92
+               OpBranch %82
+         %82 = OpLabel
+         %86 = OpIAdd %uint %85 %uint_1
+               OpBranch %83
+         %84 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_2 = OpFunction %void None %103
+%tint_store_and_preserve_padding_2 = OpFunction %void None %99
 %target_indices_1 = OpFunctionParameter %_arr_uint_uint_2
 %value_param_2 = OpFunctionParameter %_arr_strided_arr_uint_2
+        %100 = OpLabel
+        %101 = OpVariable %_ptr_Function__arr_strided_arr_uint_2 Function
+               OpStore %101 %value_param_2
+        %102 = OpCompositeExtract %uint %target_indices_1 0
+        %103 = OpCompositeExtract %uint %target_indices_1 1
+               OpBranch %104
         %104 = OpLabel
-        %105 = OpVariable %_ptr_Function__arr_strided_arr_uint_2 Function
-               OpStore %105 %value_param_2
-        %106 = OpCompositeExtract %uint %target_indices_1 0
-        %107 = OpCompositeExtract %uint %target_indices_1 1
+               OpBranch %107
+        %107 = OpLabel
+        %109 = OpPhi %uint %uint_0 %104 %110 %106
+               OpLoopMerge %108 %106 None
+               OpBranch %105
+        %105 = OpLabel
+        %111 = OpUGreaterThanEqual %bool %109 %uint_2
+               OpSelectionMerge %112 None
+               OpBranchConditional %111 %113 %112
+        %113 = OpLabel
                OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_2
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_strided_arr %105 %113
-        %120 = OpLoad %strided_arr %118 None
-        %122 = OpCompositeConstruct %_arr_uint_uint_3 %106 %107 %113
-        %123 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %122 %120
-               OpBranch %110
-        %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
-               OpBranch %111
         %112 = OpLabel
+        %114 = OpAccessChain %_ptr_Function_strided_arr %101 %109
+        %116 = OpLoad %strided_arr %114 None
+        %118 = OpCompositeConstruct %_arr_uint_uint_3 %102 %103 %109
+        %119 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %118 %116
+               OpBranch %106
+        %106 = OpLabel
+        %110 = OpIAdd %uint %109 %uint_1
+               OpBranch %107
+        %108 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_3 = OpFunction %void None %127
+%tint_store_and_preserve_padding_3 = OpFunction %void None %123
 %target_indices_2 = OpFunctionParameter %_arr_uint_uint_3
 %value_param_3 = OpFunctionParameter %strided_arr
-        %128 = OpLabel
-        %129 = OpCompositeExtract %uint %target_indices_2 0
-        %130 = OpCompositeExtract %uint %target_indices_2 1
-        %131 = OpCompositeExtract %uint %target_indices_2 2
-        %132 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %129 %uint_0 %130 %131 %uint_0
-        %133 = OpCompositeExtract %float %value_param_3 0
-               OpStore %132 %133 None
+        %124 = OpLabel
+        %125 = OpCompositeExtract %uint %target_indices_2 0
+        %126 = OpCompositeExtract %uint %target_indices_2 1
+        %127 = OpCompositeExtract %uint %target_indices_2 2
+        %128 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %uint_0 %125 %uint_0 %126 %127 %uint_0
+        %129 = OpCompositeExtract %float %value_param_3 0
+               OpStore %128 %129 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/array/type_initializer.wgsl.expected.glsl b/test/tint/array/type_initializer.wgsl.expected.glsl
index 5d461ad..ac638e9 100644
--- a/test/tint/array/type_initializer.wgsl.expected.glsl
+++ b/test/tint/array/type_initializer.wgsl.expected.glsl
@@ -9,16 +9,16 @@
   int x = 42;
   int empty[4] = int[4](0, 0, 0, 0);
   int nonempty[4] = int[4](1, 2, 3, 4);
-  int nonempty_with_expr[4] = int[4](1, x, (x + 1), nonempty[3]);
+  int nonempty_with_expr[4] = int[4](1, x, (x + 1), nonempty[3u]);
   int nested_empty[2][3][4] = int[2][3][4](int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)), int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)));
   int nested_nonempty[2][3][4] = int[2][3][4](int[3][4](int[4](1, 2, 3, 4), int[4](5, 6, 7, 8), int[4](9, 10, 11, 12)), int[3][4](int[4](13, 14, 15, 16), int[4](17, 18, 19, 20), int[4](21, 22, 23, 24)));
   int v_1[4] = int[4](1, 2, x, (x + 1));
-  int nested_nonempty_with_expr[2][3][4] = int[2][3][4](int[3][4](v_1, int[4](5, 6, nonempty[2], (nonempty[3] + 1)), nonempty), nested_nonempty[1]);
+  int nested_nonempty_with_expr[2][3][4] = int[2][3][4](int[3][4](v_1, int[4](5, 6, nonempty[2u], (nonempty[3u] + 1)), nonempty), nested_nonempty[1u]);
   int subexpr_empty = 0;
   int subexpr_nonempty = 3;
-  int subexpr_nonempty_with_expr = int[4](1, x, (x + 1), nonempty[3])[2];
+  int subexpr_nonempty_with_expr = int[4](1, x, (x + 1), nonempty[3u])[2u];
   int subexpr_nested_empty[4] = int[4](0, 0, 0, 0);
   int subexpr_nested_nonempty[4] = int[4](5, 6, 7, 8);
-  int subexpr_nested_nonempty_with_expr[4] = int[2][4](int[4](1, x, (x + 1), nonempty[3]), nested_nonempty[1][2])[1];
-  v.inner = (((((((((((empty[0] + nonempty[0]) + nonempty_with_expr[0]) + nested_empty[0][0][0]) + nested_nonempty[0][0][0]) + nested_nonempty_with_expr[0][0][0]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[0]) + subexpr_nested_nonempty[0]) + subexpr_nested_nonempty_with_expr[0]);
+  int subexpr_nested_nonempty_with_expr[4] = int[2][4](int[4](1, x, (x + 1), nonempty[3u]), nested_nonempty[1u][2u])[1u];
+  v.inner = (((((((((((empty[0u] + nonempty[0u]) + nonempty_with_expr[0u]) + nested_empty[0u][0u][0u]) + nested_nonempty[0u][0u][0u]) + nested_nonempty_with_expr[0u][0u][0u]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[0u]) + subexpr_nested_nonempty[0u]) + subexpr_nested_nonempty_with_expr[0u]);
 }
diff --git a/test/tint/array/type_initializer.wgsl.expected.ir.dxc.hlsl b/test/tint/array/type_initializer.wgsl.expected.ir.dxc.hlsl
index b1c3e08..55d6f01 100644
--- a/test/tint/array/type_initializer.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/array/type_initializer.wgsl.expected.ir.dxc.hlsl
@@ -5,24 +5,24 @@
   int x = int(42);
   int empty[4] = (int[4])0;
   int nonempty[4] = {int(1), int(2), int(3), int(4)};
-  int nonempty_with_expr[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
+  int nonempty_with_expr[4] = {int(1), x, (x + int(1)), nonempty[3u]};
   int nested_empty[2][3][4] = (int[2][3][4])0;
   int nested_nonempty[2][3][4] = {{{int(1), int(2), int(3), int(4)}, {int(5), int(6), int(7), int(8)}, {int(9), int(10), int(11), int(12)}}, {{int(13), int(14), int(15), int(16)}, {int(17), int(18), int(19), int(20)}, {int(21), int(22), int(23), int(24)}}};
   int v[4] = {int(1), int(2), x, (x + int(1))};
-  int v_1[4] = {int(5), int(6), nonempty[int(2)], (nonempty[int(3)] + int(1))};
+  int v_1[4] = {int(5), int(6), nonempty[2u], (nonempty[3u] + int(1))};
   int v_2[3][4] = {v, v_1, nonempty};
-  int v_3[3][4] = nested_nonempty[int(1)];
+  int v_3[3][4] = nested_nonempty[1u];
   int nested_nonempty_with_expr[2][3][4] = {v_2, v_3};
   int subexpr_empty = int(0);
   int subexpr_nonempty = int(3);
-  int v_4[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
-  int subexpr_nonempty_with_expr = v_4[int(2)];
+  int v_4[4] = {int(1), x, (x + int(1)), nonempty[3u]};
+  int subexpr_nonempty_with_expr = v_4[2u];
   int subexpr_nested_empty[4] = (int[4])0;
   int subexpr_nested_nonempty[4] = {int(5), int(6), int(7), int(8)};
-  int v_5[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
-  int v_6[4] = nested_nonempty[int(1)][int(2)];
+  int v_5[4] = {int(1), x, (x + int(1)), nonempty[3u]};
+  int v_6[4] = nested_nonempty[1u][2u];
   int v_7[2][4] = {v_5, v_6};
-  int subexpr_nested_nonempty_with_expr[4] = v_7[int(1)];
-  s.Store(0u, asuint((((((((((((empty[int(0)] + nonempty[int(0)]) + nonempty_with_expr[int(0)]) + nested_empty[int(0)][int(0)][int(0)]) + nested_nonempty[int(0)][int(0)][int(0)]) + nested_nonempty_with_expr[int(0)][int(0)][int(0)]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[int(0)]) + subexpr_nested_nonempty[int(0)]) + subexpr_nested_nonempty_with_expr[int(0)])));
+  int subexpr_nested_nonempty_with_expr[4] = v_7[1u];
+  s.Store(0u, asuint((((((((((((empty[0u] + nonempty[0u]) + nonempty_with_expr[0u]) + nested_empty[0u][0u][0u]) + nested_nonempty[0u][0u][0u]) + nested_nonempty_with_expr[0u][0u][0u]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[0u]) + subexpr_nested_nonempty[0u]) + subexpr_nested_nonempty_with_expr[0u])));
 }
 
diff --git a/test/tint/array/type_initializer.wgsl.expected.ir.fxc.hlsl b/test/tint/array/type_initializer.wgsl.expected.ir.fxc.hlsl
index b1c3e08..55d6f01 100644
--- a/test/tint/array/type_initializer.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/array/type_initializer.wgsl.expected.ir.fxc.hlsl
@@ -5,24 +5,24 @@
   int x = int(42);
   int empty[4] = (int[4])0;
   int nonempty[4] = {int(1), int(2), int(3), int(4)};
-  int nonempty_with_expr[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
+  int nonempty_with_expr[4] = {int(1), x, (x + int(1)), nonempty[3u]};
   int nested_empty[2][3][4] = (int[2][3][4])0;
   int nested_nonempty[2][3][4] = {{{int(1), int(2), int(3), int(4)}, {int(5), int(6), int(7), int(8)}, {int(9), int(10), int(11), int(12)}}, {{int(13), int(14), int(15), int(16)}, {int(17), int(18), int(19), int(20)}, {int(21), int(22), int(23), int(24)}}};
   int v[4] = {int(1), int(2), x, (x + int(1))};
-  int v_1[4] = {int(5), int(6), nonempty[int(2)], (nonempty[int(3)] + int(1))};
+  int v_1[4] = {int(5), int(6), nonempty[2u], (nonempty[3u] + int(1))};
   int v_2[3][4] = {v, v_1, nonempty};
-  int v_3[3][4] = nested_nonempty[int(1)];
+  int v_3[3][4] = nested_nonempty[1u];
   int nested_nonempty_with_expr[2][3][4] = {v_2, v_3};
   int subexpr_empty = int(0);
   int subexpr_nonempty = int(3);
-  int v_4[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
-  int subexpr_nonempty_with_expr = v_4[int(2)];
+  int v_4[4] = {int(1), x, (x + int(1)), nonempty[3u]};
+  int subexpr_nonempty_with_expr = v_4[2u];
   int subexpr_nested_empty[4] = (int[4])0;
   int subexpr_nested_nonempty[4] = {int(5), int(6), int(7), int(8)};
-  int v_5[4] = {int(1), x, (x + int(1)), nonempty[int(3)]};
-  int v_6[4] = nested_nonempty[int(1)][int(2)];
+  int v_5[4] = {int(1), x, (x + int(1)), nonempty[3u]};
+  int v_6[4] = nested_nonempty[1u][2u];
   int v_7[2][4] = {v_5, v_6};
-  int subexpr_nested_nonempty_with_expr[4] = v_7[int(1)];
-  s.Store(0u, asuint((((((((((((empty[int(0)] + nonempty[int(0)]) + nonempty_with_expr[int(0)]) + nested_empty[int(0)][int(0)][int(0)]) + nested_nonempty[int(0)][int(0)][int(0)]) + nested_nonempty_with_expr[int(0)][int(0)][int(0)]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[int(0)]) + subexpr_nested_nonempty[int(0)]) + subexpr_nested_nonempty_with_expr[int(0)])));
+  int subexpr_nested_nonempty_with_expr[4] = v_7[1u];
+  s.Store(0u, asuint((((((((((((empty[0u] + nonempty[0u]) + nonempty_with_expr[0u]) + nested_empty[0u][0u][0u]) + nested_nonempty[0u][0u][0u]) + nested_nonempty_with_expr[0u][0u][0u]) + subexpr_empty) + subexpr_nonempty) + subexpr_nonempty_with_expr) + subexpr_nested_empty[0u]) + subexpr_nested_nonempty[0u]) + subexpr_nested_nonempty_with_expr[0u])));
 }
 
diff --git a/test/tint/array/type_initializer.wgsl.expected.ir.msl b/test/tint/array/type_initializer.wgsl.expected.ir.msl
index bebcd67..04449be 100644
--- a/test/tint/array/type_initializer.wgsl.expected.ir.msl
+++ b/test/tint/array/type_initializer.wgsl.expected.ir.msl
@@ -22,16 +22,16 @@
   int const x = 42;
   tint_array<int, 4> const empty = tint_array<int, 4>{};
   tint_array<int, 4> const nonempty = tint_array<int, 4>{1, 2, 3, 4};
-  tint_array<int, 4> const nonempty_with_expr = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3]};
+  tint_array<int, 4> const nonempty_with_expr = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3u]};
   tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_empty = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{};
   tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{1, 2, 3, 4}, tint_array<int, 4>{5, 6, 7, 8}, tint_array<int, 4>{9, 10, 11, 12}}, tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{13, 14, 15, 16}, tint_array<int, 4>{17, 18, 19, 20}, tint_array<int, 4>{21, 22, 23, 24}}};
   tint_array<int, 4> const v = tint_array<int, 4>{1, 2, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1)))};
-  tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty_with_expr = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_array<tint_array<int, 4>, 3>{v, tint_array<int, 4>{5, 6, nonempty[2], as_type<int>((as_type<uint>(nonempty[3]) + as_type<uint>(1)))}, nonempty}, nested_nonempty[1]};
+  tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty_with_expr = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_array<tint_array<int, 4>, 3>{v, tint_array<int, 4>{5, 6, nonempty[2u], as_type<int>((as_type<uint>(nonempty[3u]) + as_type<uint>(1)))}, nonempty}, nested_nonempty[1u]};
   int const subexpr_empty = 0;
   int const subexpr_nonempty = 3;
-  int const subexpr_nonempty_with_expr = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3]}[2];
+  int const subexpr_nonempty_with_expr = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3u]}[2u];
   tint_array<int, 4> const subexpr_nested_empty = tint_array<int, 4>{};
   tint_array<int, 4> const subexpr_nested_nonempty = tint_array<int, 4>{5, 6, 7, 8};
-  tint_array<int, 4> const subexpr_nested_nonempty_with_expr = tint_array<tint_array<int, 4>, 2>{tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3]}, nested_nonempty[1][2]}[1];
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(empty[0]) + as_type<uint>(nonempty[0])))) + as_type<uint>(nonempty_with_expr[0])))) + as_type<uint>(nested_empty[0][0][0])))) + as_type<uint>(nested_nonempty[0][0][0])))) + as_type<uint>(nested_nonempty_with_expr[0][0][0])))) + as_type<uint>(subexpr_empty)))) + as_type<uint>(subexpr_nonempty)))) + as_type<uint>(subexpr_nonempty_with_expr)))) + as_type<uint>(subexpr_nested_empty[0])))) + as_type<uint>(subexpr_nested_nonempty[0])))) + as_type<uint>(subexpr_nested_nonempty_with_expr[0])));
+  tint_array<int, 4> const subexpr_nested_nonempty_with_expr = tint_array<tint_array<int, 4>, 2>{tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), nonempty[3u]}, nested_nonempty[1u][2u]}[1u];
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(empty[0u]) + as_type<uint>(nonempty[0u])))) + as_type<uint>(nonempty_with_expr[0u])))) + as_type<uint>(nested_empty[0u][0u][0u])))) + as_type<uint>(nested_nonempty[0u][0u][0u])))) + as_type<uint>(nested_nonempty_with_expr[0u][0u][0u])))) + as_type<uint>(subexpr_empty)))) + as_type<uint>(subexpr_nonempty)))) + as_type<uint>(subexpr_nonempty_with_expr)))) + as_type<uint>(subexpr_nested_empty[0u])))) + as_type<uint>(subexpr_nested_nonempty[0u])))) + as_type<uint>(subexpr_nested_nonempty_with_expr[0u])));
 }
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.dxc.hlsl
index 6383fd4..c3d880f 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.dxc.hlsl
@@ -57,28 +57,31 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((544u * idx)));
-  int scalar_i32 = asint(sb.Load(((544u * idx) + 4u)));
-  uint scalar_u32 = sb.Load(((544u * idx) + 8u));
-  float2 vec2_f32 = asfloat(sb.Load2(((544u * idx) + 16u)));
-  int2 vec2_i32 = asint(sb.Load2(((544u * idx) + 24u)));
-  uint2 vec2_u32 = sb.Load2(((544u * idx) + 32u));
-  float3 vec3_f32 = asfloat(sb.Load3(((544u * idx) + 48u)));
-  int3 vec3_i32 = asint(sb.Load3(((544u * idx) + 64u)));
-  uint3 vec3_u32 = sb.Load3(((544u * idx) + 80u));
-  float4 vec4_f32 = asfloat(sb.Load4(((544u * idx) + 96u)));
-  int4 vec4_i32 = asint(sb.Load4(((544u * idx) + 112u)));
-  uint4 vec4_u32 = sb.Load4(((544u * idx) + 128u));
-  float2x2 mat2x2_f32 = sb_load_12(((544u * idx) + 144u));
-  float2x3 mat2x3_f32 = sb_load_13(((544u * idx) + 160u));
-  float2x4 mat2x4_f32 = sb_load_14(((544u * idx) + 192u));
-  float3x2 mat3x2_f32 = sb_load_15(((544u * idx) + 224u));
-  float3x3 mat3x3_f32 = sb_load_16(((544u * idx) + 256u));
-  float3x4 mat3x4_f32 = sb_load_17(((544u * idx) + 304u));
-  float4x2 mat4x2_f32 = sb_load_18(((544u * idx) + 352u));
-  float4x3 mat4x3_f32 = sb_load_19(((544u * idx) + 384u));
-  float4x4 mat4x4_f32 = sb_load_20(((544u * idx) + 448u));
-  float3 arr2_vec3_f32[2] = sb_load_21(((544u * idx) + 512u));
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 544u);
+  float scalar_f32 = asfloat(sb.Load((544u * min(idx, (tint_symbol_4 - 1u)))));
+  int scalar_i32 = asint(sb.Load(((544u * min(idx, (tint_symbol_4 - 1u))) + 4u)));
+  uint scalar_u32 = sb.Load(((544u * min(idx, (tint_symbol_4 - 1u))) + 8u));
+  float2 vec2_f32 = asfloat(sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 16u)));
+  int2 vec2_i32 = asint(sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 24u)));
+  uint2 vec2_u32 = sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 32u));
+  float3 vec3_f32 = asfloat(sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 48u)));
+  int3 vec3_i32 = asint(sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 64u)));
+  uint3 vec3_u32 = sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 80u));
+  float4 vec4_f32 = asfloat(sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 96u)));
+  int4 vec4_i32 = asint(sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 112u)));
+  uint4 vec4_u32 = sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 128u));
+  float2x2 mat2x2_f32 = sb_load_12(((544u * min(idx, (tint_symbol_4 - 1u))) + 144u));
+  float2x3 mat2x3_f32 = sb_load_13(((544u * min(idx, (tint_symbol_4 - 1u))) + 160u));
+  float2x4 mat2x4_f32 = sb_load_14(((544u * min(idx, (tint_symbol_4 - 1u))) + 192u));
+  float3x2 mat3x2_f32 = sb_load_15(((544u * min(idx, (tint_symbol_4 - 1u))) + 224u));
+  float3x3 mat3x3_f32 = sb_load_16(((544u * min(idx, (tint_symbol_4 - 1u))) + 256u));
+  float3x4 mat3x4_f32 = sb_load_17(((544u * min(idx, (tint_symbol_4 - 1u))) + 304u));
+  float4x2 mat4x2_f32 = sb_load_18(((544u * min(idx, (tint_symbol_4 - 1u))) + 352u));
+  float4x3 mat4x3_f32 = sb_load_19(((544u * min(idx, (tint_symbol_4 - 1u))) + 384u));
+  float4x4 mat4x4_f32 = sb_load_20(((544u * min(idx, (tint_symbol_4 - 1u))) + 448u));
+  float3 arr2_vec3_f32[2] = sb_load_21(((544u * min(idx, (tint_symbol_4 - 1u))) + 512u));
   s.Store(0u, asuint((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + tint_ftoi(arr2_vec3_f32[0].x))));
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.fxc.hlsl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.fxc.hlsl
index 6383fd4..c3d880f 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.fxc.hlsl
@@ -57,28 +57,31 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((544u * idx)));
-  int scalar_i32 = asint(sb.Load(((544u * idx) + 4u)));
-  uint scalar_u32 = sb.Load(((544u * idx) + 8u));
-  float2 vec2_f32 = asfloat(sb.Load2(((544u * idx) + 16u)));
-  int2 vec2_i32 = asint(sb.Load2(((544u * idx) + 24u)));
-  uint2 vec2_u32 = sb.Load2(((544u * idx) + 32u));
-  float3 vec3_f32 = asfloat(sb.Load3(((544u * idx) + 48u)));
-  int3 vec3_i32 = asint(sb.Load3(((544u * idx) + 64u)));
-  uint3 vec3_u32 = sb.Load3(((544u * idx) + 80u));
-  float4 vec4_f32 = asfloat(sb.Load4(((544u * idx) + 96u)));
-  int4 vec4_i32 = asint(sb.Load4(((544u * idx) + 112u)));
-  uint4 vec4_u32 = sb.Load4(((544u * idx) + 128u));
-  float2x2 mat2x2_f32 = sb_load_12(((544u * idx) + 144u));
-  float2x3 mat2x3_f32 = sb_load_13(((544u * idx) + 160u));
-  float2x4 mat2x4_f32 = sb_load_14(((544u * idx) + 192u));
-  float3x2 mat3x2_f32 = sb_load_15(((544u * idx) + 224u));
-  float3x3 mat3x3_f32 = sb_load_16(((544u * idx) + 256u));
-  float3x4 mat3x4_f32 = sb_load_17(((544u * idx) + 304u));
-  float4x2 mat4x2_f32 = sb_load_18(((544u * idx) + 352u));
-  float4x3 mat4x3_f32 = sb_load_19(((544u * idx) + 384u));
-  float4x4 mat4x4_f32 = sb_load_20(((544u * idx) + 448u));
-  float3 arr2_vec3_f32[2] = sb_load_21(((544u * idx) + 512u));
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 544u);
+  float scalar_f32 = asfloat(sb.Load((544u * min(idx, (tint_symbol_4 - 1u)))));
+  int scalar_i32 = asint(sb.Load(((544u * min(idx, (tint_symbol_4 - 1u))) + 4u)));
+  uint scalar_u32 = sb.Load(((544u * min(idx, (tint_symbol_4 - 1u))) + 8u));
+  float2 vec2_f32 = asfloat(sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 16u)));
+  int2 vec2_i32 = asint(sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 24u)));
+  uint2 vec2_u32 = sb.Load2(((544u * min(idx, (tint_symbol_4 - 1u))) + 32u));
+  float3 vec3_f32 = asfloat(sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 48u)));
+  int3 vec3_i32 = asint(sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 64u)));
+  uint3 vec3_u32 = sb.Load3(((544u * min(idx, (tint_symbol_4 - 1u))) + 80u));
+  float4 vec4_f32 = asfloat(sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 96u)));
+  int4 vec4_i32 = asint(sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 112u)));
+  uint4 vec4_u32 = sb.Load4(((544u * min(idx, (tint_symbol_4 - 1u))) + 128u));
+  float2x2 mat2x2_f32 = sb_load_12(((544u * min(idx, (tint_symbol_4 - 1u))) + 144u));
+  float2x3 mat2x3_f32 = sb_load_13(((544u * min(idx, (tint_symbol_4 - 1u))) + 160u));
+  float2x4 mat2x4_f32 = sb_load_14(((544u * min(idx, (tint_symbol_4 - 1u))) + 192u));
+  float3x2 mat3x2_f32 = sb_load_15(((544u * min(idx, (tint_symbol_4 - 1u))) + 224u));
+  float3x3 mat3x3_f32 = sb_load_16(((544u * min(idx, (tint_symbol_4 - 1u))) + 256u));
+  float3x4 mat3x4_f32 = sb_load_17(((544u * min(idx, (tint_symbol_4 - 1u))) + 304u));
+  float4x2 mat4x2_f32 = sb_load_18(((544u * min(idx, (tint_symbol_4 - 1u))) + 352u));
+  float4x3 mat4x3_f32 = sb_load_19(((544u * min(idx, (tint_symbol_4 - 1u))) + 384u));
+  float4x4 mat4x4_f32 = sb_load_20(((544u * min(idx, (tint_symbol_4 - 1u))) + 448u));
+  float3 arr2_vec3_f32[2] = sb_load_21(((544u * min(idx, (tint_symbol_4 - 1u))) + 512u));
   s.Store(0u, asuint((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + tint_ftoi(arr2_vec3_f32[0].x))));
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.glsl
index 479d3a5..3767a93 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.glsl
@@ -46,46 +46,68 @@
   return mix(2147483647, mix((-2147483647 - 1), int(value), (value >= -2147483648.0f)), (value <= 2147483520.0f));
 }
 void tint_symbol_inner(uint idx) {
-  float scalar_f32 = sb.arr[idx].scalar_f32;
-  int scalar_i32 = sb.arr[idx].scalar_i32;
-  uint scalar_u32 = sb.arr[idx].scalar_u32;
-  vec2 vec2_f32 = sb.arr[idx].vec2_f32;
-  ivec2 vec2_i32 = sb.arr[idx].vec2_i32;
-  uvec2 vec2_u32 = sb.arr[idx].vec2_u32;
-  vec3 vec3_f32 = sb.arr[idx].vec3_f32;
-  ivec3 vec3_i32 = sb.arr[idx].vec3_i32;
-  uvec3 vec3_u32 = sb.arr[idx].vec3_u32;
-  vec4 vec4_f32 = sb.arr[idx].vec4_f32;
-  ivec4 vec4_i32 = sb.arr[idx].vec4_i32;
-  uvec4 vec4_u32 = sb.arr[idx].vec4_u32;
-  mat2 mat2x2_f32 = sb.arr[idx].mat2x2_f32;
-  mat2x3 mat2x3_f32 = sb.arr[idx].mat2x3_f32;
-  mat2x4 mat2x4_f32 = sb.arr[idx].mat2x4_f32;
-  mat3x2 mat3x2_f32 = sb.arr[idx].mat3x2_f32;
-  mat3 mat3x3_f32 = sb.arr[idx].mat3x3_f32;
-  mat3x4 mat3x4_f32 = sb.arr[idx].mat3x4_f32;
-  mat4x2 mat4x2_f32 = sb.arr[idx].mat4x2_f32;
-  mat4x3 mat4x3_f32 = sb.arr[idx].mat4x3_f32;
-  mat4 mat4x4_f32 = sb.arr[idx].mat4x4_f32;
-  vec3 arr2_vec3_f32[2] = sb.arr[idx].arr2_vec3_f32;
-  int v_1 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
-  int v_2 = (v_1 + int(scalar_u32));
-  int v_3 = ((v_2 + tint_f32_to_i32(vec2_f32[0u])) + vec2_i32[0u]);
-  int v_4 = (v_3 + int(vec2_u32[0u]));
-  int v_5 = ((v_4 + tint_f32_to_i32(vec3_f32[1u])) + vec3_i32[1u]);
-  int v_6 = (v_5 + int(vec3_u32[1u]));
-  int v_7 = ((v_6 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
-  int v_8 = (v_7 + int(vec4_u32[2u]));
-  int v_9 = (v_8 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_10 = (v_9 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_11 = (v_10 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_12 = (v_11 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_13 = (v_12 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  v.inner = (v_17 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
+  uint v_1 = min(idx, (uint(sb.arr.length()) - 1u));
+  float scalar_f32 = sb.arr[v_1].scalar_f32;
+  uint v_2 = min(idx, (uint(sb.arr.length()) - 1u));
+  int scalar_i32 = sb.arr[v_2].scalar_i32;
+  uint v_3 = min(idx, (uint(sb.arr.length()) - 1u));
+  uint scalar_u32 = sb.arr[v_3].scalar_u32;
+  uint v_4 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec2 vec2_f32 = sb.arr[v_4].vec2_f32;
+  uint v_5 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec2 vec2_i32 = sb.arr[v_5].vec2_i32;
+  uint v_6 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec2 vec2_u32 = sb.arr[v_6].vec2_u32;
+  uint v_7 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec3 vec3_f32 = sb.arr[v_7].vec3_f32;
+  uint v_8 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec3 vec3_i32 = sb.arr[v_8].vec3_i32;
+  uint v_9 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec3 vec3_u32 = sb.arr[v_9].vec3_u32;
+  uint v_10 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec4 vec4_f32 = sb.arr[v_10].vec4_f32;
+  uint v_11 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec4 vec4_i32 = sb.arr[v_11].vec4_i32;
+  uint v_12 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec4 vec4_u32 = sb.arr[v_12].vec4_u32;
+  uint v_13 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2 mat2x2_f32 = sb.arr[v_13].mat2x2_f32;
+  uint v_14 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2x3 mat2x3_f32 = sb.arr[v_14].mat2x3_f32;
+  uint v_15 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2x4 mat2x4_f32 = sb.arr[v_15].mat2x4_f32;
+  uint v_16 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3x2 mat3x2_f32 = sb.arr[v_16].mat3x2_f32;
+  uint v_17 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3 mat3x3_f32 = sb.arr[v_17].mat3x3_f32;
+  uint v_18 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3x4 mat3x4_f32 = sb.arr[v_18].mat3x4_f32;
+  uint v_19 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4x2 mat4x2_f32 = sb.arr[v_19].mat4x2_f32;
+  uint v_20 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4x3 mat4x3_f32 = sb.arr[v_20].mat4x3_f32;
+  uint v_21 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4 mat4x4_f32 = sb.arr[v_21].mat4x4_f32;
+  uint v_22 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec3 arr2_vec3_f32[2] = sb.arr[v_22].arr2_vec3_f32;
+  int v_23 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
+  int v_24 = (v_23 + int(scalar_u32));
+  int v_25 = ((v_24 + tint_f32_to_i32(vec2_f32[0u])) + vec2_i32[0u]);
+  int v_26 = (v_25 + int(vec2_u32[0u]));
+  int v_27 = ((v_26 + tint_f32_to_i32(vec3_f32[1u])) + vec3_i32[1u]);
+  int v_28 = (v_27 + int(vec3_u32[1u]));
+  int v_29 = ((v_28 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
+  int v_30 = (v_29 + int(vec4_u32[2u]));
+  int v_31 = (v_30 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_32 = (v_31 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_33 = (v_32 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_34 = (v_33 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_35 = (v_34 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_36 = (v_35 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_37 = (v_36 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_38 = (v_37 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_39 = (v_38 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  v.inner = (v_39 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
index 233aa7c..baceb12 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
@@ -68,46 +68,90 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((0u + (idx * 544u))));
-  int scalar_i32 = asint(sb.Load((4u + (idx * 544u))));
-  uint scalar_u32 = sb.Load((8u + (idx * 544u)));
-  float2 vec2_f32 = asfloat(sb.Load2((16u + (idx * 544u))));
-  int2 vec2_i32 = asint(sb.Load2((24u + (idx * 544u))));
-  uint2 vec2_u32 = sb.Load2((32u + (idx * 544u)));
-  float3 vec3_f32 = asfloat(sb.Load3((48u + (idx * 544u))));
-  int3 vec3_i32 = asint(sb.Load3((64u + (idx * 544u))));
-  uint3 vec3_u32 = sb.Load3((80u + (idx * 544u)));
-  float4 vec4_f32 = asfloat(sb.Load4((96u + (idx * 544u))));
-  int4 vec4_i32 = asint(sb.Load4((112u + (idx * 544u))));
-  uint4 vec4_u32 = sb.Load4((128u + (idx * 544u)));
-  float2x2 mat2x2_f32 = v_12((144u + (idx * 544u)));
-  float2x3 mat2x3_f32 = v_11((160u + (idx * 544u)));
-  float2x4 mat2x4_f32 = v_10((192u + (idx * 544u)));
-  float3x2 mat3x2_f32 = v_9((224u + (idx * 544u)));
-  float3x3 mat3x3_f32 = v_8((256u + (idx * 544u)));
-  float3x4 mat3x4_f32 = v_7((304u + (idx * 544u)));
-  float4x2 mat4x2_f32 = v_6((352u + (idx * 544u)));
-  float4x3 mat4x3_f32 = v_5((384u + (idx * 544u)));
-  float4x4 mat4x4_f32 = v_4((448u + (idx * 544u)));
-  float3 arr2_vec3_f32[2] = v((512u + (idx * 544u)));
-  int v_13 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
-  int v_14 = (v_13 + int(scalar_u32));
-  int v_15 = ((v_14 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
-  int v_16 = (v_15 + int(vec2_u32.x));
-  int v_17 = ((v_16 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
-  int v_18 = (v_17 + int(vec3_u32.y));
-  int v_19 = ((v_18 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
-  int v_20 = (v_19 + int(vec4_u32.z));
-  int v_21 = (v_20 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_22 = (v_21 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_23 = (v_22 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_24 = (v_23 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_25 = (v_24 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_26 = (v_25 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_27 = (v_26 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_28 = (v_27 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_29 = (v_28 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((v_29 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x))));
+  uint v_13 = 0u;
+  sb.GetDimensions(v_13);
+  float scalar_f32 = asfloat(sb.Load((0u + (min(idx, ((v_13 / 544u) - 1u)) * 544u))));
+  uint v_14 = 0u;
+  sb.GetDimensions(v_14);
+  int scalar_i32 = asint(sb.Load((4u + (min(idx, ((v_14 / 544u) - 1u)) * 544u))));
+  uint v_15 = 0u;
+  sb.GetDimensions(v_15);
+  uint scalar_u32 = sb.Load((8u + (min(idx, ((v_15 / 544u) - 1u)) * 544u)));
+  uint v_16 = 0u;
+  sb.GetDimensions(v_16);
+  float2 vec2_f32 = asfloat(sb.Load2((16u + (min(idx, ((v_16 / 544u) - 1u)) * 544u))));
+  uint v_17 = 0u;
+  sb.GetDimensions(v_17);
+  int2 vec2_i32 = asint(sb.Load2((24u + (min(idx, ((v_17 / 544u) - 1u)) * 544u))));
+  uint v_18 = 0u;
+  sb.GetDimensions(v_18);
+  uint2 vec2_u32 = sb.Load2((32u + (min(idx, ((v_18 / 544u) - 1u)) * 544u)));
+  uint v_19 = 0u;
+  sb.GetDimensions(v_19);
+  float3 vec3_f32 = asfloat(sb.Load3((48u + (min(idx, ((v_19 / 544u) - 1u)) * 544u))));
+  uint v_20 = 0u;
+  sb.GetDimensions(v_20);
+  int3 vec3_i32 = asint(sb.Load3((64u + (min(idx, ((v_20 / 544u) - 1u)) * 544u))));
+  uint v_21 = 0u;
+  sb.GetDimensions(v_21);
+  uint3 vec3_u32 = sb.Load3((80u + (min(idx, ((v_21 / 544u) - 1u)) * 544u)));
+  uint v_22 = 0u;
+  sb.GetDimensions(v_22);
+  float4 vec4_f32 = asfloat(sb.Load4((96u + (min(idx, ((v_22 / 544u) - 1u)) * 544u))));
+  uint v_23 = 0u;
+  sb.GetDimensions(v_23);
+  int4 vec4_i32 = asint(sb.Load4((112u + (min(idx, ((v_23 / 544u) - 1u)) * 544u))));
+  uint v_24 = 0u;
+  sb.GetDimensions(v_24);
+  uint4 vec4_u32 = sb.Load4((128u + (min(idx, ((v_24 / 544u) - 1u)) * 544u)));
+  uint v_25 = 0u;
+  sb.GetDimensions(v_25);
+  float2x2 mat2x2_f32 = v_12((144u + (min(idx, ((v_25 / 544u) - 1u)) * 544u)));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  float2x3 mat2x3_f32 = v_11((160u + (min(idx, ((v_26 / 544u) - 1u)) * 544u)));
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  float2x4 mat2x4_f32 = v_10((192u + (min(idx, ((v_27 / 544u) - 1u)) * 544u)));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  float3x2 mat3x2_f32 = v_9((224u + (min(idx, ((v_28 / 544u) - 1u)) * 544u)));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  float3x3 mat3x3_f32 = v_8((256u + (min(idx, ((v_29 / 544u) - 1u)) * 544u)));
+  uint v_30 = 0u;
+  sb.GetDimensions(v_30);
+  float3x4 mat3x4_f32 = v_7((304u + (min(idx, ((v_30 / 544u) - 1u)) * 544u)));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  float4x2 mat4x2_f32 = v_6((352u + (min(idx, ((v_31 / 544u) - 1u)) * 544u)));
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  float4x3 mat4x3_f32 = v_5((384u + (min(idx, ((v_32 / 544u) - 1u)) * 544u)));
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  float4x4 mat4x4_f32 = v_4((448u + (min(idx, ((v_33 / 544u) - 1u)) * 544u)));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  float3 arr2_vec3_f32[2] = v((512u + (min(idx, ((v_34 / 544u) - 1u)) * 544u)));
+  int v_35 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
+  int v_36 = (v_35 + int(scalar_u32));
+  int v_37 = ((v_36 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
+  int v_38 = (v_37 + int(vec2_u32.x));
+  int v_39 = ((v_38 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
+  int v_40 = (v_39 + int(vec3_u32.y));
+  int v_41 = ((v_40 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
+  int v_42 = (v_41 + int(vec4_u32.z));
+  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((v_51 + tint_f32_to_i32(arr2_vec3_f32[0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
index 233aa7c..baceb12 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
@@ -68,46 +68,90 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((0u + (idx * 544u))));
-  int scalar_i32 = asint(sb.Load((4u + (idx * 544u))));
-  uint scalar_u32 = sb.Load((8u + (idx * 544u)));
-  float2 vec2_f32 = asfloat(sb.Load2((16u + (idx * 544u))));
-  int2 vec2_i32 = asint(sb.Load2((24u + (idx * 544u))));
-  uint2 vec2_u32 = sb.Load2((32u + (idx * 544u)));
-  float3 vec3_f32 = asfloat(sb.Load3((48u + (idx * 544u))));
-  int3 vec3_i32 = asint(sb.Load3((64u + (idx * 544u))));
-  uint3 vec3_u32 = sb.Load3((80u + (idx * 544u)));
-  float4 vec4_f32 = asfloat(sb.Load4((96u + (idx * 544u))));
-  int4 vec4_i32 = asint(sb.Load4((112u + (idx * 544u))));
-  uint4 vec4_u32 = sb.Load4((128u + (idx * 544u)));
-  float2x2 mat2x2_f32 = v_12((144u + (idx * 544u)));
-  float2x3 mat2x3_f32 = v_11((160u + (idx * 544u)));
-  float2x4 mat2x4_f32 = v_10((192u + (idx * 544u)));
-  float3x2 mat3x2_f32 = v_9((224u + (idx * 544u)));
-  float3x3 mat3x3_f32 = v_8((256u + (idx * 544u)));
-  float3x4 mat3x4_f32 = v_7((304u + (idx * 544u)));
-  float4x2 mat4x2_f32 = v_6((352u + (idx * 544u)));
-  float4x3 mat4x3_f32 = v_5((384u + (idx * 544u)));
-  float4x4 mat4x4_f32 = v_4((448u + (idx * 544u)));
-  float3 arr2_vec3_f32[2] = v((512u + (idx * 544u)));
-  int v_13 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
-  int v_14 = (v_13 + int(scalar_u32));
-  int v_15 = ((v_14 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
-  int v_16 = (v_15 + int(vec2_u32.x));
-  int v_17 = ((v_16 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
-  int v_18 = (v_17 + int(vec3_u32.y));
-  int v_19 = ((v_18 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
-  int v_20 = (v_19 + int(vec4_u32.z));
-  int v_21 = (v_20 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_22 = (v_21 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_23 = (v_22 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_24 = (v_23 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_25 = (v_24 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_26 = (v_25 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_27 = (v_26 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_28 = (v_27 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_29 = (v_28 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((v_29 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x))));
+  uint v_13 = 0u;
+  sb.GetDimensions(v_13);
+  float scalar_f32 = asfloat(sb.Load((0u + (min(idx, ((v_13 / 544u) - 1u)) * 544u))));
+  uint v_14 = 0u;
+  sb.GetDimensions(v_14);
+  int scalar_i32 = asint(sb.Load((4u + (min(idx, ((v_14 / 544u) - 1u)) * 544u))));
+  uint v_15 = 0u;
+  sb.GetDimensions(v_15);
+  uint scalar_u32 = sb.Load((8u + (min(idx, ((v_15 / 544u) - 1u)) * 544u)));
+  uint v_16 = 0u;
+  sb.GetDimensions(v_16);
+  float2 vec2_f32 = asfloat(sb.Load2((16u + (min(idx, ((v_16 / 544u) - 1u)) * 544u))));
+  uint v_17 = 0u;
+  sb.GetDimensions(v_17);
+  int2 vec2_i32 = asint(sb.Load2((24u + (min(idx, ((v_17 / 544u) - 1u)) * 544u))));
+  uint v_18 = 0u;
+  sb.GetDimensions(v_18);
+  uint2 vec2_u32 = sb.Load2((32u + (min(idx, ((v_18 / 544u) - 1u)) * 544u)));
+  uint v_19 = 0u;
+  sb.GetDimensions(v_19);
+  float3 vec3_f32 = asfloat(sb.Load3((48u + (min(idx, ((v_19 / 544u) - 1u)) * 544u))));
+  uint v_20 = 0u;
+  sb.GetDimensions(v_20);
+  int3 vec3_i32 = asint(sb.Load3((64u + (min(idx, ((v_20 / 544u) - 1u)) * 544u))));
+  uint v_21 = 0u;
+  sb.GetDimensions(v_21);
+  uint3 vec3_u32 = sb.Load3((80u + (min(idx, ((v_21 / 544u) - 1u)) * 544u)));
+  uint v_22 = 0u;
+  sb.GetDimensions(v_22);
+  float4 vec4_f32 = asfloat(sb.Load4((96u + (min(idx, ((v_22 / 544u) - 1u)) * 544u))));
+  uint v_23 = 0u;
+  sb.GetDimensions(v_23);
+  int4 vec4_i32 = asint(sb.Load4((112u + (min(idx, ((v_23 / 544u) - 1u)) * 544u))));
+  uint v_24 = 0u;
+  sb.GetDimensions(v_24);
+  uint4 vec4_u32 = sb.Load4((128u + (min(idx, ((v_24 / 544u) - 1u)) * 544u)));
+  uint v_25 = 0u;
+  sb.GetDimensions(v_25);
+  float2x2 mat2x2_f32 = v_12((144u + (min(idx, ((v_25 / 544u) - 1u)) * 544u)));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  float2x3 mat2x3_f32 = v_11((160u + (min(idx, ((v_26 / 544u) - 1u)) * 544u)));
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  float2x4 mat2x4_f32 = v_10((192u + (min(idx, ((v_27 / 544u) - 1u)) * 544u)));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  float3x2 mat3x2_f32 = v_9((224u + (min(idx, ((v_28 / 544u) - 1u)) * 544u)));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  float3x3 mat3x3_f32 = v_8((256u + (min(idx, ((v_29 / 544u) - 1u)) * 544u)));
+  uint v_30 = 0u;
+  sb.GetDimensions(v_30);
+  float3x4 mat3x4_f32 = v_7((304u + (min(idx, ((v_30 / 544u) - 1u)) * 544u)));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  float4x2 mat4x2_f32 = v_6((352u + (min(idx, ((v_31 / 544u) - 1u)) * 544u)));
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  float4x3 mat4x3_f32 = v_5((384u + (min(idx, ((v_32 / 544u) - 1u)) * 544u)));
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  float4x4 mat4x4_f32 = v_4((448u + (min(idx, ((v_33 / 544u) - 1u)) * 544u)));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  float3 arr2_vec3_f32[2] = v((512u + (min(idx, ((v_34 / 544u) - 1u)) * 544u)));
+  int v_35 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
+  int v_36 = (v_35 + int(scalar_u32));
+  int v_37 = ((v_36 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
+  int v_38 = (v_37 + int(vec2_u32.x));
+  int v_39 = ((v_38 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
+  int v_40 = (v_39 + int(vec3_u32.y));
+  int v_41 = ((v_40 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
+  int v_42 = (v_41 + int(vec4_u32.z));
+  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((v_51 + tint_f32_to_i32(arr2_vec3_f32[0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.msl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.msl
index 3e98afa..2a70609 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.ir.msl
@@ -56,6 +56,7 @@
 struct tint_module_vars_struct {
   const device S_packed_vec3* sb;
   device int* s;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 int tint_f32_to_i32(float value) {
@@ -68,37 +69,37 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  float const scalar_f32 = (*tint_module_vars.sb).arr[idx].scalar_f32;
-  int const scalar_i32 = (*tint_module_vars.sb).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*tint_module_vars.sb).arr[idx].scalar_u32;
-  float2 const vec2_f32 = (*tint_module_vars.sb).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*tint_module_vars.sb).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*tint_module_vars.sb).arr[idx].vec2_u32;
-  float3 const vec3_f32 = float3((*tint_module_vars.sb).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*tint_module_vars.sb).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*tint_module_vars.sb).arr[idx].vec3_u32);
-  float4 const vec4_f32 = (*tint_module_vars.sb).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*tint_module_vars.sb).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*tint_module_vars.sb).arr[idx].vec4_u32;
-  float2x2 const mat2x2_f32 = (*tint_module_vars.sb).arr[idx].mat2x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.sb).arr[idx].mat2x3_f32;
+  float const scalar_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_f32;
+  int const scalar_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_i32;
+  uint const scalar_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_u32;
+  float2 const vec2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_f32;
+  int2 const vec2_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_i32;
+  uint2 const vec2_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_u32;
+  float3 const vec3_f32 = float3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_f32);
+  int3 const vec3_i32 = int3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_i32);
+  uint3 const vec3_u32 = uint3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_u32);
+  float4 const vec4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_f32;
+  int4 const vec4_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_i32;
+  uint4 const vec4_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_u32;
+  float2x2 const mat2x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x3_f32;
   float3 const v_2 = float3(v_1[0u].packed);
   float2x3 const mat2x3_f32 = float2x3(v_2, float3(v_1[1u].packed));
-  float2x4 const mat2x4_f32 = (*tint_module_vars.sb).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*tint_module_vars.sb).arr[idx].mat3x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.sb).arr[idx].mat3x3_f32;
+  float2x4 const mat2x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x3_f32;
   float3 const v_4 = float3(v_3[0u].packed);
   float3 const v_5 = float3(v_3[1u].packed);
   float3x3 const mat3x3_f32 = float3x3(v_4, v_5, float3(v_3[2u].packed));
-  float3x4 const mat3x4_f32 = (*tint_module_vars.sb).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*tint_module_vars.sb).arr[idx].mat4x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.sb).arr[idx].mat4x3_f32;
+  float3x4 const mat3x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x3_f32;
   float3 const v_7 = float3(v_6[0u].packed);
   float3 const v_8 = float3(v_6[1u].packed);
   float3 const v_9 = float3(v_6[2u].packed);
   float4x3 const mat4x3_f32 = float4x3(v_7, v_8, v_9, float3(v_6[3u].packed));
-  float4x4 const mat4x4_f32 = (*tint_module_vars.sb).arr[idx].mat4x4_f32;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.sb).arr[idx].arr2_vec3_f32));
+  float4x4 const mat4x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x4_f32;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].arr2_vec3_f32));
   int const v_10 = as_type<int>((as_type<uint>(tint_f32_to_i32(scalar_f32)) + as_type<uint>(scalar_i32)));
   int const v_11 = as_type<int>((as_type<uint>(v_10) + as_type<uint>(int(scalar_u32))));
   int const v_12 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_11) + as_type<uint>(tint_f32_to_i32(vec2_f32[0u]))))) + as_type<uint>(vec2_i32[0u])));
@@ -107,19 +108,19 @@
   int const v_15 = as_type<int>((as_type<uint>(v_14) + as_type<uint>(int(vec3_u32[1u]))));
   int const v_16 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_15) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_17 = as_type<int>((as_type<uint>(v_16) + as_type<uint>(int(vec4_u32[2u]))));
-  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
+  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
 }
 
-kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const device S_packed_vec3* sb [[buffer(1)]], device int* s [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .s=s};
+kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const device S_packed_vec3* sb [[buffer(1)]], device int* s [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .s=s, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(idx, tint_module_vars);
 }
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.msl
index 43474d1..40b1142 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.msl
@@ -74,6 +74,10 @@
   return result;
 }
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 int tint_ftoi(float v) {
   return select(2147483647, select(int(v), (-2147483647 - 1), (v < -2147483648.0f)), (v <= 2147483520.0f));
 }
@@ -107,34 +111,34 @@
   tint_array<Inner, 1> arr;
 };
 
-void tint_symbol_inner(uint idx, const device S_tint_packed_vec3* const tint_symbol_1, device int* const tint_symbol_2) {
-  float const scalar_f32 = (*(tint_symbol_1)).arr[idx].scalar_f32;
-  int const scalar_i32 = (*(tint_symbol_1)).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*(tint_symbol_1)).arr[idx].scalar_u32;
-  float2 const vec2_f32 = (*(tint_symbol_1)).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*(tint_symbol_1)).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[idx].vec2_u32;
-  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[idx].vec3_u32);
-  float4 const vec4_f32 = (*(tint_symbol_1)).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*(tint_symbol_1)).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[idx].vec4_u32;
-  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[idx].mat2x2_f32;
-  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[idx].mat2x3_f32);
-  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[idx].mat3x2_f32;
-  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[idx].mat3x3_f32);
-  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[idx].mat4x2_f32;
-  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[idx].mat4x3_f32);
-  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[idx].mat4x4_f32;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[idx].arr2_vec3_f32);
-  *(tint_symbol_2) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))));
+void tint_symbol_inner(uint idx, const device S_tint_packed_vec3* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2, device int* const tint_symbol_3) {
+  float const scalar_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_f32;
+  int const scalar_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_i32;
+  uint const scalar_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_u32;
+  float2 const vec2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_f32;
+  int2 const vec2_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_i32;
+  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_u32;
+  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_f32);
+  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_i32);
+  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_u32);
+  float4 const vec4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_f32;
+  int4 const vec4_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_i32;
+  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_u32;
+  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x2_f32;
+  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x3_f32);
+  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x2_f32;
+  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x3_f32);
+  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x2_f32;
+  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x3_f32);
+  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x4_f32;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].arr2_vec3_f32);
+  *(tint_symbol_3) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))));
 }
 
-kernel void tint_symbol(const device S_tint_packed_vec3* tint_symbol_3 [[buffer(1)]], device int* tint_symbol_4 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
-  tint_symbol_inner(idx, tint_symbol_3, tint_symbol_4);
+kernel void tint_symbol(const device S_tint_packed_vec3* tint_symbol_4 [[buffer(1)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]], device int* tint_symbol_6 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
+  tint_symbol_inner(idx, tint_symbol_4, tint_symbol_5, tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.spvasm
index f575c7d..7fde976 100644
--- a/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/read.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 205
+; Bound: 295
 ; Schema: 0
                OpCapability Shader
+         %46 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -151,10 +152,11 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %37 = OpTypeFunction %void %uint
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_Inner = OpTypePointer StorageBuffer %_runtimearr_Inner
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
      %uint_3 = OpConstant %uint 3
@@ -195,135 +197,223 @@
 %_ptr_StorageBuffer__arr_v3float_uint_2 = OpTypePointer StorageBuffer %_arr_v3float_uint_2
     %uint_21 = OpConstant %uint 21
 %_ptr_StorageBuffer_int_0 = OpTypePointer StorageBuffer %int
-        %188 = OpTypeFunction %int %float
+        %278 = OpTypeFunction %int %float
 %float_n2_14748365e_09 = OpConstant %float -2.14748365e+09
        %bool = OpTypeBool
 %int_n2147483648 = OpConstant %int -2147483648
 %float_2_14748352e_09 = OpConstant %float 2.14748352e+09
 %int_2147483647 = OpConstant %int 2147483647
-        %201 = OpTypeFunction %void
+        %291 = OpTypeFunction %void
  %main_inner = OpFunction %void None %37
         %idx = OpFunctionParameter %uint
          %38 = OpLabel
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
- %scalar_f32 = OpLoad %float %39 None
-         %43 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
- %scalar_i32 = OpLoad %int %43 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
- %scalar_u32 = OpLoad %uint %47 None
-         %50 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_3
-   %vec2_f32 = OpLoad %v2float %50 None
-         %54 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_4
-   %vec2_i32 = OpLoad %v2int %54 None
-         %58 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_5
-   %vec2_u32 = OpLoad %v2uint %58 None
-         %62 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_6
-   %vec3_f32 = OpLoad %v3float %62 None
-         %66 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_7
-   %vec3_i32 = OpLoad %v3int %66 None
-         %70 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_8
-   %vec3_u32 = OpLoad %v3uint %70 None
-         %74 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_9
-   %vec4_f32 = OpLoad %v4float %74 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_10
-   %vec4_i32 = OpLoad %v4int %78 None
-         %82 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_11
-   %vec4_u32 = OpLoad %v4uint %82 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_12
- %mat2x2_f32 = OpLoad %mat2v2float %86 None
-         %90 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %idx %uint_13
- %mat2x3_f32 = OpLoad %mat2v3float %90 None
-         %94 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_14
- %mat2x4_f32 = OpLoad %mat2v4float %94 None
-         %98 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_15
- %mat3x2_f32 = OpLoad %mat3v2float %98 None
-        %102 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %idx %uint_16
- %mat3x3_f32 = OpLoad %mat3v3float %102 None
-        %106 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_17
- %mat3x4_f32 = OpLoad %mat3v4float %106 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_18
- %mat4x2_f32 = OpLoad %mat4v2float %110 None
-        %114 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %idx %uint_19
- %mat4x3_f32 = OpLoad %mat4v3float %114 None
-        %118 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_20
- %mat4x4_f32 = OpLoad %mat4v4float %118 None
-        %122 = OpAccessChain %_ptr_StorageBuffer__arr_v3float_uint_2 %sb %uint_0 %idx %uint_21
-%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %122 None
-        %126 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
-        %128 = OpIAdd %int %126 %scalar_i32
-        %129 = OpBitcast %int %scalar_u32
-        %130 = OpIAdd %int %128 %129
-        %131 = OpCompositeExtract %float %vec2_f32 0
-        %132 = OpFunctionCall %int %tint_f32_to_i32 %131
-        %133 = OpIAdd %int %130 %132
-        %134 = OpCompositeExtract %int %vec2_i32 0
-        %135 = OpIAdd %int %133 %134
-        %136 = OpCompositeExtract %uint %vec2_u32 0
-        %137 = OpBitcast %int %136
-        %138 = OpIAdd %int %135 %137
-        %139 = OpCompositeExtract %float %vec3_f32 1
-        %140 = OpFunctionCall %int %tint_f32_to_i32 %139
-        %141 = OpIAdd %int %138 %140
-        %142 = OpCompositeExtract %int %vec3_i32 1
-        %143 = OpIAdd %int %141 %142
-        %144 = OpCompositeExtract %uint %vec3_u32 1
-        %145 = OpBitcast %int %144
-        %146 = OpIAdd %int %143 %145
-        %147 = OpCompositeExtract %float %vec4_f32 2
-        %148 = OpFunctionCall %int %tint_f32_to_i32 %147
-        %149 = OpIAdd %int %146 %148
-        %150 = OpCompositeExtract %int %vec4_i32 2
-        %151 = OpIAdd %int %149 %150
-        %152 = OpCompositeExtract %uint %vec4_u32 2
-        %153 = OpBitcast %int %152
-        %154 = OpIAdd %int %151 %153
-        %155 = OpCompositeExtract %float %mat2x2_f32 0 0
-        %156 = OpFunctionCall %int %tint_f32_to_i32 %155
-        %157 = OpIAdd %int %154 %156
-        %158 = OpCompositeExtract %float %mat2x3_f32 0 0
-        %159 = OpFunctionCall %int %tint_f32_to_i32 %158
-        %160 = OpIAdd %int %157 %159
-        %161 = OpCompositeExtract %float %mat2x4_f32 0 0
-        %162 = OpFunctionCall %int %tint_f32_to_i32 %161
-        %163 = OpIAdd %int %160 %162
-        %164 = OpCompositeExtract %float %mat3x2_f32 0 0
-        %165 = OpFunctionCall %int %tint_f32_to_i32 %164
-        %166 = OpIAdd %int %163 %165
-        %167 = OpCompositeExtract %float %mat3x3_f32 0 0
-        %168 = OpFunctionCall %int %tint_f32_to_i32 %167
-        %169 = OpIAdd %int %166 %168
-        %170 = OpCompositeExtract %float %mat3x4_f32 0 0
-        %171 = OpFunctionCall %int %tint_f32_to_i32 %170
-        %172 = OpIAdd %int %169 %171
-        %173 = OpCompositeExtract %float %mat4x2_f32 0 0
-        %174 = OpFunctionCall %int %tint_f32_to_i32 %173
-        %175 = OpIAdd %int %172 %174
-        %176 = OpCompositeExtract %float %mat4x3_f32 0 0
-        %177 = OpFunctionCall %int %tint_f32_to_i32 %176
-        %178 = OpIAdd %int %175 %177
-        %179 = OpCompositeExtract %float %mat4x4_f32 0 0
-        %180 = OpFunctionCall %int %tint_f32_to_i32 %179
-        %181 = OpIAdd %int %178 %180
-        %182 = OpCompositeExtract %float %arr2_vec3_f32 0 0
-        %183 = OpFunctionCall %int %tint_f32_to_i32 %182
-        %184 = OpIAdd %int %181 %183
-        %185 = OpAccessChain %_ptr_StorageBuffer_int_0 %29 %uint_0
-               OpStore %185 %184 None
+         %39 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %42 = OpArrayLength %uint %sb 0
+         %43 = OpISub %uint %42 %uint_1
+         %45 = OpExtInst %uint %46 UMin %idx %43
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %45 %uint_0
+ %scalar_f32 = OpLoad %float %47 None
+         %50 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %51 = OpArrayLength %uint %sb 0
+         %52 = OpISub %uint %51 %uint_1
+         %53 = OpExtInst %uint %46 UMin %idx %52
+         %54 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %53 %uint_1
+ %scalar_i32 = OpLoad %int %54 None
+         %57 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %58 = OpArrayLength %uint %sb 0
+         %59 = OpISub %uint %58 %uint_1
+         %60 = OpExtInst %uint %46 UMin %idx %59
+         %61 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %60 %uint_2
+ %scalar_u32 = OpLoad %uint %61 None
+         %64 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %65 = OpArrayLength %uint %sb 0
+         %66 = OpISub %uint %65 %uint_1
+         %67 = OpExtInst %uint %46 UMin %idx %66
+         %68 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %67 %uint_3
+   %vec2_f32 = OpLoad %v2float %68 None
+         %72 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %73 = OpArrayLength %uint %sb 0
+         %74 = OpISub %uint %73 %uint_1
+         %75 = OpExtInst %uint %46 UMin %idx %74
+         %76 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %75 %uint_4
+   %vec2_i32 = OpLoad %v2int %76 None
+         %80 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %81 = OpArrayLength %uint %sb 0
+         %82 = OpISub %uint %81 %uint_1
+         %83 = OpExtInst %uint %46 UMin %idx %82
+         %84 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %83 %uint_5
+   %vec2_u32 = OpLoad %v2uint %84 None
+         %88 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %89 = OpArrayLength %uint %sb 0
+         %90 = OpISub %uint %89 %uint_1
+         %91 = OpExtInst %uint %46 UMin %idx %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %91 %uint_6
+   %vec3_f32 = OpLoad %v3float %92 None
+         %96 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %97 = OpArrayLength %uint %sb 0
+         %98 = OpISub %uint %97 %uint_1
+         %99 = OpExtInst %uint %46 UMin %idx %98
+        %100 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %99 %uint_7
+   %vec3_i32 = OpLoad %v3int %100 None
+        %104 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %105 = OpArrayLength %uint %sb 0
+        %106 = OpISub %uint %105 %uint_1
+        %107 = OpExtInst %uint %46 UMin %idx %106
+        %108 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %107 %uint_8
+   %vec3_u32 = OpLoad %v3uint %108 None
+        %112 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %113 = OpArrayLength %uint %sb 0
+        %114 = OpISub %uint %113 %uint_1
+        %115 = OpExtInst %uint %46 UMin %idx %114
+        %116 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %115 %uint_9
+   %vec4_f32 = OpLoad %v4float %116 None
+        %120 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %121 = OpArrayLength %uint %sb 0
+        %122 = OpISub %uint %121 %uint_1
+        %123 = OpExtInst %uint %46 UMin %idx %122
+        %124 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %123 %uint_10
+   %vec4_i32 = OpLoad %v4int %124 None
+        %128 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %129 = OpArrayLength %uint %sb 0
+        %130 = OpISub %uint %129 %uint_1
+        %131 = OpExtInst %uint %46 UMin %idx %130
+        %132 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %131 %uint_11
+   %vec4_u32 = OpLoad %v4uint %132 None
+        %136 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %137 = OpArrayLength %uint %sb 0
+        %138 = OpISub %uint %137 %uint_1
+        %139 = OpExtInst %uint %46 UMin %idx %138
+        %140 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %139 %uint_12
+ %mat2x2_f32 = OpLoad %mat2v2float %140 None
+        %144 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %145 = OpArrayLength %uint %sb 0
+        %146 = OpISub %uint %145 %uint_1
+        %147 = OpExtInst %uint %46 UMin %idx %146
+        %148 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %147 %uint_13
+ %mat2x3_f32 = OpLoad %mat2v3float %148 None
+        %152 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %153 = OpArrayLength %uint %sb 0
+        %154 = OpISub %uint %153 %uint_1
+        %155 = OpExtInst %uint %46 UMin %idx %154
+        %156 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %155 %uint_14
+ %mat2x4_f32 = OpLoad %mat2v4float %156 None
+        %160 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %161 = OpArrayLength %uint %sb 0
+        %162 = OpISub %uint %161 %uint_1
+        %163 = OpExtInst %uint %46 UMin %idx %162
+        %164 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %163 %uint_15
+ %mat3x2_f32 = OpLoad %mat3v2float %164 None
+        %168 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %169 = OpArrayLength %uint %sb 0
+        %170 = OpISub %uint %169 %uint_1
+        %171 = OpExtInst %uint %46 UMin %idx %170
+        %172 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %171 %uint_16
+ %mat3x3_f32 = OpLoad %mat3v3float %172 None
+        %176 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %177 = OpArrayLength %uint %sb 0
+        %178 = OpISub %uint %177 %uint_1
+        %179 = OpExtInst %uint %46 UMin %idx %178
+        %180 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %179 %uint_17
+ %mat3x4_f32 = OpLoad %mat3v4float %180 None
+        %184 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %185 = OpArrayLength %uint %sb 0
+        %186 = OpISub %uint %185 %uint_1
+        %187 = OpExtInst %uint %46 UMin %idx %186
+        %188 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %187 %uint_18
+ %mat4x2_f32 = OpLoad %mat4v2float %188 None
+        %192 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %193 = OpArrayLength %uint %sb 0
+        %194 = OpISub %uint %193 %uint_1
+        %195 = OpExtInst %uint %46 UMin %idx %194
+        %196 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %195 %uint_19
+ %mat4x3_f32 = OpLoad %mat4v3float %196 None
+        %200 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %201 = OpArrayLength %uint %sb 0
+        %202 = OpISub %uint %201 %uint_1
+        %203 = OpExtInst %uint %46 UMin %idx %202
+        %204 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %203 %uint_20
+ %mat4x4_f32 = OpLoad %mat4v4float %204 None
+        %208 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %209 = OpArrayLength %uint %sb 0
+        %210 = OpISub %uint %209 %uint_1
+        %211 = OpExtInst %uint %46 UMin %idx %210
+        %212 = OpAccessChain %_ptr_StorageBuffer__arr_v3float_uint_2 %sb %uint_0 %211 %uint_21
+%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %212 None
+        %216 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
+        %218 = OpIAdd %int %216 %scalar_i32
+        %219 = OpBitcast %int %scalar_u32
+        %220 = OpIAdd %int %218 %219
+        %221 = OpCompositeExtract %float %vec2_f32 0
+        %222 = OpFunctionCall %int %tint_f32_to_i32 %221
+        %223 = OpIAdd %int %220 %222
+        %224 = OpCompositeExtract %int %vec2_i32 0
+        %225 = OpIAdd %int %223 %224
+        %226 = OpCompositeExtract %uint %vec2_u32 0
+        %227 = OpBitcast %int %226
+        %228 = OpIAdd %int %225 %227
+        %229 = OpCompositeExtract %float %vec3_f32 1
+        %230 = OpFunctionCall %int %tint_f32_to_i32 %229
+        %231 = OpIAdd %int %228 %230
+        %232 = OpCompositeExtract %int %vec3_i32 1
+        %233 = OpIAdd %int %231 %232
+        %234 = OpCompositeExtract %uint %vec3_u32 1
+        %235 = OpBitcast %int %234
+        %236 = OpIAdd %int %233 %235
+        %237 = OpCompositeExtract %float %vec4_f32 2
+        %238 = OpFunctionCall %int %tint_f32_to_i32 %237
+        %239 = OpIAdd %int %236 %238
+        %240 = OpCompositeExtract %int %vec4_i32 2
+        %241 = OpIAdd %int %239 %240
+        %242 = OpCompositeExtract %uint %vec4_u32 2
+        %243 = OpBitcast %int %242
+        %244 = OpIAdd %int %241 %243
+        %245 = OpCompositeExtract %float %mat2x2_f32 0 0
+        %246 = OpFunctionCall %int %tint_f32_to_i32 %245
+        %247 = OpIAdd %int %244 %246
+        %248 = OpCompositeExtract %float %mat2x3_f32 0 0
+        %249 = OpFunctionCall %int %tint_f32_to_i32 %248
+        %250 = OpIAdd %int %247 %249
+        %251 = OpCompositeExtract %float %mat2x4_f32 0 0
+        %252 = OpFunctionCall %int %tint_f32_to_i32 %251
+        %253 = OpIAdd %int %250 %252
+        %254 = OpCompositeExtract %float %mat3x2_f32 0 0
+        %255 = OpFunctionCall %int %tint_f32_to_i32 %254
+        %256 = OpIAdd %int %253 %255
+        %257 = OpCompositeExtract %float %mat3x3_f32 0 0
+        %258 = OpFunctionCall %int %tint_f32_to_i32 %257
+        %259 = OpIAdd %int %256 %258
+        %260 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %261 = OpFunctionCall %int %tint_f32_to_i32 %260
+        %262 = OpIAdd %int %259 %261
+        %263 = OpCompositeExtract %float %mat4x2_f32 0 0
+        %264 = OpFunctionCall %int %tint_f32_to_i32 %263
+        %265 = OpIAdd %int %262 %264
+        %266 = OpCompositeExtract %float %mat4x3_f32 0 0
+        %267 = OpFunctionCall %int %tint_f32_to_i32 %266
+        %268 = OpIAdd %int %265 %267
+        %269 = OpCompositeExtract %float %mat4x4_f32 0 0
+        %270 = OpFunctionCall %int %tint_f32_to_i32 %269
+        %271 = OpIAdd %int %268 %270
+        %272 = OpCompositeExtract %float %arr2_vec3_f32 0 0
+        %273 = OpFunctionCall %int %tint_f32_to_i32 %272
+        %274 = OpIAdd %int %271 %273
+        %275 = OpAccessChain %_ptr_StorageBuffer_int_0 %29 %uint_0
+               OpStore %275 %274 None
                OpReturn
                OpFunctionEnd
-%tint_f32_to_i32 = OpFunction %int None %188
+%tint_f32_to_i32 = OpFunction %int None %278
       %value = OpFunctionParameter %float
-        %189 = OpLabel
-        %190 = OpConvertFToS %int %value
-        %191 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
-        %194 = OpSelect %int %191 %190 %int_n2147483648
-        %196 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
-        %198 = OpSelect %int %196 %194 %int_2147483647
-               OpReturnValue %198
+        %279 = OpLabel
+        %280 = OpConvertFToS %int %value
+        %281 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
+        %284 = OpSelect %int %281 %280 %int_n2147483648
+        %286 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
+        %288 = OpSelect %int %286 %284 %int_2147483647
+               OpReturnValue %288
                OpFunctionEnd
-       %main = OpFunction %void None %201
-        %202 = OpLabel
-        %203 = OpLoad %uint %main_local_invocation_index_Input None
-        %204 = OpFunctionCall %void %main_inner %203
+       %main = OpFunction %void None %291
+        %292 = OpLabel
+        %293 = OpLoad %uint %main_local_invocation_index_Input None
+        %294 = OpFunctionCall %void %main_inner %293
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
index 2e78482..62b156f 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
@@ -104,42 +104,45 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((800u * idx)));
-  int scalar_i32 = asint(sb.Load(((800u * idx) + 4u)));
-  uint scalar_u32 = sb.Load(((800u * idx) + 8u));
-  float16_t scalar_f16 = sb.Load<float16_t>(((800u * idx) + 12u));
-  float2 vec2_f32 = asfloat(sb.Load2(((800u * idx) + 16u)));
-  int2 vec2_i32 = asint(sb.Load2(((800u * idx) + 24u)));
-  uint2 vec2_u32 = sb.Load2(((800u * idx) + 32u));
-  vector<float16_t, 2> vec2_f16 = sb.Load<vector<float16_t, 2> >(((800u * idx) + 40u));
-  float3 vec3_f32 = asfloat(sb.Load3(((800u * idx) + 48u)));
-  int3 vec3_i32 = asint(sb.Load3(((800u * idx) + 64u)));
-  uint3 vec3_u32 = sb.Load3(((800u * idx) + 80u));
-  vector<float16_t, 3> vec3_f16 = sb.Load<vector<float16_t, 3> >(((800u * idx) + 96u));
-  float4 vec4_f32 = asfloat(sb.Load4(((800u * idx) + 112u)));
-  int4 vec4_i32 = asint(sb.Load4(((800u * idx) + 128u)));
-  uint4 vec4_u32 = sb.Load4(((800u * idx) + 144u));
-  vector<float16_t, 4> vec4_f16 = sb.Load<vector<float16_t, 4> >(((800u * idx) + 160u));
-  float2x2 mat2x2_f32 = sb_load_16(((800u * idx) + 168u));
-  float2x3 mat2x3_f32 = sb_load_17(((800u * idx) + 192u));
-  float2x4 mat2x4_f32 = sb_load_18(((800u * idx) + 224u));
-  float3x2 mat3x2_f32 = sb_load_19(((800u * idx) + 256u));
-  float3x3 mat3x3_f32 = sb_load_20(((800u * idx) + 288u));
-  float3x4 mat3x4_f32 = sb_load_21(((800u * idx) + 336u));
-  float4x2 mat4x2_f32 = sb_load_22(((800u * idx) + 384u));
-  float4x3 mat4x3_f32 = sb_load_23(((800u * idx) + 416u));
-  float4x4 mat4x4_f32 = sb_load_24(((800u * idx) + 480u));
-  matrix<float16_t, 2, 2> mat2x2_f16 = sb_load_25(((800u * idx) + 544u));
-  matrix<float16_t, 2, 3> mat2x3_f16 = sb_load_26(((800u * idx) + 552u));
-  matrix<float16_t, 2, 4> mat2x4_f16 = sb_load_27(((800u * idx) + 568u));
-  matrix<float16_t, 3, 2> mat3x2_f16 = sb_load_28(((800u * idx) + 584u));
-  matrix<float16_t, 3, 3> mat3x3_f16 = sb_load_29(((800u * idx) + 600u));
-  matrix<float16_t, 3, 4> mat3x4_f16 = sb_load_30(((800u * idx) + 624u));
-  matrix<float16_t, 4, 2> mat4x2_f16 = sb_load_31(((800u * idx) + 648u));
-  matrix<float16_t, 4, 3> mat4x3_f16 = sb_load_32(((800u * idx) + 664u));
-  matrix<float16_t, 4, 4> mat4x4_f16 = sb_load_33(((800u * idx) + 696u));
-  float3 arr2_vec3_f32[2] = sb_load_34(((800u * idx) + 736u));
-  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = sb_load_35(((800u * idx) + 768u));
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 800u);
+  float scalar_f32 = asfloat(sb.Load((800u * min(idx, (tint_symbol_4 - 1u)))));
+  int scalar_i32 = asint(sb.Load(((800u * min(idx, (tint_symbol_4 - 1u))) + 4u)));
+  uint scalar_u32 = sb.Load(((800u * min(idx, (tint_symbol_4 - 1u))) + 8u));
+  float16_t scalar_f16 = sb.Load<float16_t>(((800u * min(idx, (tint_symbol_4 - 1u))) + 12u));
+  float2 vec2_f32 = asfloat(sb.Load2(((800u * min(idx, (tint_symbol_4 - 1u))) + 16u)));
+  int2 vec2_i32 = asint(sb.Load2(((800u * min(idx, (tint_symbol_4 - 1u))) + 24u)));
+  uint2 vec2_u32 = sb.Load2(((800u * min(idx, (tint_symbol_4 - 1u))) + 32u));
+  vector<float16_t, 2> vec2_f16 = sb.Load<vector<float16_t, 2> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 40u));
+  float3 vec3_f32 = asfloat(sb.Load3(((800u * min(idx, (tint_symbol_4 - 1u))) + 48u)));
+  int3 vec3_i32 = asint(sb.Load3(((800u * min(idx, (tint_symbol_4 - 1u))) + 64u)));
+  uint3 vec3_u32 = sb.Load3(((800u * min(idx, (tint_symbol_4 - 1u))) + 80u));
+  vector<float16_t, 3> vec3_f16 = sb.Load<vector<float16_t, 3> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 96u));
+  float4 vec4_f32 = asfloat(sb.Load4(((800u * min(idx, (tint_symbol_4 - 1u))) + 112u)));
+  int4 vec4_i32 = asint(sb.Load4(((800u * min(idx, (tint_symbol_4 - 1u))) + 128u)));
+  uint4 vec4_u32 = sb.Load4(((800u * min(idx, (tint_symbol_4 - 1u))) + 144u));
+  vector<float16_t, 4> vec4_f16 = sb.Load<vector<float16_t, 4> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 160u));
+  float2x2 mat2x2_f32 = sb_load_16(((800u * min(idx, (tint_symbol_4 - 1u))) + 168u));
+  float2x3 mat2x3_f32 = sb_load_17(((800u * min(idx, (tint_symbol_4 - 1u))) + 192u));
+  float2x4 mat2x4_f32 = sb_load_18(((800u * min(idx, (tint_symbol_4 - 1u))) + 224u));
+  float3x2 mat3x2_f32 = sb_load_19(((800u * min(idx, (tint_symbol_4 - 1u))) + 256u));
+  float3x3 mat3x3_f32 = sb_load_20(((800u * min(idx, (tint_symbol_4 - 1u))) + 288u));
+  float3x4 mat3x4_f32 = sb_load_21(((800u * min(idx, (tint_symbol_4 - 1u))) + 336u));
+  float4x2 mat4x2_f32 = sb_load_22(((800u * min(idx, (tint_symbol_4 - 1u))) + 384u));
+  float4x3 mat4x3_f32 = sb_load_23(((800u * min(idx, (tint_symbol_4 - 1u))) + 416u));
+  float4x4 mat4x4_f32 = sb_load_24(((800u * min(idx, (tint_symbol_4 - 1u))) + 480u));
+  matrix<float16_t, 2, 2> mat2x2_f16 = sb_load_25(((800u * min(idx, (tint_symbol_4 - 1u))) + 544u));
+  matrix<float16_t, 2, 3> mat2x3_f16 = sb_load_26(((800u * min(idx, (tint_symbol_4 - 1u))) + 552u));
+  matrix<float16_t, 2, 4> mat2x4_f16 = sb_load_27(((800u * min(idx, (tint_symbol_4 - 1u))) + 568u));
+  matrix<float16_t, 3, 2> mat3x2_f16 = sb_load_28(((800u * min(idx, (tint_symbol_4 - 1u))) + 584u));
+  matrix<float16_t, 3, 3> mat3x3_f16 = sb_load_29(((800u * min(idx, (tint_symbol_4 - 1u))) + 600u));
+  matrix<float16_t, 3, 4> mat3x4_f16 = sb_load_30(((800u * min(idx, (tint_symbol_4 - 1u))) + 624u));
+  matrix<float16_t, 4, 2> mat4x2_f16 = sb_load_31(((800u * min(idx, (tint_symbol_4 - 1u))) + 648u));
+  matrix<float16_t, 4, 3> mat4x3_f16 = sb_load_32(((800u * min(idx, (tint_symbol_4 - 1u))) + 664u));
+  matrix<float16_t, 4, 4> mat4x4_f16 = sb_load_33(((800u * min(idx, (tint_symbol_4 - 1u))) + 696u));
+  float3 arr2_vec3_f32[2] = sb_load_34(((800u * min(idx, (tint_symbol_4 - 1u))) + 736u));
+  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = sb_load_35(((800u * min(idx, (tint_symbol_4 - 1u))) + 768u));
   s.Store(0u, asuint((((((((((((((((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + int(scalar_f16)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + int(vec2_f16.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + int(vec3_f16.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + int(vec4_f16.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + int(mat2x2_f16[0].x)) + int(mat2x3_f16[0].x)) + int(mat2x4_f16[0].x)) + int(mat3x2_f16[0].x)) + int(mat3x3_f16[0].x)) + int(mat3x4_f16[0].x)) + int(mat4x2_f16[0].x)) + int(mat4x3_f16[0].x)) + int(mat4x4_f16[0].x)) + int(arr2_mat4x2_f16[0][0].x)) + tint_ftoi(arr2_vec3_f32[0].x))));
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.glsl
index 4e6e3f6..1628656 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.glsl
@@ -69,74 +69,110 @@
   return mix(2147483647, mix((-2147483647 - 1), int(value), (value >= -65504.0hf)), (value <= 65504.0hf));
 }
 void tint_symbol_inner(uint idx) {
-  float scalar_f32 = sb.arr[idx].scalar_f32;
-  int scalar_i32 = sb.arr[idx].scalar_i32;
-  uint scalar_u32 = sb.arr[idx].scalar_u32;
-  float16_t scalar_f16 = sb.arr[idx].scalar_f16;
-  vec2 vec2_f32 = sb.arr[idx].vec2_f32;
-  ivec2 vec2_i32 = sb.arr[idx].vec2_i32;
-  uvec2 vec2_u32 = sb.arr[idx].vec2_u32;
-  f16vec2 vec2_f16 = sb.arr[idx].vec2_f16;
-  vec3 vec3_f32 = sb.arr[idx].vec3_f32;
-  ivec3 vec3_i32 = sb.arr[idx].vec3_i32;
-  uvec3 vec3_u32 = sb.arr[idx].vec3_u32;
-  f16vec3 vec3_f16 = sb.arr[idx].vec3_f16;
-  vec4 vec4_f32 = sb.arr[idx].vec4_f32;
-  ivec4 vec4_i32 = sb.arr[idx].vec4_i32;
-  uvec4 vec4_u32 = sb.arr[idx].vec4_u32;
-  f16vec4 vec4_f16 = sb.arr[idx].vec4_f16;
-  mat2 mat2x2_f32 = sb.arr[idx].mat2x2_f32;
-  mat2x3 mat2x3_f32 = sb.arr[idx].mat2x3_f32;
-  mat2x4 mat2x4_f32 = sb.arr[idx].mat2x4_f32;
-  mat3x2 mat3x2_f32 = sb.arr[idx].mat3x2_f32;
-  mat3 mat3x3_f32 = sb.arr[idx].mat3x3_f32;
-  mat3x4 mat3x4_f32 = sb.arr[idx].mat3x4_f32;
-  mat4x2 mat4x2_f32 = sb.arr[idx].mat4x2_f32;
-  mat4x3 mat4x3_f32 = sb.arr[idx].mat4x3_f32;
-  mat4 mat4x4_f32 = sb.arr[idx].mat4x4_f32;
-  f16mat2 mat2x2_f16 = sb.arr[idx].mat2x2_f16;
-  f16mat2x3 mat2x3_f16 = sb.arr[idx].mat2x3_f16;
-  f16mat2x4 mat2x4_f16 = sb.arr[idx].mat2x4_f16;
-  f16mat3x2 mat3x2_f16 = sb.arr[idx].mat3x2_f16;
-  f16mat3 mat3x3_f16 = sb.arr[idx].mat3x3_f16;
-  f16mat3x4 mat3x4_f16 = sb.arr[idx].mat3x4_f16;
-  f16mat4x2 mat4x2_f16 = sb.arr[idx].mat4x2_f16;
-  f16mat4x3 mat4x3_f16 = sb.arr[idx].mat4x3_f16;
-  f16mat4 mat4x4_f16 = sb.arr[idx].mat4x4_f16;
-  vec3 arr2_vec3_f32[2] = sb.arr[idx].arr2_vec3_f32;
-  f16mat4x2 arr2_mat4x2_f16[2] = sb.arr[idx].arr2_mat4x2_f16;
-  int v_1 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
-  int v_2 = (v_1 + int(scalar_u32));
-  int v_3 = (v_2 + tint_f16_to_i32(scalar_f16));
-  int v_4 = ((v_3 + tint_f32_to_i32(vec2_f32[0u])) + vec2_i32[0u]);
-  int v_5 = (v_4 + int(vec2_u32[0u]));
-  int v_6 = (v_5 + tint_f16_to_i32(vec2_f16[0u]));
-  int v_7 = ((v_6 + tint_f32_to_i32(vec3_f32[1u])) + vec3_i32[1u]);
-  int v_8 = (v_7 + int(vec3_u32[1u]));
-  int v_9 = (v_8 + tint_f16_to_i32(vec3_f16[1u]));
-  int v_10 = ((v_9 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
-  int v_11 = (v_10 + int(vec4_u32[2u]));
-  int v_12 = (v_11 + tint_f16_to_i32(vec4_f16[2u]));
-  int v_13 = (v_12 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_19 = (v_18 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_20 = (v_19 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_21 = (v_20 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  int v_22 = (v_21 + tint_f16_to_i32(mat2x2_f16[0][0u]));
-  int v_23 = (v_22 + tint_f16_to_i32(mat2x3_f16[0][0u]));
-  int v_24 = (v_23 + tint_f16_to_i32(mat2x4_f16[0][0u]));
-  int v_25 = (v_24 + tint_f16_to_i32(mat3x2_f16[0][0u]));
-  int v_26 = (v_25 + tint_f16_to_i32(mat3x3_f16[0][0u]));
-  int v_27 = (v_26 + tint_f16_to_i32(mat3x4_f16[0][0u]));
-  int v_28 = (v_27 + tint_f16_to_i32(mat4x2_f16[0][0u]));
-  int v_29 = (v_28 + tint_f16_to_i32(mat4x3_f16[0][0u]));
-  int v_30 = (v_29 + tint_f16_to_i32(mat4x4_f16[0][0u]));
-  int v_31 = (v_30 + tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]));
-  v.inner = (v_31 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
+  uint v_1 = min(idx, (uint(sb.arr.length()) - 1u));
+  float scalar_f32 = sb.arr[v_1].scalar_f32;
+  uint v_2 = min(idx, (uint(sb.arr.length()) - 1u));
+  int scalar_i32 = sb.arr[v_2].scalar_i32;
+  uint v_3 = min(idx, (uint(sb.arr.length()) - 1u));
+  uint scalar_u32 = sb.arr[v_3].scalar_u32;
+  uint v_4 = min(idx, (uint(sb.arr.length()) - 1u));
+  float16_t scalar_f16 = sb.arr[v_4].scalar_f16;
+  uint v_5 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec2 vec2_f32 = sb.arr[v_5].vec2_f32;
+  uint v_6 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec2 vec2_i32 = sb.arr[v_6].vec2_i32;
+  uint v_7 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec2 vec2_u32 = sb.arr[v_7].vec2_u32;
+  uint v_8 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16vec2 vec2_f16 = sb.arr[v_8].vec2_f16;
+  uint v_9 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec3 vec3_f32 = sb.arr[v_9].vec3_f32;
+  uint v_10 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec3 vec3_i32 = sb.arr[v_10].vec3_i32;
+  uint v_11 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec3 vec3_u32 = sb.arr[v_11].vec3_u32;
+  uint v_12 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16vec3 vec3_f16 = sb.arr[v_12].vec3_f16;
+  uint v_13 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec4 vec4_f32 = sb.arr[v_13].vec4_f32;
+  uint v_14 = min(idx, (uint(sb.arr.length()) - 1u));
+  ivec4 vec4_i32 = sb.arr[v_14].vec4_i32;
+  uint v_15 = min(idx, (uint(sb.arr.length()) - 1u));
+  uvec4 vec4_u32 = sb.arr[v_15].vec4_u32;
+  uint v_16 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16vec4 vec4_f16 = sb.arr[v_16].vec4_f16;
+  uint v_17 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2 mat2x2_f32 = sb.arr[v_17].mat2x2_f32;
+  uint v_18 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2x3 mat2x3_f32 = sb.arr[v_18].mat2x3_f32;
+  uint v_19 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat2x4 mat2x4_f32 = sb.arr[v_19].mat2x4_f32;
+  uint v_20 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3x2 mat3x2_f32 = sb.arr[v_20].mat3x2_f32;
+  uint v_21 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3 mat3x3_f32 = sb.arr[v_21].mat3x3_f32;
+  uint v_22 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat3x4 mat3x4_f32 = sb.arr[v_22].mat3x4_f32;
+  uint v_23 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4x2 mat4x2_f32 = sb.arr[v_23].mat4x2_f32;
+  uint v_24 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4x3 mat4x3_f32 = sb.arr[v_24].mat4x3_f32;
+  uint v_25 = min(idx, (uint(sb.arr.length()) - 1u));
+  mat4 mat4x4_f32 = sb.arr[v_25].mat4x4_f32;
+  uint v_26 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat2 mat2x2_f16 = sb.arr[v_26].mat2x2_f16;
+  uint v_27 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat2x3 mat2x3_f16 = sb.arr[v_27].mat2x3_f16;
+  uint v_28 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat2x4 mat2x4_f16 = sb.arr[v_28].mat2x4_f16;
+  uint v_29 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat3x2 mat3x2_f16 = sb.arr[v_29].mat3x2_f16;
+  uint v_30 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat3 mat3x3_f16 = sb.arr[v_30].mat3x3_f16;
+  uint v_31 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat3x4 mat3x4_f16 = sb.arr[v_31].mat3x4_f16;
+  uint v_32 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat4x2 mat4x2_f16 = sb.arr[v_32].mat4x2_f16;
+  uint v_33 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat4x3 mat4x3_f16 = sb.arr[v_33].mat4x3_f16;
+  uint v_34 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat4 mat4x4_f16 = sb.arr[v_34].mat4x4_f16;
+  uint v_35 = min(idx, (uint(sb.arr.length()) - 1u));
+  vec3 arr2_vec3_f32[2] = sb.arr[v_35].arr2_vec3_f32;
+  uint v_36 = min(idx, (uint(sb.arr.length()) - 1u));
+  f16mat4x2 arr2_mat4x2_f16[2] = sb.arr[v_36].arr2_mat4x2_f16;
+  int v_37 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
+  int v_38 = (v_37 + int(scalar_u32));
+  int v_39 = (v_38 + tint_f16_to_i32(scalar_f16));
+  int v_40 = ((v_39 + tint_f32_to_i32(vec2_f32[0u])) + vec2_i32[0u]);
+  int v_41 = (v_40 + int(vec2_u32[0u]));
+  int v_42 = (v_41 + tint_f16_to_i32(vec2_f16[0u]));
+  int v_43 = ((v_42 + tint_f32_to_i32(vec3_f32[1u])) + vec3_i32[1u]);
+  int v_44 = (v_43 + int(vec3_u32[1u]));
+  int v_45 = (v_44 + tint_f16_to_i32(vec3_f16[1u]));
+  int v_46 = ((v_45 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
+  int v_47 = (v_46 + int(vec4_u32[2u]));
+  int v_48 = (v_47 + tint_f16_to_i32(vec4_f16[2u]));
+  int v_49 = (v_48 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_50 = (v_49 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_51 = (v_50 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_52 = (v_51 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_53 = (v_52 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_54 = (v_53 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_55 = (v_54 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_56 = (v_55 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_57 = (v_56 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  int v_58 = (v_57 + tint_f16_to_i32(mat2x2_f16[0u][0u]));
+  int v_59 = (v_58 + tint_f16_to_i32(mat2x3_f16[0u][0u]));
+  int v_60 = (v_59 + tint_f16_to_i32(mat2x4_f16[0u][0u]));
+  int v_61 = (v_60 + tint_f16_to_i32(mat3x2_f16[0u][0u]));
+  int v_62 = (v_61 + tint_f16_to_i32(mat3x3_f16[0u][0u]));
+  int v_63 = (v_62 + tint_f16_to_i32(mat3x4_f16[0u][0u]));
+  int v_64 = (v_63 + tint_f16_to_i32(mat4x2_f16[0u][0u]));
+  int v_65 = (v_64 + tint_f16_to_i32(mat4x3_f16[0u][0u]));
+  int v_66 = (v_65 + tint_f16_to_i32(mat4x4_f16[0u][0u]));
+  int v_67 = (v_66 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]));
+  v.inner = (v_67 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
index fe5f9bd..5520caa 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
@@ -130,74 +130,146 @@
 }
 
 void main_inner(uint idx) {
-  float scalar_f32 = asfloat(sb.Load((0u + (idx * 800u))));
-  int scalar_i32 = asint(sb.Load((4u + (idx * 800u))));
-  uint scalar_u32 = sb.Load((8u + (idx * 800u)));
-  float16_t scalar_f16 = sb.Load<float16_t>((12u + (idx * 800u)));
-  float2 vec2_f32 = asfloat(sb.Load2((16u + (idx * 800u))));
-  int2 vec2_i32 = asint(sb.Load2((24u + (idx * 800u))));
-  uint2 vec2_u32 = sb.Load2((32u + (idx * 800u)));
-  vector<float16_t, 2> vec2_f16 = sb.Load<vector<float16_t, 2> >((40u + (idx * 800u)));
-  float3 vec3_f32 = asfloat(sb.Load3((48u + (idx * 800u))));
-  int3 vec3_i32 = asint(sb.Load3((64u + (idx * 800u))));
-  uint3 vec3_u32 = sb.Load3((80u + (idx * 800u)));
-  vector<float16_t, 3> vec3_f16 = sb.Load<vector<float16_t, 3> >((96u + (idx * 800u)));
-  float4 vec4_f32 = asfloat(sb.Load4((112u + (idx * 800u))));
-  int4 vec4_i32 = asint(sb.Load4((128u + (idx * 800u))));
-  uint4 vec4_u32 = sb.Load4((144u + (idx * 800u)));
-  vector<float16_t, 4> vec4_f16 = sb.Load<vector<float16_t, 4> >((160u + (idx * 800u)));
-  float2x2 mat2x2_f32 = v_25((168u + (idx * 800u)));
-  float2x3 mat2x3_f32 = v_24((192u + (idx * 800u)));
-  float2x4 mat2x4_f32 = v_23((224u + (idx * 800u)));
-  float3x2 mat3x2_f32 = v_22((256u + (idx * 800u)));
-  float3x3 mat3x3_f32 = v_21((288u + (idx * 800u)));
-  float3x4 mat3x4_f32 = v_20((336u + (idx * 800u)));
-  float4x2 mat4x2_f32 = v_19((384u + (idx * 800u)));
-  float4x3 mat4x3_f32 = v_18((416u + (idx * 800u)));
-  float4x4 mat4x4_f32 = v_17((480u + (idx * 800u)));
-  matrix<float16_t, 2, 2> mat2x2_f16 = v_16((544u + (idx * 800u)));
-  matrix<float16_t, 2, 3> mat2x3_f16 = v_15((552u + (idx * 800u)));
-  matrix<float16_t, 2, 4> mat2x4_f16 = v_14((568u + (idx * 800u)));
-  matrix<float16_t, 3, 2> mat3x2_f16 = v_13((584u + (idx * 800u)));
-  matrix<float16_t, 3, 3> mat3x3_f16 = v_12((600u + (idx * 800u)));
-  matrix<float16_t, 3, 4> mat3x4_f16 = v_11((624u + (idx * 800u)));
-  matrix<float16_t, 4, 2> mat4x2_f16 = v((648u + (idx * 800u)));
-  matrix<float16_t, 4, 3> mat4x3_f16 = v_10((664u + (idx * 800u)));
-  matrix<float16_t, 4, 4> mat4x4_f16 = v_9((696u + (idx * 800u)));
-  float3 arr2_vec3_f32[2] = v_5((736u + (idx * 800u)));
-  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = v_1((768u + (idx * 800u)));
-  int v_26 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
-  int v_27 = (v_26 + int(scalar_u32));
-  int v_28 = (v_27 + tint_f16_to_i32(scalar_f16));
-  int v_29 = ((v_28 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
-  int v_30 = (v_29 + int(vec2_u32.x));
-  int v_31 = (v_30 + tint_f16_to_i32(vec2_f16.x));
-  int v_32 = ((v_31 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
-  int v_33 = (v_32 + int(vec3_u32.y));
-  int v_34 = (v_33 + tint_f16_to_i32(vec3_f16.y));
-  int v_35 = ((v_34 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
-  int v_36 = (v_35 + int(vec4_u32.z));
-  int v_37 = (v_36 + tint_f16_to_i32(vec4_f16.z));
-  int v_38 = (v_37 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_39 = (v_38 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_40 = (v_39 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_41 = (v_40 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_42 = (v_41 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_43 = (v_42 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_44 = (v_43 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_45 = (v_44 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_46 = (v_45 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  int v_47 = (v_46 + tint_f16_to_i32(mat2x2_f16[int(0)].x));
-  int v_48 = (v_47 + tint_f16_to_i32(mat2x3_f16[int(0)].x));
-  int v_49 = (v_48 + tint_f16_to_i32(mat2x4_f16[int(0)].x));
-  int v_50 = (v_49 + tint_f16_to_i32(mat3x2_f16[int(0)].x));
-  int v_51 = (v_50 + tint_f16_to_i32(mat3x3_f16[int(0)].x));
-  int v_52 = (v_51 + tint_f16_to_i32(mat3x4_f16[int(0)].x));
-  int v_53 = (v_52 + tint_f16_to_i32(mat4x2_f16[int(0)].x));
-  int v_54 = (v_53 + tint_f16_to_i32(mat4x3_f16[int(0)].x));
-  int v_55 = (v_54 + tint_f16_to_i32(mat4x4_f16[int(0)].x));
-  int v_56 = (v_55 + tint_f16_to_i32(arr2_mat4x2_f16[int(0)][int(0)].x));
-  s.Store(0u, asuint((v_56 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x))));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  float scalar_f32 = asfloat(sb.Load((0u + (min(idx, ((v_26 / 800u) - 1u)) * 800u))));
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  int scalar_i32 = asint(sb.Load((4u + (min(idx, ((v_27 / 800u) - 1u)) * 800u))));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  uint scalar_u32 = sb.Load((8u + (min(idx, ((v_28 / 800u) - 1u)) * 800u)));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  float16_t scalar_f16 = sb.Load<float16_t>((12u + (min(idx, ((v_29 / 800u) - 1u)) * 800u)));
+  uint v_30 = 0u;
+  sb.GetDimensions(v_30);
+  float2 vec2_f32 = asfloat(sb.Load2((16u + (min(idx, ((v_30 / 800u) - 1u)) * 800u))));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  int2 vec2_i32 = asint(sb.Load2((24u + (min(idx, ((v_31 / 800u) - 1u)) * 800u))));
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  uint2 vec2_u32 = sb.Load2((32u + (min(idx, ((v_32 / 800u) - 1u)) * 800u)));
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  vector<float16_t, 2> vec2_f16 = sb.Load<vector<float16_t, 2> >((40u + (min(idx, ((v_33 / 800u) - 1u)) * 800u)));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  float3 vec3_f32 = asfloat(sb.Load3((48u + (min(idx, ((v_34 / 800u) - 1u)) * 800u))));
+  uint v_35 = 0u;
+  sb.GetDimensions(v_35);
+  int3 vec3_i32 = asint(sb.Load3((64u + (min(idx, ((v_35 / 800u) - 1u)) * 800u))));
+  uint v_36 = 0u;
+  sb.GetDimensions(v_36);
+  uint3 vec3_u32 = sb.Load3((80u + (min(idx, ((v_36 / 800u) - 1u)) * 800u)));
+  uint v_37 = 0u;
+  sb.GetDimensions(v_37);
+  vector<float16_t, 3> vec3_f16 = sb.Load<vector<float16_t, 3> >((96u + (min(idx, ((v_37 / 800u) - 1u)) * 800u)));
+  uint v_38 = 0u;
+  sb.GetDimensions(v_38);
+  float4 vec4_f32 = asfloat(sb.Load4((112u + (min(idx, ((v_38 / 800u) - 1u)) * 800u))));
+  uint v_39 = 0u;
+  sb.GetDimensions(v_39);
+  int4 vec4_i32 = asint(sb.Load4((128u + (min(idx, ((v_39 / 800u) - 1u)) * 800u))));
+  uint v_40 = 0u;
+  sb.GetDimensions(v_40);
+  uint4 vec4_u32 = sb.Load4((144u + (min(idx, ((v_40 / 800u) - 1u)) * 800u)));
+  uint v_41 = 0u;
+  sb.GetDimensions(v_41);
+  vector<float16_t, 4> vec4_f16 = sb.Load<vector<float16_t, 4> >((160u + (min(idx, ((v_41 / 800u) - 1u)) * 800u)));
+  uint v_42 = 0u;
+  sb.GetDimensions(v_42);
+  float2x2 mat2x2_f32 = v_25((168u + (min(idx, ((v_42 / 800u) - 1u)) * 800u)));
+  uint v_43 = 0u;
+  sb.GetDimensions(v_43);
+  float2x3 mat2x3_f32 = v_24((192u + (min(idx, ((v_43 / 800u) - 1u)) * 800u)));
+  uint v_44 = 0u;
+  sb.GetDimensions(v_44);
+  float2x4 mat2x4_f32 = v_23((224u + (min(idx, ((v_44 / 800u) - 1u)) * 800u)));
+  uint v_45 = 0u;
+  sb.GetDimensions(v_45);
+  float3x2 mat3x2_f32 = v_22((256u + (min(idx, ((v_45 / 800u) - 1u)) * 800u)));
+  uint v_46 = 0u;
+  sb.GetDimensions(v_46);
+  float3x3 mat3x3_f32 = v_21((288u + (min(idx, ((v_46 / 800u) - 1u)) * 800u)));
+  uint v_47 = 0u;
+  sb.GetDimensions(v_47);
+  float3x4 mat3x4_f32 = v_20((336u + (min(idx, ((v_47 / 800u) - 1u)) * 800u)));
+  uint v_48 = 0u;
+  sb.GetDimensions(v_48);
+  float4x2 mat4x2_f32 = v_19((384u + (min(idx, ((v_48 / 800u) - 1u)) * 800u)));
+  uint v_49 = 0u;
+  sb.GetDimensions(v_49);
+  float4x3 mat4x3_f32 = v_18((416u + (min(idx, ((v_49 / 800u) - 1u)) * 800u)));
+  uint v_50 = 0u;
+  sb.GetDimensions(v_50);
+  float4x4 mat4x4_f32 = v_17((480u + (min(idx, ((v_50 / 800u) - 1u)) * 800u)));
+  uint v_51 = 0u;
+  sb.GetDimensions(v_51);
+  matrix<float16_t, 2, 2> mat2x2_f16 = v_16((544u + (min(idx, ((v_51 / 800u) - 1u)) * 800u)));
+  uint v_52 = 0u;
+  sb.GetDimensions(v_52);
+  matrix<float16_t, 2, 3> mat2x3_f16 = v_15((552u + (min(idx, ((v_52 / 800u) - 1u)) * 800u)));
+  uint v_53 = 0u;
+  sb.GetDimensions(v_53);
+  matrix<float16_t, 2, 4> mat2x4_f16 = v_14((568u + (min(idx, ((v_53 / 800u) - 1u)) * 800u)));
+  uint v_54 = 0u;
+  sb.GetDimensions(v_54);
+  matrix<float16_t, 3, 2> mat3x2_f16 = v_13((584u + (min(idx, ((v_54 / 800u) - 1u)) * 800u)));
+  uint v_55 = 0u;
+  sb.GetDimensions(v_55);
+  matrix<float16_t, 3, 3> mat3x3_f16 = v_12((600u + (min(idx, ((v_55 / 800u) - 1u)) * 800u)));
+  uint v_56 = 0u;
+  sb.GetDimensions(v_56);
+  matrix<float16_t, 3, 4> mat3x4_f16 = v_11((624u + (min(idx, ((v_56 / 800u) - 1u)) * 800u)));
+  uint v_57 = 0u;
+  sb.GetDimensions(v_57);
+  matrix<float16_t, 4, 2> mat4x2_f16 = v((648u + (min(idx, ((v_57 / 800u) - 1u)) * 800u)));
+  uint v_58 = 0u;
+  sb.GetDimensions(v_58);
+  matrix<float16_t, 4, 3> mat4x3_f16 = v_10((664u + (min(idx, ((v_58 / 800u) - 1u)) * 800u)));
+  uint v_59 = 0u;
+  sb.GetDimensions(v_59);
+  matrix<float16_t, 4, 4> mat4x4_f16 = v_9((696u + (min(idx, ((v_59 / 800u) - 1u)) * 800u)));
+  uint v_60 = 0u;
+  sb.GetDimensions(v_60);
+  float3 arr2_vec3_f32[2] = v_5((736u + (min(idx, ((v_60 / 800u) - 1u)) * 800u)));
+  uint v_61 = 0u;
+  sb.GetDimensions(v_61);
+  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = v_1((768u + (min(idx, ((v_61 / 800u) - 1u)) * 800u)));
+  int v_62 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
+  int v_63 = (v_62 + int(scalar_u32));
+  int v_64 = (v_63 + tint_f16_to_i32(scalar_f16));
+  int v_65 = ((v_64 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
+  int v_66 = (v_65 + int(vec2_u32.x));
+  int v_67 = (v_66 + tint_f16_to_i32(vec2_f16.x));
+  int v_68 = ((v_67 + tint_f32_to_i32(vec3_f32.y)) + vec3_i32.y);
+  int v_69 = (v_68 + int(vec3_u32.y));
+  int v_70 = (v_69 + tint_f16_to_i32(vec3_f16.y));
+  int v_71 = ((v_70 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
+  int v_72 = (v_71 + int(vec4_u32.z));
+  int v_73 = (v_72 + tint_f16_to_i32(vec4_f16.z));
+  int v_74 = (v_73 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_75 = (v_74 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_76 = (v_75 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_77 = (v_76 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_78 = (v_77 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_79 = (v_78 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_80 = (v_79 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_81 = (v_80 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_82 = (v_81 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  int v_83 = (v_82 + tint_f16_to_i32(mat2x2_f16[0u].x));
+  int v_84 = (v_83 + tint_f16_to_i32(mat2x3_f16[0u].x));
+  int v_85 = (v_84 + tint_f16_to_i32(mat2x4_f16[0u].x));
+  int v_86 = (v_85 + tint_f16_to_i32(mat3x2_f16[0u].x));
+  int v_87 = (v_86 + tint_f16_to_i32(mat3x3_f16[0u].x));
+  int v_88 = (v_87 + tint_f16_to_i32(mat3x4_f16[0u].x));
+  int v_89 = (v_88 + tint_f16_to_i32(mat4x2_f16[0u].x));
+  int v_90 = (v_89 + tint_f16_to_i32(mat4x3_f16[0u].x));
+  int v_91 = (v_90 + tint_f16_to_i32(mat4x4_f16[0u].x));
+  int v_92 = (v_91 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u].x));
+  s.Store(0u, asuint((v_92 + tint_f32_to_i32(arr2_vec3_f32[0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.msl b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.msl
index 97e35d4..afc9105 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.ir.msl
@@ -79,6 +79,7 @@
 struct tint_module_vars_struct {
   const device S_packed_vec3* sb;
   device int* s;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 int tint_f32_to_i32(float value) {
@@ -95,60 +96,60 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  float const scalar_f32 = (*tint_module_vars.sb).arr[idx].scalar_f32;
-  int const scalar_i32 = (*tint_module_vars.sb).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*tint_module_vars.sb).arr[idx].scalar_u32;
-  half const scalar_f16 = (*tint_module_vars.sb).arr[idx].scalar_f16;
-  float2 const vec2_f32 = (*tint_module_vars.sb).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*tint_module_vars.sb).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*tint_module_vars.sb).arr[idx].vec2_u32;
-  half2 const vec2_f16 = (*tint_module_vars.sb).arr[idx].vec2_f16;
-  float3 const vec3_f32 = float3((*tint_module_vars.sb).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*tint_module_vars.sb).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*tint_module_vars.sb).arr[idx].vec3_u32);
-  half3 const vec3_f16 = half3((*tint_module_vars.sb).arr[idx].vec3_f16);
-  float4 const vec4_f32 = (*tint_module_vars.sb).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*tint_module_vars.sb).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*tint_module_vars.sb).arr[idx].vec4_u32;
-  half4 const vec4_f16 = (*tint_module_vars.sb).arr[idx].vec4_f16;
-  float2x2 const mat2x2_f32 = (*tint_module_vars.sb).arr[idx].mat2x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.sb).arr[idx].mat2x3_f32;
+  float const scalar_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_f32;
+  int const scalar_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_i32;
+  uint const scalar_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_u32;
+  half const scalar_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_f16;
+  float2 const vec2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_f32;
+  int2 const vec2_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_i32;
+  uint2 const vec2_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_u32;
+  half2 const vec2_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_f16;
+  float3 const vec3_f32 = float3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_f32);
+  int3 const vec3_i32 = int3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_i32);
+  uint3 const vec3_u32 = uint3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_u32);
+  half3 const vec3_f16 = half3((*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_f16);
+  float4 const vec4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_f32;
+  int4 const vec4_i32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_i32;
+  uint4 const vec4_u32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_u32;
+  half4 const vec4_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_f16;
+  float2x2 const mat2x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f32;
   float3 const v_2 = float3(v_1[0u].packed);
   float2x3 const mat2x3_f32 = float2x3(v_2, float3(v_1[1u].packed));
-  float2x4 const mat2x4_f32 = (*tint_module_vars.sb).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*tint_module_vars.sb).arr[idx].mat3x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.sb).arr[idx].mat3x3_f32;
+  float2x4 const mat2x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f32;
   float3 const v_4 = float3(v_3[0u].packed);
   float3 const v_5 = float3(v_3[1u].packed);
   float3x3 const mat3x3_f32 = float3x3(v_4, v_5, float3(v_3[2u].packed));
-  float3x4 const mat3x4_f32 = (*tint_module_vars.sb).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*tint_module_vars.sb).arr[idx].mat4x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.sb).arr[idx].mat4x3_f32;
+  float3x4 const mat3x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f32;
   float3 const v_7 = float3(v_6[0u].packed);
   float3 const v_8 = float3(v_6[1u].packed);
   float3 const v_9 = float3(v_6[2u].packed);
   float4x3 const mat4x3_f32 = float4x3(v_7, v_8, v_9, float3(v_6[3u].packed));
-  float4x4 const mat4x4_f32 = (*tint_module_vars.sb).arr[idx].mat4x4_f32;
-  half2x2 const mat2x2_f16 = (*tint_module_vars.sb).arr[idx].mat2x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_10 = (*tint_module_vars.sb).arr[idx].mat2x3_f16;
+  float4x4 const mat4x4_f32 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f32;
+  half2x2 const mat2x2_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_10 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f16;
   half3 const v_11 = half3(v_10[0u].packed_1);
   half2x3 const mat2x3_f16 = half2x3(v_11, half3(v_10[1u].packed_1));
-  half2x4 const mat2x4_f16 = (*tint_module_vars.sb).arr[idx].mat2x4_f16;
-  half3x2 const mat3x2_f16 = (*tint_module_vars.sb).arr[idx].mat3x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_12 = (*tint_module_vars.sb).arr[idx].mat3x3_f16;
+  half2x4 const mat2x4_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f16;
+  half3x2 const mat3x2_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_12 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f16;
   half3 const v_13 = half3(v_12[0u].packed_1);
   half3 const v_14 = half3(v_12[1u].packed_1);
   half3x3 const mat3x3_f16 = half3x3(v_13, v_14, half3(v_12[2u].packed_1));
-  half3x4 const mat3x4_f16 = (*tint_module_vars.sb).arr[idx].mat3x4_f16;
-  half4x2 const mat4x2_f16 = (*tint_module_vars.sb).arr[idx].mat4x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_15 = (*tint_module_vars.sb).arr[idx].mat4x3_f16;
+  half3x4 const mat3x4_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f16;
+  half4x2 const mat4x2_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_15 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f16;
   half3 const v_16 = half3(v_15[0u].packed_1);
   half3 const v_17 = half3(v_15[1u].packed_1);
   half3 const v_18 = half3(v_15[2u].packed_1);
   half4x3 const mat4x3_f16 = half4x3(v_16, v_17, v_18, half3(v_15[3u].packed_1));
-  half4x4 const mat4x4_f16 = (*tint_module_vars.sb).arr[idx].mat4x4_f16;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.sb).arr[idx].arr2_vec3_f32));
-  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*tint_module_vars.sb).arr[idx].arr2_mat4x2_f16;
+  half4x4 const mat4x4_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f16;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].arr2_vec3_f32));
+  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].arr2_mat4x2_f16;
   int const v_19 = as_type<int>((as_type<uint>(tint_f32_to_i32(scalar_f32)) + as_type<uint>(scalar_i32)));
   int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(int(scalar_u32))));
   int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f16_to_i32(scalar_f16))));
@@ -161,29 +162,29 @@
   int const v_28 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_27) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_29 = as_type<int>((as_type<uint>(v_28) + as_type<uint>(int(vec4_u32[2u]))));
   int const v_30 = as_type<int>((as_type<uint>(v_29) + as_type<uint>(tint_f16_to_i32(vec4_f16[2u]))));
-  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0][0u]))));
-  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0][0u]))));
-  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0][0u]))));
-  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0][0u]))));
-  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0][0u]))));
-  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0][0u]))));
-  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0][0u]))));
-  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0][0u]))));
-  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0][0u]))));
-  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
+  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0u][0u]))));
+  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0u][0u]))));
+  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0u][0u]))));
+  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0u][0u]))));
+  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0u][0u]))));
+  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0u][0u]))));
+  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0u][0u]))));
+  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0u][0u]))));
+  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0u][0u]))));
+  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
 }
 
-kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const device S_packed_vec3* sb [[buffer(1)]], device int* s [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .s=s};
+kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const device S_packed_vec3* sb [[buffer(1)]], device int* s [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .s=s, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(idx, tint_module_vars);
 }
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.msl
index ebfeca5..b9df814 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.msl
@@ -112,6 +112,10 @@
   return result;
 }
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 int tint_ftoi(float v) {
   return select(2147483647, select(int(v), (-2147483647 - 1), (v < -2147483648.0f)), (v <= 2147483520.0f));
 }
@@ -159,48 +163,48 @@
   tint_array<Inner, 1> arr;
 };
 
-void tint_symbol_inner(uint idx, const device S_tint_packed_vec3* const tint_symbol_1, device int* const tint_symbol_2) {
-  float const scalar_f32 = (*(tint_symbol_1)).arr[idx].scalar_f32;
-  int const scalar_i32 = (*(tint_symbol_1)).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*(tint_symbol_1)).arr[idx].scalar_u32;
-  half const scalar_f16 = (*(tint_symbol_1)).arr[idx].scalar_f16;
-  float2 const vec2_f32 = (*(tint_symbol_1)).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*(tint_symbol_1)).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[idx].vec2_u32;
-  half2 const vec2_f16 = (*(tint_symbol_1)).arr[idx].vec2_f16;
-  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[idx].vec3_u32);
-  half3 const vec3_f16 = half3((*(tint_symbol_1)).arr[idx].vec3_f16);
-  float4 const vec4_f32 = (*(tint_symbol_1)).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*(tint_symbol_1)).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[idx].vec4_u32;
-  half4 const vec4_f16 = (*(tint_symbol_1)).arr[idx].vec4_f16;
-  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[idx].mat2x2_f32;
-  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[idx].mat2x3_f32);
-  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[idx].mat3x2_f32;
-  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[idx].mat3x3_f32);
-  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[idx].mat4x2_f32;
-  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[idx].mat4x3_f32);
-  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[idx].mat4x4_f32;
-  half2x2 const mat2x2_f16 = (*(tint_symbol_1)).arr[idx].mat2x2_f16;
-  half2x3 const mat2x3_f16 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[idx].mat2x3_f16);
-  half2x4 const mat2x4_f16 = (*(tint_symbol_1)).arr[idx].mat2x4_f16;
-  half3x2 const mat3x2_f16 = (*(tint_symbol_1)).arr[idx].mat3x2_f16;
-  half3x3 const mat3x3_f16 = tint_unpack_vec3_in_composite_4((*(tint_symbol_1)).arr[idx].mat3x3_f16);
-  half3x4 const mat3x4_f16 = (*(tint_symbol_1)).arr[idx].mat3x4_f16;
-  half4x2 const mat4x2_f16 = (*(tint_symbol_1)).arr[idx].mat4x2_f16;
-  half4x3 const mat4x3_f16 = tint_unpack_vec3_in_composite_5((*(tint_symbol_1)).arr[idx].mat4x3_f16);
-  half4x4 const mat4x4_f16 = (*(tint_symbol_1)).arr[idx].mat4x4_f16;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_6((*(tint_symbol_1)).arr[idx].arr2_vec3_f32);
-  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*(tint_symbol_1)).arr[idx].arr2_mat4x2_f16;
-  *(tint_symbol_2) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(int(scalar_f16))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(int(vec2_f16[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(int(vec3_f16[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(int(vec4_f16[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(int(mat2x2_f16[0][0]))))) + as_type<uint>(int(mat2x3_f16[0][0]))))) + as_type<uint>(int(mat2x4_f16[0][0]))))) + as_type<uint>(int(mat3x2_f16[0][0]))))) + as_type<uint>(int(mat3x3_f16[0][0]))))) + as_type<uint>(int(mat3x4_f16[0][0]))))) + as_type<uint>(int(mat4x2_f16[0][0]))))) + as_type<uint>(int(mat4x3_f16[0][0]))))) + as_type<uint>(int(mat4x4_f16[0][0]))))) + as_type<uint>(int(arr2_mat4x2_f16[0][0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))));
+void tint_symbol_inner(uint idx, const device S_tint_packed_vec3* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2, device int* const tint_symbol_3) {
+  float const scalar_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_f32;
+  int const scalar_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_i32;
+  uint const scalar_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_u32;
+  half const scalar_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_f16;
+  float2 const vec2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_f32;
+  int2 const vec2_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_i32;
+  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_u32;
+  half2 const vec2_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_f16;
+  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_f32);
+  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_i32);
+  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_u32);
+  half3 const vec3_f16 = half3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_f16);
+  float4 const vec4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_f32;
+  int4 const vec4_i32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_i32;
+  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_u32;
+  half4 const vec4_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_f16;
+  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f32;
+  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f32);
+  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f32;
+  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f32);
+  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f32;
+  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f32);
+  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f32;
+  half2x2 const mat2x2_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f16;
+  half2x3 const mat2x3_f16 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f16);
+  half2x4 const mat2x4_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f16;
+  half3x2 const mat3x2_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f16;
+  half3x3 const mat3x3_f16 = tint_unpack_vec3_in_composite_4((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f16);
+  half3x4 const mat3x4_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f16;
+  half4x2 const mat4x2_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f16;
+  half4x3 const mat4x3_f16 = tint_unpack_vec3_in_composite_5((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f16);
+  half4x4 const mat4x4_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f16;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_6((*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].arr2_vec3_f32);
+  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*(tint_symbol_1)).arr[min(idx, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].arr2_mat4x2_f16;
+  *(tint_symbol_3) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(int(scalar_f16))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(int(vec2_f16[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(int(vec3_f16[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(int(vec4_f16[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(int(mat2x2_f16[0][0]))))) + as_type<uint>(int(mat2x3_f16[0][0]))))) + as_type<uint>(int(mat2x4_f16[0][0]))))) + as_type<uint>(int(mat3x2_f16[0][0]))))) + as_type<uint>(int(mat3x3_f16[0][0]))))) + as_type<uint>(int(mat3x4_f16[0][0]))))) + as_type<uint>(int(mat4x2_f16[0][0]))))) + as_type<uint>(int(mat4x3_f16[0][0]))))) + as_type<uint>(int(mat4x4_f16[0][0]))))) + as_type<uint>(int(arr2_mat4x2_f16[0][0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))));
 }
 
-kernel void tint_symbol(const device S_tint_packed_vec3* tint_symbol_3 [[buffer(1)]], device int* tint_symbol_4 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
-  tint_symbol_inner(idx, tint_symbol_3, tint_symbol_4);
+kernel void tint_symbol(const device S_tint_packed_vec3* tint_symbol_4 [[buffer(1)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]], device int* tint_symbol_6 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
+  tint_symbol_inner(idx, tint_symbol_4, tint_symbol_5, tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.spvasm
index 7aee25a..dcfc4ca 100644
--- a/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/read_f16.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 327
+; Bound: 473
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %60 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -233,10 +234,11 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %51 = OpTypeFunction %void %uint
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_Inner = OpTypePointer StorageBuffer %_runtimearr_Inner
      %uint_0 = OpConstant %uint 0
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
      %uint_3 = OpConstant %uint 3
@@ -305,217 +307,361 @@
 %_ptr_StorageBuffer__arr_mat4v2half_uint_2 = OpTypePointer StorageBuffer %_arr_mat4v2half_uint_2
     %uint_35 = OpConstant %uint 35
 %_ptr_StorageBuffer_int_0 = OpTypePointer StorageBuffer %int
-        %300 = OpTypeFunction %int %float
+        %446 = OpTypeFunction %int %float
 %float_n2_14748365e_09 = OpConstant %float -2.14748365e+09
        %bool = OpTypeBool
 %int_n2147483648 = OpConstant %int -2147483648
 %float_2_14748352e_09 = OpConstant %float 2.14748352e+09
 %int_2147483647 = OpConstant %int 2147483647
-        %313 = OpTypeFunction %int %half
+        %459 = OpTypeFunction %int %half
 %half_n0x1_ffcp_15 = OpConstant %half -0x1.ffcp+15
 %half_0x1_ffcp_15 = OpConstant %half 0x1.ffcp+15
-        %323 = OpTypeFunction %void
+        %469 = OpTypeFunction %void
  %main_inner = OpFunction %void None %51
         %idx = OpFunctionParameter %uint
          %52 = OpLabel
-         %53 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
- %scalar_f32 = OpLoad %float %53 None
-         %57 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
- %scalar_i32 = OpLoad %int %57 None
-         %61 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
- %scalar_u32 = OpLoad %uint %61 None
-         %64 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %idx %uint_3
- %scalar_f16 = OpLoad %half %64 None
-         %68 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_4
-   %vec2_f32 = OpLoad %v2float %68 None
-         %72 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_5
-   %vec2_i32 = OpLoad %v2int %72 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_6
-   %vec2_u32 = OpLoad %v2uint %76 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %idx %uint_7
-   %vec2_f16 = OpLoad %v2half %80 None
-         %84 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_8
-   %vec3_f32 = OpLoad %v3float %84 None
-         %88 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_9
-   %vec3_i32 = OpLoad %v3int %88 None
-         %92 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_10
-   %vec3_u32 = OpLoad %v3uint %92 None
-         %96 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %idx %uint_11
-   %vec3_f16 = OpLoad %v3half %96 None
-        %100 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_12
-   %vec4_f32 = OpLoad %v4float %100 None
-        %104 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_13
-   %vec4_i32 = OpLoad %v4int %104 None
-        %108 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_14
-   %vec4_u32 = OpLoad %v4uint %108 None
-        %112 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %idx %uint_15
-   %vec4_f16 = OpLoad %v4half %112 None
-        %116 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_16
- %mat2x2_f32 = OpLoad %mat2v2float %116 None
-        %120 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %idx %uint_17
- %mat2x3_f32 = OpLoad %mat2v3float %120 None
-        %124 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_18
- %mat2x4_f32 = OpLoad %mat2v4float %124 None
-        %128 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_19
- %mat3x2_f32 = OpLoad %mat3v2float %128 None
-        %132 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %idx %uint_20
- %mat3x3_f32 = OpLoad %mat3v3float %132 None
-        %136 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_21
- %mat3x4_f32 = OpLoad %mat3v4float %136 None
-        %140 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_22
- %mat4x2_f32 = OpLoad %mat4v2float %140 None
-        %144 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %idx %uint_23
- %mat4x3_f32 = OpLoad %mat4v3float %144 None
-        %148 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_24
- %mat4x4_f32 = OpLoad %mat4v4float %148 None
-        %152 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %idx %uint_25
- %mat2x2_f16 = OpLoad %mat2v2half %152 None
-        %156 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %sb %uint_0 %idx %uint_26
- %mat2x3_f16 = OpLoad %mat2v3half %156 None
-        %160 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %idx %uint_27
- %mat2x4_f16 = OpLoad %mat2v4half %160 None
-        %164 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %idx %uint_28
- %mat3x2_f16 = OpLoad %mat3v2half %164 None
-        %168 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %sb %uint_0 %idx %uint_29
- %mat3x3_f16 = OpLoad %mat3v3half %168 None
-        %172 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %idx %uint_30
- %mat3x4_f16 = OpLoad %mat3v4half %172 None
-        %176 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %idx %uint_31
- %mat4x2_f16 = OpLoad %mat4v2half %176 None
-        %180 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %sb %uint_0 %idx %uint_32
- %mat4x3_f16 = OpLoad %mat4v3half %180 None
-        %184 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %idx %uint_33
- %mat4x4_f16 = OpLoad %mat4v4half %184 None
-        %188 = OpAccessChain %_ptr_StorageBuffer__arr_v3float_uint_2 %sb %uint_0 %idx %uint_34
-%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %188 None
-        %192 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %idx %uint_35
-%arr2_mat4x2_f16 = OpLoad %_arr_mat4v2half_uint_2 %192 None
-        %196 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
-        %198 = OpIAdd %int %196 %scalar_i32
-        %199 = OpBitcast %int %scalar_u32
-        %200 = OpIAdd %int %198 %199
-        %201 = OpFunctionCall %int %tint_f16_to_i32 %scalar_f16
-        %203 = OpIAdd %int %200 %201
-        %204 = OpCompositeExtract %float %vec2_f32 0
-        %205 = OpFunctionCall %int %tint_f32_to_i32 %204
-        %206 = OpIAdd %int %203 %205
-        %207 = OpCompositeExtract %int %vec2_i32 0
-        %208 = OpIAdd %int %206 %207
-        %209 = OpCompositeExtract %uint %vec2_u32 0
-        %210 = OpBitcast %int %209
-        %211 = OpIAdd %int %208 %210
-        %212 = OpCompositeExtract %half %vec2_f16 0
-        %213 = OpFunctionCall %int %tint_f16_to_i32 %212
-        %214 = OpIAdd %int %211 %213
-        %215 = OpCompositeExtract %float %vec3_f32 1
-        %216 = OpFunctionCall %int %tint_f32_to_i32 %215
-        %217 = OpIAdd %int %214 %216
-        %218 = OpCompositeExtract %int %vec3_i32 1
-        %219 = OpIAdd %int %217 %218
-        %220 = OpCompositeExtract %uint %vec3_u32 1
-        %221 = OpBitcast %int %220
-        %222 = OpIAdd %int %219 %221
-        %223 = OpCompositeExtract %half %vec3_f16 1
-        %224 = OpFunctionCall %int %tint_f16_to_i32 %223
-        %225 = OpIAdd %int %222 %224
-        %226 = OpCompositeExtract %float %vec4_f32 2
-        %227 = OpFunctionCall %int %tint_f32_to_i32 %226
-        %228 = OpIAdd %int %225 %227
-        %229 = OpCompositeExtract %int %vec4_i32 2
-        %230 = OpIAdd %int %228 %229
-        %231 = OpCompositeExtract %uint %vec4_u32 2
-        %232 = OpBitcast %int %231
-        %233 = OpIAdd %int %230 %232
-        %234 = OpCompositeExtract %half %vec4_f16 2
-        %235 = OpFunctionCall %int %tint_f16_to_i32 %234
-        %236 = OpIAdd %int %233 %235
-        %237 = OpCompositeExtract %float %mat2x2_f32 0 0
-        %238 = OpFunctionCall %int %tint_f32_to_i32 %237
-        %239 = OpIAdd %int %236 %238
-        %240 = OpCompositeExtract %float %mat2x3_f32 0 0
-        %241 = OpFunctionCall %int %tint_f32_to_i32 %240
-        %242 = OpIAdd %int %239 %241
-        %243 = OpCompositeExtract %float %mat2x4_f32 0 0
-        %244 = OpFunctionCall %int %tint_f32_to_i32 %243
-        %245 = OpIAdd %int %242 %244
-        %246 = OpCompositeExtract %float %mat3x2_f32 0 0
-        %247 = OpFunctionCall %int %tint_f32_to_i32 %246
-        %248 = OpIAdd %int %245 %247
-        %249 = OpCompositeExtract %float %mat3x3_f32 0 0
-        %250 = OpFunctionCall %int %tint_f32_to_i32 %249
-        %251 = OpIAdd %int %248 %250
-        %252 = OpCompositeExtract %float %mat3x4_f32 0 0
-        %253 = OpFunctionCall %int %tint_f32_to_i32 %252
-        %254 = OpIAdd %int %251 %253
-        %255 = OpCompositeExtract %float %mat4x2_f32 0 0
-        %256 = OpFunctionCall %int %tint_f32_to_i32 %255
-        %257 = OpIAdd %int %254 %256
-        %258 = OpCompositeExtract %float %mat4x3_f32 0 0
-        %259 = OpFunctionCall %int %tint_f32_to_i32 %258
-        %260 = OpIAdd %int %257 %259
-        %261 = OpCompositeExtract %float %mat4x4_f32 0 0
-        %262 = OpFunctionCall %int %tint_f32_to_i32 %261
-        %263 = OpIAdd %int %260 %262
-        %264 = OpCompositeExtract %half %mat2x2_f16 0 0
-        %265 = OpFunctionCall %int %tint_f16_to_i32 %264
-        %266 = OpIAdd %int %263 %265
-        %267 = OpCompositeExtract %half %mat2x3_f16 0 0
-        %268 = OpFunctionCall %int %tint_f16_to_i32 %267
-        %269 = OpIAdd %int %266 %268
-        %270 = OpCompositeExtract %half %mat2x4_f16 0 0
-        %271 = OpFunctionCall %int %tint_f16_to_i32 %270
-        %272 = OpIAdd %int %269 %271
-        %273 = OpCompositeExtract %half %mat3x2_f16 0 0
-        %274 = OpFunctionCall %int %tint_f16_to_i32 %273
-        %275 = OpIAdd %int %272 %274
-        %276 = OpCompositeExtract %half %mat3x3_f16 0 0
-        %277 = OpFunctionCall %int %tint_f16_to_i32 %276
-        %278 = OpIAdd %int %275 %277
-        %279 = OpCompositeExtract %half %mat3x4_f16 0 0
-        %280 = OpFunctionCall %int %tint_f16_to_i32 %279
-        %281 = OpIAdd %int %278 %280
-        %282 = OpCompositeExtract %half %mat4x2_f16 0 0
-        %283 = OpFunctionCall %int %tint_f16_to_i32 %282
-        %284 = OpIAdd %int %281 %283
-        %285 = OpCompositeExtract %half %mat4x3_f16 0 0
-        %286 = OpFunctionCall %int %tint_f16_to_i32 %285
-        %287 = OpIAdd %int %284 %286
-        %288 = OpCompositeExtract %half %mat4x4_f16 0 0
-        %289 = OpFunctionCall %int %tint_f16_to_i32 %288
-        %290 = OpIAdd %int %287 %289
-        %291 = OpCompositeExtract %half %arr2_mat4x2_f16 0 0 0
-        %292 = OpFunctionCall %int %tint_f16_to_i32 %291
-        %293 = OpIAdd %int %290 %292
-        %294 = OpCompositeExtract %float %arr2_vec3_f32 0 0
-        %295 = OpFunctionCall %int %tint_f32_to_i32 %294
-        %296 = OpIAdd %int %293 %295
-        %297 = OpAccessChain %_ptr_StorageBuffer_int_0 %43 %uint_0
-               OpStore %297 %296 None
+         %53 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %56 = OpArrayLength %uint %sb 0
+         %57 = OpISub %uint %56 %uint_1
+         %59 = OpExtInst %uint %60 UMin %idx %57
+         %61 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %59 %uint_0
+ %scalar_f32 = OpLoad %float %61 None
+         %64 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %65 = OpArrayLength %uint %sb 0
+         %66 = OpISub %uint %65 %uint_1
+         %67 = OpExtInst %uint %60 UMin %idx %66
+         %68 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %67 %uint_1
+ %scalar_i32 = OpLoad %int %68 None
+         %71 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %72 = OpArrayLength %uint %sb 0
+         %73 = OpISub %uint %72 %uint_1
+         %74 = OpExtInst %uint %60 UMin %idx %73
+         %75 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %74 %uint_2
+ %scalar_u32 = OpLoad %uint %75 None
+         %78 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %79 = OpArrayLength %uint %sb 0
+         %80 = OpISub %uint %79 %uint_1
+         %81 = OpExtInst %uint %60 UMin %idx %80
+         %82 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %81 %uint_3
+ %scalar_f16 = OpLoad %half %82 None
+         %86 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %87 = OpArrayLength %uint %sb 0
+         %88 = OpISub %uint %87 %uint_1
+         %89 = OpExtInst %uint %60 UMin %idx %88
+         %90 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %89 %uint_4
+   %vec2_f32 = OpLoad %v2float %90 None
+         %94 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %95 = OpArrayLength %uint %sb 0
+         %96 = OpISub %uint %95 %uint_1
+         %97 = OpExtInst %uint %60 UMin %idx %96
+         %98 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %97 %uint_5
+   %vec2_i32 = OpLoad %v2int %98 None
+        %102 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %103 = OpArrayLength %uint %sb 0
+        %104 = OpISub %uint %103 %uint_1
+        %105 = OpExtInst %uint %60 UMin %idx %104
+        %106 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %105 %uint_6
+   %vec2_u32 = OpLoad %v2uint %106 None
+        %110 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %111 = OpArrayLength %uint %sb 0
+        %112 = OpISub %uint %111 %uint_1
+        %113 = OpExtInst %uint %60 UMin %idx %112
+        %114 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %113 %uint_7
+   %vec2_f16 = OpLoad %v2half %114 None
+        %118 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %119 = OpArrayLength %uint %sb 0
+        %120 = OpISub %uint %119 %uint_1
+        %121 = OpExtInst %uint %60 UMin %idx %120
+        %122 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %121 %uint_8
+   %vec3_f32 = OpLoad %v3float %122 None
+        %126 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %127 = OpArrayLength %uint %sb 0
+        %128 = OpISub %uint %127 %uint_1
+        %129 = OpExtInst %uint %60 UMin %idx %128
+        %130 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %129 %uint_9
+   %vec3_i32 = OpLoad %v3int %130 None
+        %134 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %135 = OpArrayLength %uint %sb 0
+        %136 = OpISub %uint %135 %uint_1
+        %137 = OpExtInst %uint %60 UMin %idx %136
+        %138 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %137 %uint_10
+   %vec3_u32 = OpLoad %v3uint %138 None
+        %142 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %143 = OpArrayLength %uint %sb 0
+        %144 = OpISub %uint %143 %uint_1
+        %145 = OpExtInst %uint %60 UMin %idx %144
+        %146 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %145 %uint_11
+   %vec3_f16 = OpLoad %v3half %146 None
+        %150 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %151 = OpArrayLength %uint %sb 0
+        %152 = OpISub %uint %151 %uint_1
+        %153 = OpExtInst %uint %60 UMin %idx %152
+        %154 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %153 %uint_12
+   %vec4_f32 = OpLoad %v4float %154 None
+        %158 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %159 = OpArrayLength %uint %sb 0
+        %160 = OpISub %uint %159 %uint_1
+        %161 = OpExtInst %uint %60 UMin %idx %160
+        %162 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %161 %uint_13
+   %vec4_i32 = OpLoad %v4int %162 None
+        %166 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %167 = OpArrayLength %uint %sb 0
+        %168 = OpISub %uint %167 %uint_1
+        %169 = OpExtInst %uint %60 UMin %idx %168
+        %170 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %169 %uint_14
+   %vec4_u32 = OpLoad %v4uint %170 None
+        %174 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %175 = OpArrayLength %uint %sb 0
+        %176 = OpISub %uint %175 %uint_1
+        %177 = OpExtInst %uint %60 UMin %idx %176
+        %178 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %177 %uint_15
+   %vec4_f16 = OpLoad %v4half %178 None
+        %182 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %183 = OpArrayLength %uint %sb 0
+        %184 = OpISub %uint %183 %uint_1
+        %185 = OpExtInst %uint %60 UMin %idx %184
+        %186 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %185 %uint_16
+ %mat2x2_f32 = OpLoad %mat2v2float %186 None
+        %190 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %191 = OpArrayLength %uint %sb 0
+        %192 = OpISub %uint %191 %uint_1
+        %193 = OpExtInst %uint %60 UMin %idx %192
+        %194 = OpAccessChain %_ptr_StorageBuffer_mat2v3float %sb %uint_0 %193 %uint_17
+ %mat2x3_f32 = OpLoad %mat2v3float %194 None
+        %198 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %199 = OpArrayLength %uint %sb 0
+        %200 = OpISub %uint %199 %uint_1
+        %201 = OpExtInst %uint %60 UMin %idx %200
+        %202 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %201 %uint_18
+ %mat2x4_f32 = OpLoad %mat2v4float %202 None
+        %206 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %207 = OpArrayLength %uint %sb 0
+        %208 = OpISub %uint %207 %uint_1
+        %209 = OpExtInst %uint %60 UMin %idx %208
+        %210 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %209 %uint_19
+ %mat3x2_f32 = OpLoad %mat3v2float %210 None
+        %214 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %215 = OpArrayLength %uint %sb 0
+        %216 = OpISub %uint %215 %uint_1
+        %217 = OpExtInst %uint %60 UMin %idx %216
+        %218 = OpAccessChain %_ptr_StorageBuffer_mat3v3float %sb %uint_0 %217 %uint_20
+ %mat3x3_f32 = OpLoad %mat3v3float %218 None
+        %222 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %223 = OpArrayLength %uint %sb 0
+        %224 = OpISub %uint %223 %uint_1
+        %225 = OpExtInst %uint %60 UMin %idx %224
+        %226 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %225 %uint_21
+ %mat3x4_f32 = OpLoad %mat3v4float %226 None
+        %230 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %231 = OpArrayLength %uint %sb 0
+        %232 = OpISub %uint %231 %uint_1
+        %233 = OpExtInst %uint %60 UMin %idx %232
+        %234 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %233 %uint_22
+ %mat4x2_f32 = OpLoad %mat4v2float %234 None
+        %238 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %239 = OpArrayLength %uint %sb 0
+        %240 = OpISub %uint %239 %uint_1
+        %241 = OpExtInst %uint %60 UMin %idx %240
+        %242 = OpAccessChain %_ptr_StorageBuffer_mat4v3float %sb %uint_0 %241 %uint_23
+ %mat4x3_f32 = OpLoad %mat4v3float %242 None
+        %246 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %247 = OpArrayLength %uint %sb 0
+        %248 = OpISub %uint %247 %uint_1
+        %249 = OpExtInst %uint %60 UMin %idx %248
+        %250 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %249 %uint_24
+ %mat4x4_f32 = OpLoad %mat4v4float %250 None
+        %254 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %255 = OpArrayLength %uint %sb 0
+        %256 = OpISub %uint %255 %uint_1
+        %257 = OpExtInst %uint %60 UMin %idx %256
+        %258 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %257 %uint_25
+ %mat2x2_f16 = OpLoad %mat2v2half %258 None
+        %262 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %263 = OpArrayLength %uint %sb 0
+        %264 = OpISub %uint %263 %uint_1
+        %265 = OpExtInst %uint %60 UMin %idx %264
+        %266 = OpAccessChain %_ptr_StorageBuffer_mat2v3half %sb %uint_0 %265 %uint_26
+ %mat2x3_f16 = OpLoad %mat2v3half %266 None
+        %270 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %271 = OpArrayLength %uint %sb 0
+        %272 = OpISub %uint %271 %uint_1
+        %273 = OpExtInst %uint %60 UMin %idx %272
+        %274 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %273 %uint_27
+ %mat2x4_f16 = OpLoad %mat2v4half %274 None
+        %278 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %279 = OpArrayLength %uint %sb 0
+        %280 = OpISub %uint %279 %uint_1
+        %281 = OpExtInst %uint %60 UMin %idx %280
+        %282 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %281 %uint_28
+ %mat3x2_f16 = OpLoad %mat3v2half %282 None
+        %286 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %287 = OpArrayLength %uint %sb 0
+        %288 = OpISub %uint %287 %uint_1
+        %289 = OpExtInst %uint %60 UMin %idx %288
+        %290 = OpAccessChain %_ptr_StorageBuffer_mat3v3half %sb %uint_0 %289 %uint_29
+ %mat3x3_f16 = OpLoad %mat3v3half %290 None
+        %294 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %295 = OpArrayLength %uint %sb 0
+        %296 = OpISub %uint %295 %uint_1
+        %297 = OpExtInst %uint %60 UMin %idx %296
+        %298 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %297 %uint_30
+ %mat3x4_f16 = OpLoad %mat3v4half %298 None
+        %302 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %303 = OpArrayLength %uint %sb 0
+        %304 = OpISub %uint %303 %uint_1
+        %305 = OpExtInst %uint %60 UMin %idx %304
+        %306 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %305 %uint_31
+ %mat4x2_f16 = OpLoad %mat4v2half %306 None
+        %310 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %311 = OpArrayLength %uint %sb 0
+        %312 = OpISub %uint %311 %uint_1
+        %313 = OpExtInst %uint %60 UMin %idx %312
+        %314 = OpAccessChain %_ptr_StorageBuffer_mat4v3half %sb %uint_0 %313 %uint_32
+ %mat4x3_f16 = OpLoad %mat4v3half %314 None
+        %318 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %319 = OpArrayLength %uint %sb 0
+        %320 = OpISub %uint %319 %uint_1
+        %321 = OpExtInst %uint %60 UMin %idx %320
+        %322 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %321 %uint_33
+ %mat4x4_f16 = OpLoad %mat4v4half %322 None
+        %326 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %327 = OpArrayLength %uint %sb 0
+        %328 = OpISub %uint %327 %uint_1
+        %329 = OpExtInst %uint %60 UMin %idx %328
+        %330 = OpAccessChain %_ptr_StorageBuffer__arr_v3float_uint_2 %sb %uint_0 %329 %uint_34
+%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %330 None
+        %334 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %335 = OpArrayLength %uint %sb 0
+        %336 = OpISub %uint %335 %uint_1
+        %337 = OpExtInst %uint %60 UMin %idx %336
+        %338 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %337 %uint_35
+%arr2_mat4x2_f16 = OpLoad %_arr_mat4v2half_uint_2 %338 None
+        %342 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
+        %344 = OpIAdd %int %342 %scalar_i32
+        %345 = OpBitcast %int %scalar_u32
+        %346 = OpIAdd %int %344 %345
+        %347 = OpFunctionCall %int %tint_f16_to_i32 %scalar_f16
+        %349 = OpIAdd %int %346 %347
+        %350 = OpCompositeExtract %float %vec2_f32 0
+        %351 = OpFunctionCall %int %tint_f32_to_i32 %350
+        %352 = OpIAdd %int %349 %351
+        %353 = OpCompositeExtract %int %vec2_i32 0
+        %354 = OpIAdd %int %352 %353
+        %355 = OpCompositeExtract %uint %vec2_u32 0
+        %356 = OpBitcast %int %355
+        %357 = OpIAdd %int %354 %356
+        %358 = OpCompositeExtract %half %vec2_f16 0
+        %359 = OpFunctionCall %int %tint_f16_to_i32 %358
+        %360 = OpIAdd %int %357 %359
+        %361 = OpCompositeExtract %float %vec3_f32 1
+        %362 = OpFunctionCall %int %tint_f32_to_i32 %361
+        %363 = OpIAdd %int %360 %362
+        %364 = OpCompositeExtract %int %vec3_i32 1
+        %365 = OpIAdd %int %363 %364
+        %366 = OpCompositeExtract %uint %vec3_u32 1
+        %367 = OpBitcast %int %366
+        %368 = OpIAdd %int %365 %367
+        %369 = OpCompositeExtract %half %vec3_f16 1
+        %370 = OpFunctionCall %int %tint_f16_to_i32 %369
+        %371 = OpIAdd %int %368 %370
+        %372 = OpCompositeExtract %float %vec4_f32 2
+        %373 = OpFunctionCall %int %tint_f32_to_i32 %372
+        %374 = OpIAdd %int %371 %373
+        %375 = OpCompositeExtract %int %vec4_i32 2
+        %376 = OpIAdd %int %374 %375
+        %377 = OpCompositeExtract %uint %vec4_u32 2
+        %378 = OpBitcast %int %377
+        %379 = OpIAdd %int %376 %378
+        %380 = OpCompositeExtract %half %vec4_f16 2
+        %381 = OpFunctionCall %int %tint_f16_to_i32 %380
+        %382 = OpIAdd %int %379 %381
+        %383 = OpCompositeExtract %float %mat2x2_f32 0 0
+        %384 = OpFunctionCall %int %tint_f32_to_i32 %383
+        %385 = OpIAdd %int %382 %384
+        %386 = OpCompositeExtract %float %mat2x3_f32 0 0
+        %387 = OpFunctionCall %int %tint_f32_to_i32 %386
+        %388 = OpIAdd %int %385 %387
+        %389 = OpCompositeExtract %float %mat2x4_f32 0 0
+        %390 = OpFunctionCall %int %tint_f32_to_i32 %389
+        %391 = OpIAdd %int %388 %390
+        %392 = OpCompositeExtract %float %mat3x2_f32 0 0
+        %393 = OpFunctionCall %int %tint_f32_to_i32 %392
+        %394 = OpIAdd %int %391 %393
+        %395 = OpCompositeExtract %float %mat3x3_f32 0 0
+        %396 = OpFunctionCall %int %tint_f32_to_i32 %395
+        %397 = OpIAdd %int %394 %396
+        %398 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %399 = OpFunctionCall %int %tint_f32_to_i32 %398
+        %400 = OpIAdd %int %397 %399
+        %401 = OpCompositeExtract %float %mat4x2_f32 0 0
+        %402 = OpFunctionCall %int %tint_f32_to_i32 %401
+        %403 = OpIAdd %int %400 %402
+        %404 = OpCompositeExtract %float %mat4x3_f32 0 0
+        %405 = OpFunctionCall %int %tint_f32_to_i32 %404
+        %406 = OpIAdd %int %403 %405
+        %407 = OpCompositeExtract %float %mat4x4_f32 0 0
+        %408 = OpFunctionCall %int %tint_f32_to_i32 %407
+        %409 = OpIAdd %int %406 %408
+        %410 = OpCompositeExtract %half %mat2x2_f16 0 0
+        %411 = OpFunctionCall %int %tint_f16_to_i32 %410
+        %412 = OpIAdd %int %409 %411
+        %413 = OpCompositeExtract %half %mat2x3_f16 0 0
+        %414 = OpFunctionCall %int %tint_f16_to_i32 %413
+        %415 = OpIAdd %int %412 %414
+        %416 = OpCompositeExtract %half %mat2x4_f16 0 0
+        %417 = OpFunctionCall %int %tint_f16_to_i32 %416
+        %418 = OpIAdd %int %415 %417
+        %419 = OpCompositeExtract %half %mat3x2_f16 0 0
+        %420 = OpFunctionCall %int %tint_f16_to_i32 %419
+        %421 = OpIAdd %int %418 %420
+        %422 = OpCompositeExtract %half %mat3x3_f16 0 0
+        %423 = OpFunctionCall %int %tint_f16_to_i32 %422
+        %424 = OpIAdd %int %421 %423
+        %425 = OpCompositeExtract %half %mat3x4_f16 0 0
+        %426 = OpFunctionCall %int %tint_f16_to_i32 %425
+        %427 = OpIAdd %int %424 %426
+        %428 = OpCompositeExtract %half %mat4x2_f16 0 0
+        %429 = OpFunctionCall %int %tint_f16_to_i32 %428
+        %430 = OpIAdd %int %427 %429
+        %431 = OpCompositeExtract %half %mat4x3_f16 0 0
+        %432 = OpFunctionCall %int %tint_f16_to_i32 %431
+        %433 = OpIAdd %int %430 %432
+        %434 = OpCompositeExtract %half %mat4x4_f16 0 0
+        %435 = OpFunctionCall %int %tint_f16_to_i32 %434
+        %436 = OpIAdd %int %433 %435
+        %437 = OpCompositeExtract %half %arr2_mat4x2_f16 0 0 0
+        %438 = OpFunctionCall %int %tint_f16_to_i32 %437
+        %439 = OpIAdd %int %436 %438
+        %440 = OpCompositeExtract %float %arr2_vec3_f32 0 0
+        %441 = OpFunctionCall %int %tint_f32_to_i32 %440
+        %442 = OpIAdd %int %439 %441
+        %443 = OpAccessChain %_ptr_StorageBuffer_int_0 %43 %uint_0
+               OpStore %443 %442 None
                OpReturn
                OpFunctionEnd
-%tint_f32_to_i32 = OpFunction %int None %300
+%tint_f32_to_i32 = OpFunction %int None %446
       %value = OpFunctionParameter %float
-        %301 = OpLabel
-        %302 = OpConvertFToS %int %value
-        %303 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
-        %306 = OpSelect %int %303 %302 %int_n2147483648
-        %308 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
-        %310 = OpSelect %int %308 %306 %int_2147483647
-               OpReturnValue %310
+        %447 = OpLabel
+        %448 = OpConvertFToS %int %value
+        %449 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
+        %452 = OpSelect %int %449 %448 %int_n2147483648
+        %454 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
+        %456 = OpSelect %int %454 %452 %int_2147483647
+               OpReturnValue %456
                OpFunctionEnd
-%tint_f16_to_i32 = OpFunction %int None %313
+%tint_f16_to_i32 = OpFunction %int None %459
     %value_0 = OpFunctionParameter %half
-        %314 = OpLabel
-        %315 = OpConvertFToS %int %value_0
-        %316 = OpFOrdGreaterThanEqual %bool %value_0 %half_n0x1_ffcp_15
-        %318 = OpSelect %int %316 %315 %int_n2147483648
-        %319 = OpFOrdLessThanEqual %bool %value_0 %half_0x1_ffcp_15
-        %321 = OpSelect %int %319 %318 %int_2147483647
-               OpReturnValue %321
+        %460 = OpLabel
+        %461 = OpConvertFToS %int %value_0
+        %462 = OpFOrdGreaterThanEqual %bool %value_0 %half_n0x1_ffcp_15
+        %464 = OpSelect %int %462 %461 %int_n2147483648
+        %465 = OpFOrdLessThanEqual %bool %value_0 %half_0x1_ffcp_15
+        %467 = OpSelect %int %465 %464 %int_2147483647
+               OpReturnValue %467
                OpFunctionEnd
-       %main = OpFunction %void None %323
-        %324 = OpLabel
-        %325 = OpLoad %uint %main_local_invocation_index_Input None
-        %326 = OpFunctionCall %void %main_inner %325
+       %main = OpFunction %void None %469
+        %470 = OpLabel
+        %471 = OpLoad %uint %main_local_invocation_index_Input None
+        %472 = OpFunctionCall %void %main_inner %471
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.dxc.hlsl
index def10b2..550de5a 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.dxc.hlsl
@@ -68,29 +68,32 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((544u * idx), asuint(0.0f));
-  sb.Store(((544u * idx) + 4u), asuint(0));
-  sb.Store(((544u * idx) + 8u), asuint(0u));
-  sb.Store2(((544u * idx) + 16u), asuint((0.0f).xx));
-  sb.Store2(((544u * idx) + 24u), asuint(int2((0).xx)));
-  sb.Store2(((544u * idx) + 32u), asuint((0u).xx));
-  sb.Store3(((544u * idx) + 48u), asuint((0.0f).xxx));
-  sb.Store3(((544u * idx) + 64u), asuint(int3((0).xxx)));
-  sb.Store3(((544u * idx) + 80u), asuint((0u).xxx));
-  sb.Store4(((544u * idx) + 96u), asuint((0.0f).xxxx));
-  sb.Store4(((544u * idx) + 112u), asuint(int4((0).xxxx)));
-  sb.Store4(((544u * idx) + 128u), asuint((0u).xxxx));
-  sb_store_12(((544u * idx) + 144u), float2x2((0.0f).xx, (0.0f).xx));
-  sb_store_13(((544u * idx) + 160u), float2x3((0.0f).xxx, (0.0f).xxx));
-  sb_store_14(((544u * idx) + 192u), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  sb_store_15(((544u * idx) + 224u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_16(((544u * idx) + 256u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_17(((544u * idx) + 304u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  sb_store_18(((544u * idx) + 352u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_19(((544u * idx) + 384u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_20(((544u * idx) + 448u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  float3 tint_symbol_2[2] = (float3[2])0;
-  sb_store_21(((544u * idx) + 512u), tint_symbol_2);
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 544u);
+  sb.Store((544u * min(idx, (tint_symbol_4 - 1u))), asuint(0.0f));
+  sb.Store(((544u * min(idx, (tint_symbol_4 - 1u))) + 4u), asuint(0));
+  sb.Store(((544u * min(idx, (tint_symbol_4 - 1u))) + 8u), asuint(0u));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 16u), asuint((0.0f).xx));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 24u), asuint(int2((0).xx)));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 32u), asuint((0u).xx));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 48u), asuint((0.0f).xxx));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 64u), asuint(int3((0).xxx)));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 80u), asuint((0u).xxx));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 96u), asuint((0.0f).xxxx));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 112u), asuint(int4((0).xxxx)));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 128u), asuint((0u).xxxx));
+  sb_store_12(((544u * min(idx, (tint_symbol_4 - 1u))) + 144u), float2x2((0.0f).xx, (0.0f).xx));
+  sb_store_13(((544u * min(idx, (tint_symbol_4 - 1u))) + 160u), float2x3((0.0f).xxx, (0.0f).xxx));
+  sb_store_14(((544u * min(idx, (tint_symbol_4 - 1u))) + 192u), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  sb_store_15(((544u * min(idx, (tint_symbol_4 - 1u))) + 224u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_16(((544u * min(idx, (tint_symbol_4 - 1u))) + 256u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_17(((544u * min(idx, (tint_symbol_4 - 1u))) + 304u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  sb_store_18(((544u * min(idx, (tint_symbol_4 - 1u))) + 352u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_19(((544u * min(idx, (tint_symbol_4 - 1u))) + 384u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_20(((544u * min(idx, (tint_symbol_4 - 1u))) + 448u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  float3 tint_symbol_5[2] = (float3[2])0;
+  sb_store_21(((544u * min(idx, (tint_symbol_4 - 1u))) + 512u), tint_symbol_5);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.fxc.hlsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.fxc.hlsl
index def10b2..550de5a 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.fxc.hlsl
@@ -68,29 +68,32 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((544u * idx), asuint(0.0f));
-  sb.Store(((544u * idx) + 4u), asuint(0));
-  sb.Store(((544u * idx) + 8u), asuint(0u));
-  sb.Store2(((544u * idx) + 16u), asuint((0.0f).xx));
-  sb.Store2(((544u * idx) + 24u), asuint(int2((0).xx)));
-  sb.Store2(((544u * idx) + 32u), asuint((0u).xx));
-  sb.Store3(((544u * idx) + 48u), asuint((0.0f).xxx));
-  sb.Store3(((544u * idx) + 64u), asuint(int3((0).xxx)));
-  sb.Store3(((544u * idx) + 80u), asuint((0u).xxx));
-  sb.Store4(((544u * idx) + 96u), asuint((0.0f).xxxx));
-  sb.Store4(((544u * idx) + 112u), asuint(int4((0).xxxx)));
-  sb.Store4(((544u * idx) + 128u), asuint((0u).xxxx));
-  sb_store_12(((544u * idx) + 144u), float2x2((0.0f).xx, (0.0f).xx));
-  sb_store_13(((544u * idx) + 160u), float2x3((0.0f).xxx, (0.0f).xxx));
-  sb_store_14(((544u * idx) + 192u), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  sb_store_15(((544u * idx) + 224u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_16(((544u * idx) + 256u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_17(((544u * idx) + 304u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  sb_store_18(((544u * idx) + 352u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_19(((544u * idx) + 384u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_20(((544u * idx) + 448u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  float3 tint_symbol_2[2] = (float3[2])0;
-  sb_store_21(((544u * idx) + 512u), tint_symbol_2);
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 544u);
+  sb.Store((544u * min(idx, (tint_symbol_4 - 1u))), asuint(0.0f));
+  sb.Store(((544u * min(idx, (tint_symbol_4 - 1u))) + 4u), asuint(0));
+  sb.Store(((544u * min(idx, (tint_symbol_4 - 1u))) + 8u), asuint(0u));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 16u), asuint((0.0f).xx));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 24u), asuint(int2((0).xx)));
+  sb.Store2(((544u * min(idx, (tint_symbol_4 - 1u))) + 32u), asuint((0u).xx));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 48u), asuint((0.0f).xxx));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 64u), asuint(int3((0).xxx)));
+  sb.Store3(((544u * min(idx, (tint_symbol_4 - 1u))) + 80u), asuint((0u).xxx));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 96u), asuint((0.0f).xxxx));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 112u), asuint(int4((0).xxxx)));
+  sb.Store4(((544u * min(idx, (tint_symbol_4 - 1u))) + 128u), asuint((0u).xxxx));
+  sb_store_12(((544u * min(idx, (tint_symbol_4 - 1u))) + 144u), float2x2((0.0f).xx, (0.0f).xx));
+  sb_store_13(((544u * min(idx, (tint_symbol_4 - 1u))) + 160u), float2x3((0.0f).xxx, (0.0f).xxx));
+  sb_store_14(((544u * min(idx, (tint_symbol_4 - 1u))) + 192u), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  sb_store_15(((544u * min(idx, (tint_symbol_4 - 1u))) + 224u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_16(((544u * min(idx, (tint_symbol_4 - 1u))) + 256u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_17(((544u * min(idx, (tint_symbol_4 - 1u))) + 304u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  sb_store_18(((544u * min(idx, (tint_symbol_4 - 1u))) + 352u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_19(((544u * min(idx, (tint_symbol_4 - 1u))) + 384u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_20(((544u * min(idx, (tint_symbol_4 - 1u))) + 448u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  float3 tint_symbol_5[2] = (float3[2])0;
+  sb_store_21(((544u * min(idx, (tint_symbol_4 - 1u))) + 512u), tint_symbol_5);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
index 78b72f9..3689b83 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.glsl
@@ -71,28 +71,46 @@
   sb.arr[target_indices[0u]].mat2x3_f32[1u] = value_param[1u];
 }
 void tint_symbol_inner(uint idx) {
-  sb.arr[idx].scalar_f32 = 0.0f;
-  sb.arr[idx].scalar_i32 = 0;
-  sb.arr[idx].scalar_u32 = 0u;
-  sb.arr[idx].vec2_f32 = vec2(0.0f);
-  sb.arr[idx].vec2_i32 = ivec2(0);
-  sb.arr[idx].vec2_u32 = uvec2(0u);
-  sb.arr[idx].vec3_f32 = vec3(0.0f);
-  sb.arr[idx].vec3_i32 = ivec3(0);
-  sb.arr[idx].vec3_u32 = uvec3(0u);
-  sb.arr[idx].vec4_f32 = vec4(0.0f);
-  sb.arr[idx].vec4_i32 = ivec4(0);
-  sb.arr[idx].vec4_u32 = uvec4(0u);
-  sb.arr[idx].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding(uint[1](idx), mat2x3(vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
-  sb.arr[idx].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding_1(uint[1](idx), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  sb.arr[idx].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding_2(uint[1](idx), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  tint_store_and_preserve_padding_3(uint[1](idx), vec3[2](vec3(0.0f), vec3(0.0f)));
+  uint v_2 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_2].scalar_f32 = 0.0f;
+  uint v_3 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_3].scalar_i32 = 0;
+  uint v_4 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_4].scalar_u32 = 0u;
+  uint v_5 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_5].vec2_f32 = vec2(0.0f);
+  uint v_6 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_6].vec2_i32 = ivec2(0);
+  uint v_7 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_7].vec2_u32 = uvec2(0u);
+  uint v_8 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_8].vec3_f32 = vec3(0.0f);
+  uint v_9 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_9].vec3_i32 = ivec3(0);
+  uint v_10 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_10].vec3_u32 = uvec3(0u);
+  uint v_11 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_11].vec4_f32 = vec4(0.0f);
+  uint v_12 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_12].vec4_i32 = ivec4(0);
+  uint v_13 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_13].vec4_u32 = uvec4(0u);
+  uint v_14 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_14].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat2x3(vec3(0.0f), vec3(0.0f)));
+  uint v_15 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_15].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
+  uint v_16 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_16].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding_1(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
+  uint v_17 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_17].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
+  uint v_18 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_18].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding_2(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
+  uint v_19 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_19].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
+  tint_store_and_preserve_padding_3(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), vec3[2](vec3(0.0f), vec3(0.0f)));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.dxc.hlsl
index 7b4c9e1..6e3d233 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.dxc.hlsl
@@ -77,29 +77,76 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((0u + (idx * 544u)), asuint(0.0f));
-  sb.Store((4u + (idx * 544u)), asuint(int(0)));
-  sb.Store((8u + (idx * 544u)), 0u);
-  sb.Store2((16u + (idx * 544u)), asuint((0.0f).xx));
-  sb.Store2((24u + (idx * 544u)), asuint(int2((int(0)).xx)));
-  sb.Store2((32u + (idx * 544u)), (0u).xx);
-  sb.Store3((48u + (idx * 544u)), asuint((0.0f).xxx));
-  sb.Store3((64u + (idx * 544u)), asuint(int3((int(0)).xxx)));
-  sb.Store3((80u + (idx * 544u)), (0u).xxx);
-  sb.Store4((96u + (idx * 544u)), asuint((0.0f).xxxx));
-  sb.Store4((112u + (idx * 544u)), asuint(int4((int(0)).xxxx)));
-  sb.Store4((128u + (idx * 544u)), (0u).xxxx);
-  v_11((144u + (idx * 544u)), float2x2((0.0f).xx, (0.0f).xx));
-  v_10((160u + (idx * 544u)), float2x3((0.0f).xxx, (0.0f).xxx));
-  v_9((192u + (idx * 544u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  v_8((224u + (idx * 544u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_7((256u + (idx * 544u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_6((304u + (idx * 544u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  v_5((352u + (idx * 544u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_4((384u + (idx * 544u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_3((448u + (idx * 544u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  float3 v_12[2] = (float3[2])0;
-  v((512u + (idx * 544u)), v_12);
+  uint v_12 = 0u;
+  sb.GetDimensions(v_12);
+  sb.Store((0u + (min(idx, ((v_12 / 544u) - 1u)) * 544u)), asuint(0.0f));
+  uint v_13 = 0u;
+  sb.GetDimensions(v_13);
+  sb.Store((4u + (min(idx, ((v_13 / 544u) - 1u)) * 544u)), asuint(int(0)));
+  uint v_14 = 0u;
+  sb.GetDimensions(v_14);
+  sb.Store((8u + (min(idx, ((v_14 / 544u) - 1u)) * 544u)), 0u);
+  uint v_15 = 0u;
+  sb.GetDimensions(v_15);
+  sb.Store2((16u + (min(idx, ((v_15 / 544u) - 1u)) * 544u)), asuint((0.0f).xx));
+  uint v_16 = 0u;
+  sb.GetDimensions(v_16);
+  uint v_17 = (24u + (min(idx, ((v_16 / 544u) - 1u)) * 544u));
+  sb.Store2(v_17, asuint(int2((int(0)).xx)));
+  uint v_18 = 0u;
+  sb.GetDimensions(v_18);
+  sb.Store2((32u + (min(idx, ((v_18 / 544u) - 1u)) * 544u)), (0u).xx);
+  uint v_19 = 0u;
+  sb.GetDimensions(v_19);
+  sb.Store3((48u + (min(idx, ((v_19 / 544u) - 1u)) * 544u)), asuint((0.0f).xxx));
+  uint v_20 = 0u;
+  sb.GetDimensions(v_20);
+  uint v_21 = (64u + (min(idx, ((v_20 / 544u) - 1u)) * 544u));
+  sb.Store3(v_21, asuint(int3((int(0)).xxx)));
+  uint v_22 = 0u;
+  sb.GetDimensions(v_22);
+  sb.Store3((80u + (min(idx, ((v_22 / 544u) - 1u)) * 544u)), (0u).xxx);
+  uint v_23 = 0u;
+  sb.GetDimensions(v_23);
+  sb.Store4((96u + (min(idx, ((v_23 / 544u) - 1u)) * 544u)), asuint((0.0f).xxxx));
+  uint v_24 = 0u;
+  sb.GetDimensions(v_24);
+  uint v_25 = (112u + (min(idx, ((v_24 / 544u) - 1u)) * 544u));
+  sb.Store4(v_25, asuint(int4((int(0)).xxxx)));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  sb.Store4((128u + (min(idx, ((v_26 / 544u) - 1u)) * 544u)), (0u).xxxx);
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  v_11((144u + (min(idx, ((v_27 / 544u) - 1u)) * 544u)), float2x2((0.0f).xx, (0.0f).xx));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  v_10((160u + (min(idx, ((v_28 / 544u) - 1u)) * 544u)), float2x3((0.0f).xxx, (0.0f).xxx));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  v_9((192u + (min(idx, ((v_29 / 544u) - 1u)) * 544u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  uint v_30 = 0u;
+  sb.GetDimensions(v_30);
+  v_8((224u + (min(idx, ((v_30 / 544u) - 1u)) * 544u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  v_7((256u + (min(idx, ((v_31 / 544u) - 1u)) * 544u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  v_6((304u + (min(idx, ((v_32 / 544u) - 1u)) * 544u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  v_5((352u + (min(idx, ((v_33 / 544u) - 1u)) * 544u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  v_4((384u + (min(idx, ((v_34 / 544u) - 1u)) * 544u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_35 = 0u;
+  sb.GetDimensions(v_35);
+  v_3((448u + (min(idx, ((v_35 / 544u) - 1u)) * 544u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_36 = 0u;
+  sb.GetDimensions(v_36);
+  float3 v_37[2] = (float3[2])0;
+  v((512u + (min(idx, ((v_36 / 544u) - 1u)) * 544u)), v_37);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.fxc.hlsl
index 7b4c9e1..6e3d233 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.fxc.hlsl
@@ -77,29 +77,76 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((0u + (idx * 544u)), asuint(0.0f));
-  sb.Store((4u + (idx * 544u)), asuint(int(0)));
-  sb.Store((8u + (idx * 544u)), 0u);
-  sb.Store2((16u + (idx * 544u)), asuint((0.0f).xx));
-  sb.Store2((24u + (idx * 544u)), asuint(int2((int(0)).xx)));
-  sb.Store2((32u + (idx * 544u)), (0u).xx);
-  sb.Store3((48u + (idx * 544u)), asuint((0.0f).xxx));
-  sb.Store3((64u + (idx * 544u)), asuint(int3((int(0)).xxx)));
-  sb.Store3((80u + (idx * 544u)), (0u).xxx);
-  sb.Store4((96u + (idx * 544u)), asuint((0.0f).xxxx));
-  sb.Store4((112u + (idx * 544u)), asuint(int4((int(0)).xxxx)));
-  sb.Store4((128u + (idx * 544u)), (0u).xxxx);
-  v_11((144u + (idx * 544u)), float2x2((0.0f).xx, (0.0f).xx));
-  v_10((160u + (idx * 544u)), float2x3((0.0f).xxx, (0.0f).xxx));
-  v_9((192u + (idx * 544u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  v_8((224u + (idx * 544u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_7((256u + (idx * 544u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_6((304u + (idx * 544u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  v_5((352u + (idx * 544u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_4((384u + (idx * 544u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_3((448u + (idx * 544u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  float3 v_12[2] = (float3[2])0;
-  v((512u + (idx * 544u)), v_12);
+  uint v_12 = 0u;
+  sb.GetDimensions(v_12);
+  sb.Store((0u + (min(idx, ((v_12 / 544u) - 1u)) * 544u)), asuint(0.0f));
+  uint v_13 = 0u;
+  sb.GetDimensions(v_13);
+  sb.Store((4u + (min(idx, ((v_13 / 544u) - 1u)) * 544u)), asuint(int(0)));
+  uint v_14 = 0u;
+  sb.GetDimensions(v_14);
+  sb.Store((8u + (min(idx, ((v_14 / 544u) - 1u)) * 544u)), 0u);
+  uint v_15 = 0u;
+  sb.GetDimensions(v_15);
+  sb.Store2((16u + (min(idx, ((v_15 / 544u) - 1u)) * 544u)), asuint((0.0f).xx));
+  uint v_16 = 0u;
+  sb.GetDimensions(v_16);
+  uint v_17 = (24u + (min(idx, ((v_16 / 544u) - 1u)) * 544u));
+  sb.Store2(v_17, asuint(int2((int(0)).xx)));
+  uint v_18 = 0u;
+  sb.GetDimensions(v_18);
+  sb.Store2((32u + (min(idx, ((v_18 / 544u) - 1u)) * 544u)), (0u).xx);
+  uint v_19 = 0u;
+  sb.GetDimensions(v_19);
+  sb.Store3((48u + (min(idx, ((v_19 / 544u) - 1u)) * 544u)), asuint((0.0f).xxx));
+  uint v_20 = 0u;
+  sb.GetDimensions(v_20);
+  uint v_21 = (64u + (min(idx, ((v_20 / 544u) - 1u)) * 544u));
+  sb.Store3(v_21, asuint(int3((int(0)).xxx)));
+  uint v_22 = 0u;
+  sb.GetDimensions(v_22);
+  sb.Store3((80u + (min(idx, ((v_22 / 544u) - 1u)) * 544u)), (0u).xxx);
+  uint v_23 = 0u;
+  sb.GetDimensions(v_23);
+  sb.Store4((96u + (min(idx, ((v_23 / 544u) - 1u)) * 544u)), asuint((0.0f).xxxx));
+  uint v_24 = 0u;
+  sb.GetDimensions(v_24);
+  uint v_25 = (112u + (min(idx, ((v_24 / 544u) - 1u)) * 544u));
+  sb.Store4(v_25, asuint(int4((int(0)).xxxx)));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  sb.Store4((128u + (min(idx, ((v_26 / 544u) - 1u)) * 544u)), (0u).xxxx);
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  v_11((144u + (min(idx, ((v_27 / 544u) - 1u)) * 544u)), float2x2((0.0f).xx, (0.0f).xx));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  v_10((160u + (min(idx, ((v_28 / 544u) - 1u)) * 544u)), float2x3((0.0f).xxx, (0.0f).xxx));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  v_9((192u + (min(idx, ((v_29 / 544u) - 1u)) * 544u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  uint v_30 = 0u;
+  sb.GetDimensions(v_30);
+  v_8((224u + (min(idx, ((v_30 / 544u) - 1u)) * 544u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  v_7((256u + (min(idx, ((v_31 / 544u) - 1u)) * 544u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  v_6((304u + (min(idx, ((v_32 / 544u) - 1u)) * 544u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  v_5((352u + (min(idx, ((v_33 / 544u) - 1u)) * 544u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  v_4((384u + (min(idx, ((v_34 / 544u) - 1u)) * 544u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_35 = 0u;
+  sb.GetDimensions(v_35);
+  v_3((448u + (min(idx, ((v_35 / 544u) - 1u)) * 544u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_36 = 0u;
+  sb.GetDimensions(v_36);
+  float3 v_37[2] = (float3[2])0;
+  v((512u + (min(idx, ((v_36 / 544u) - 1u)) * 544u)), v_37);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.msl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.msl
index 3d7a05d..8f30e04 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Inner_packed_vec3 {
   /* 0x0000 */ float scalar_f32;
   /* 0x0004 */ int scalar_i32;
@@ -55,6 +58,7 @@
 
 struct tint_module_vars_struct {
   device S_packed_vec3* sb;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_store_and_preserve_padding_3(device tint_array<tint_packed_vec3_f32_array_element, 2>* const target, tint_array<float3, 2> value_param) {
@@ -62,6 +66,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 2u)) {
         break;
@@ -94,31 +99,34 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.sb).arr[idx].scalar_f32 = 0.0f;
-  (*tint_module_vars.sb).arr[idx].scalar_i32 = 0;
-  (*tint_module_vars.sb).arr[idx].scalar_u32 = 0u;
-  (*tint_module_vars.sb).arr[idx].vec2_f32 = float2(0.0f);
-  (*tint_module_vars.sb).arr[idx].vec2_i32 = int2(0);
-  (*tint_module_vars.sb).arr[idx].vec2_u32 = uint2(0u);
-  (*tint_module_vars.sb).arr[idx].vec3_f32 = packed_float3(float3(0.0f));
-  (*tint_module_vars.sb).arr[idx].vec3_i32 = packed_int3(int3(0));
-  (*tint_module_vars.sb).arr[idx].vec3_u32 = packed_uint3(uint3(0u));
-  (*tint_module_vars.sb).arr[idx].vec4_f32 = float4(0.0f);
-  (*tint_module_vars.sb).arr[idx].vec4_i32 = int4(0);
-  (*tint_module_vars.sb).arr[idx].vec4_u32 = uint4(0u);
-  (*tint_module_vars.sb).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding((&(*tint_module_vars.sb).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
-  (*tint_module_vars.sb).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.sb).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
-  (*tint_module_vars.sb).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.sb).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
-  tint_store_and_preserve_padding_3((&(*tint_module_vars.sb).arr[idx].arr2_vec3_f32), tint_array<float3, 2>{});
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_f32 = 0.0f;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_i32 = 0;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].scalar_u32 = 0u;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_f32 = float2(0.0f);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_i32 = int2(0);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec2_u32 = uint2(0u);
+  device packed_float3* const v_2 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_f32);
+  (*v_2) = packed_float3(float3(0.0f));
+  device packed_int3* const v_3 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_i32);
+  (*v_3) = packed_int3(int3(0));
+  device packed_uint3* const v_4 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec3_u32);
+  (*v_4) = packed_uint3(uint3(0u));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_f32 = float4(0.0f);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_i32 = int4(0);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].vec4_u32 = uint4(0u);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
+  tint_store_and_preserve_padding_3((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 544u) - 1u))].arr2_vec3_f32), tint_array<float3, 2>{});
 }
 
-kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], device S_packed_vec3* sb [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb};
+kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], device S_packed_vec3* sb [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(idx, tint_module_vars);
 }
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
index c71462e..0b8f625 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -54,6 +57,10 @@
   /* 0x0000 */ tint_array<Inner_tint_packed_vec3, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Inner {
   float scalar_f32;
   int scalar_i32;
@@ -103,38 +110,39 @@
 
 void assign_and_preserve_padding_3(device tint_array<tint_packed_vec3_f32_array_element, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    (*(dest))[i].elements = packed_float3(value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(dest))[min(i, 1u)].elements = packed_float3(value[min(i, 1u)]);
   }
 }
 
-void tint_symbol_inner(uint idx, device S_tint_packed_vec3* const tint_symbol_2) {
-  (*(tint_symbol_2)).arr[idx].scalar_f32 = 0.0f;
-  (*(tint_symbol_2)).arr[idx].scalar_i32 = 0;
-  (*(tint_symbol_2)).arr[idx].scalar_u32 = 0u;
-  (*(tint_symbol_2)).arr[idx].vec2_f32 = float2(0.0f);
-  (*(tint_symbol_2)).arr[idx].vec2_i32 = int2(0);
-  (*(tint_symbol_2)).arr[idx].vec2_u32 = uint2(0u);
-  (*(tint_symbol_2)).arr[idx].vec3_f32 = packed_float3(0.0f);
-  (*(tint_symbol_2)).arr[idx].vec3_i32 = packed_int3(0);
-  (*(tint_symbol_2)).arr[idx].vec3_u32 = packed_uint3(0u);
-  (*(tint_symbol_2)).arr[idx].vec4_f32 = float4(0.0f);
-  (*(tint_symbol_2)).arr[idx].vec4_i32 = int4(0);
-  (*(tint_symbol_2)).arr[idx].vec4_u32 = uint4(0u);
-  (*(tint_symbol_2)).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding(&((*(tint_symbol_2)).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_2)).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
-  (*(tint_symbol_2)).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding_1(&((*(tint_symbol_2)).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_2)).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
-  (*(tint_symbol_2)).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding_2(&((*(tint_symbol_2)).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_2)).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
+void tint_symbol_inner(uint idx, device S_tint_packed_vec3* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_f32 = 0.0f;
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_i32 = 0;
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].scalar_u32 = 0u;
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_f32 = float2(0.0f);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_i32 = int2(0);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec2_u32 = uint2(0u);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_f32 = packed_float3(0.0f);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_i32 = packed_int3(0);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec3_u32 = packed_uint3(0u);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_f32 = float4(0.0f);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_i32 = int4(0);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].vec4_u32 = uint4(0u);
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding_3(&((*(tint_symbol_2)).arr[idx].arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_3(&((*(tint_symbol_2)).arr[min(idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 544u) - 1u))].arr2_vec3_f32), tint_symbol_1);
 }
 
-kernel void tint_symbol(device S_tint_packed_vec3* tint_symbol_3 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
-  tint_symbol_inner(idx, tint_symbol_3);
+kernel void tint_symbol(device S_tint_packed_vec3* tint_symbol_4 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]], uint idx [[thread_index_in_threadgroup]]) {
+  tint_symbol_inner(idx, tint_symbol_4, tint_symbol_5);
   return;
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
index a1f84f5..2ff52f6 100644
--- a/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/write.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 187
+; Bound: 277
 ; Schema: 0
                OpCapability Shader
+         %43 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -130,207 +131,296 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %34 = OpTypeFunction %void %uint
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_Inner = OpTypePointer StorageBuffer %_runtimearr_Inner
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
     %float_0 = OpConstant %float 0
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-     %uint_1 = OpConstant %uint 1
       %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
      %uint_3 = OpConstant %uint 3
-         %49 = OpConstantNull %v2float
+         %67 = OpConstantNull %v2float
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
      %uint_4 = OpConstant %uint 4
-         %53 = OpConstantNull %v2int
+         %75 = OpConstantNull %v2int
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_5 = OpConstant %uint 5
-         %57 = OpConstantNull %v2uint
+         %83 = OpConstantNull %v2uint
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
      %uint_6 = OpConstant %uint 6
-         %61 = OpConstantNull %v3float
+         %91 = OpConstantNull %v3float
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
      %uint_7 = OpConstant %uint 7
-         %65 = OpConstantNull %v3int
+         %99 = OpConstantNull %v3int
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_8 = OpConstant %uint 8
-         %69 = OpConstantNull %v3uint
+        %107 = OpConstantNull %v3uint
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_9 = OpConstant %uint 9
-         %73 = OpConstantNull %v4float
+        %115 = OpConstantNull %v4float
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
     %uint_10 = OpConstant %uint 10
-         %77 = OpConstantNull %v4int
+        %123 = OpConstantNull %v4int
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
     %uint_11 = OpConstant %uint 11
-         %81 = OpConstantNull %v4uint
+        %131 = OpConstantNull %v4uint
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
     %uint_12 = OpConstant %uint 12
-         %85 = OpConstantNull %mat2v2float
+        %139 = OpConstantNull %mat2v2float
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-         %90 = OpConstantNull %mat2v3float
+        %148 = OpConstantNull %mat2v3float
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
     %uint_14 = OpConstant %uint 14
-         %94 = OpConstantNull %mat2v4float
+        %156 = OpConstantNull %mat2v4float
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
     %uint_15 = OpConstant %uint 15
-         %98 = OpConstantNull %mat3v2float
-        %102 = OpConstantNull %mat3v3float
+        %164 = OpConstantNull %mat3v2float
+        %172 = OpConstantNull %mat3v3float
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
     %uint_17 = OpConstant %uint 17
-        %106 = OpConstantNull %mat3v4float
+        %180 = OpConstantNull %mat3v4float
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
     %uint_18 = OpConstant %uint 18
-        %110 = OpConstantNull %mat4v2float
-        %114 = OpConstantNull %mat4v3float
+        %188 = OpConstantNull %mat4v2float
+        %196 = OpConstantNull %mat4v3float
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
     %uint_20 = OpConstant %uint 20
-        %118 = OpConstantNull %mat4v4float
-        %122 = OpConstantNull %_arr_v3float_uint_2
-        %125 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+        %204 = OpConstantNull %mat4v4float
+        %212 = OpConstantNull %_arr_v3float_uint_2
+        %215 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
     %uint_13 = OpConstant %uint 13
-        %135 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+        %225 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
     %uint_16 = OpConstant %uint 16
-        %147 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+        %237 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
     %uint_19 = OpConstant %uint 19
-        %161 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
+        %251 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
        %bool = OpTypeBool
     %uint_21 = OpConstant %uint 21
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %183 = OpTypeFunction %void
+        %273 = OpTypeFunction %void
  %main_inner = OpFunction %void None %34
         %idx = OpFunctionParameter %uint
          %35 = OpLabel
-         %36 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
-               OpStore %36 %float_0 None
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
-               OpStore %40 %int_0 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
-               OpStore %44 %uint_0 None
-         %46 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_3
-               OpStore %46 %49 None
-         %50 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_4
-               OpStore %50 %53 None
-         %54 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_5
-               OpStore %54 %57 None
-         %58 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_6
-               OpStore %58 %61 None
-         %62 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_7
-               OpStore %62 %65 None
-         %66 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_8
-               OpStore %66 %69 None
-         %70 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_9
-               OpStore %70 %73 None
-         %74 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_10
-               OpStore %74 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_11
-               OpStore %78 %81 None
-         %82 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_12
-               OpStore %82 %85 None
-         %87 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-         %88 = OpFunctionCall %void %tint_store_and_preserve_padding %87 %90
-         %91 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_14
-               OpStore %91 %94 None
-         %95 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_15
-               OpStore %95 %98 None
-         %99 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %100 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %99 %102
-        %103 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_17
-               OpStore %103 %106 None
-        %107 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_18
-               OpStore %107 %110 None
-        %111 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %112 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %111 %114
-        %115 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_20
-               OpStore %115 %118 None
-        %119 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %120 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %119 %122
+         %36 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %39 = OpArrayLength %uint %sb 0
+         %40 = OpISub %uint %39 %uint_1
+         %42 = OpExtInst %uint %43 UMin %idx %40
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %42 %uint_0
+               OpStore %44 %float_0 None
+         %47 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %48 = OpArrayLength %uint %sb 0
+         %49 = OpISub %uint %48 %uint_1
+         %50 = OpExtInst %uint %43 UMin %idx %49
+         %51 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %50 %uint_1
+               OpStore %51 %int_0 None
+         %54 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %55 = OpArrayLength %uint %sb 0
+         %56 = OpISub %uint %55 %uint_1
+         %57 = OpExtInst %uint %43 UMin %idx %56
+         %58 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %57 %uint_2
+               OpStore %58 %uint_0 None
+         %60 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %61 = OpArrayLength %uint %sb 0
+         %62 = OpISub %uint %61 %uint_1
+         %63 = OpExtInst %uint %43 UMin %idx %62
+         %64 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %63 %uint_3
+               OpStore %64 %67 None
+         %68 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %69 = OpArrayLength %uint %sb 0
+         %70 = OpISub %uint %69 %uint_1
+         %71 = OpExtInst %uint %43 UMin %idx %70
+         %72 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %71 %uint_4
+               OpStore %72 %75 None
+         %76 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %77 = OpArrayLength %uint %sb 0
+         %78 = OpISub %uint %77 %uint_1
+         %79 = OpExtInst %uint %43 UMin %idx %78
+         %80 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %79 %uint_5
+               OpStore %80 %83 None
+         %84 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %85 = OpArrayLength %uint %sb 0
+         %86 = OpISub %uint %85 %uint_1
+         %87 = OpExtInst %uint %43 UMin %idx %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %87 %uint_6
+               OpStore %88 %91 None
+         %92 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %93 = OpArrayLength %uint %sb 0
+         %94 = OpISub %uint %93 %uint_1
+         %95 = OpExtInst %uint %43 UMin %idx %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %95 %uint_7
+               OpStore %96 %99 None
+        %100 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %101 = OpArrayLength %uint %sb 0
+        %102 = OpISub %uint %101 %uint_1
+        %103 = OpExtInst %uint %43 UMin %idx %102
+        %104 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %103 %uint_8
+               OpStore %104 %107 None
+        %108 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %109 = OpArrayLength %uint %sb 0
+        %110 = OpISub %uint %109 %uint_1
+        %111 = OpExtInst %uint %43 UMin %idx %110
+        %112 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %111 %uint_9
+               OpStore %112 %115 None
+        %116 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %117 = OpArrayLength %uint %sb 0
+        %118 = OpISub %uint %117 %uint_1
+        %119 = OpExtInst %uint %43 UMin %idx %118
+        %120 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %119 %uint_10
+               OpStore %120 %123 None
+        %124 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %125 = OpArrayLength %uint %sb 0
+        %126 = OpISub %uint %125 %uint_1
+        %127 = OpExtInst %uint %43 UMin %idx %126
+        %128 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %127 %uint_11
+               OpStore %128 %131 None
+        %132 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %133 = OpArrayLength %uint %sb 0
+        %134 = OpISub %uint %133 %uint_1
+        %135 = OpExtInst %uint %43 UMin %idx %134
+        %136 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %135 %uint_12
+               OpStore %136 %139 None
+        %140 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %141 = OpArrayLength %uint %sb 0
+        %142 = OpISub %uint %141 %uint_1
+        %143 = OpExtInst %uint %43 UMin %idx %142
+        %145 = OpCompositeConstruct %_arr_uint_uint_1 %143
+        %146 = OpFunctionCall %void %tint_store_and_preserve_padding %145 %148
+        %149 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %150 = OpArrayLength %uint %sb 0
+        %151 = OpISub %uint %150 %uint_1
+        %152 = OpExtInst %uint %43 UMin %idx %151
+        %153 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %152 %uint_14
+               OpStore %153 %156 None
+        %157 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %158 = OpArrayLength %uint %sb 0
+        %159 = OpISub %uint %158 %uint_1
+        %160 = OpExtInst %uint %43 UMin %idx %159
+        %161 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %160 %uint_15
+               OpStore %161 %164 None
+        %165 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %166 = OpArrayLength %uint %sb 0
+        %167 = OpISub %uint %166 %uint_1
+        %168 = OpExtInst %uint %43 UMin %idx %167
+        %169 = OpCompositeConstruct %_arr_uint_uint_1 %168
+        %170 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %169 %172
+        %173 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %174 = OpArrayLength %uint %sb 0
+        %175 = OpISub %uint %174 %uint_1
+        %176 = OpExtInst %uint %43 UMin %idx %175
+        %177 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %176 %uint_17
+               OpStore %177 %180 None
+        %181 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %182 = OpArrayLength %uint %sb 0
+        %183 = OpISub %uint %182 %uint_1
+        %184 = OpExtInst %uint %43 UMin %idx %183
+        %185 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %184 %uint_18
+               OpStore %185 %188 None
+        %189 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %190 = OpArrayLength %uint %sb 0
+        %191 = OpISub %uint %190 %uint_1
+        %192 = OpExtInst %uint %43 UMin %idx %191
+        %193 = OpCompositeConstruct %_arr_uint_uint_1 %192
+        %194 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %193 %196
+        %197 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %198 = OpArrayLength %uint %sb 0
+        %199 = OpISub %uint %198 %uint_1
+        %200 = OpExtInst %uint %43 UMin %idx %199
+        %201 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %200 %uint_20
+               OpStore %201 %204 None
+        %205 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %206 = OpArrayLength %uint %sb 0
+        %207 = OpISub %uint %206 %uint_1
+        %208 = OpExtInst %uint %43 UMin %idx %207
+        %209 = OpCompositeConstruct %_arr_uint_uint_1 %208
+        %210 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %209 %212
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %125
+%tint_store_and_preserve_padding = OpFunction %void None %215
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param = OpFunctionParameter %mat2v3float
-        %126 = OpLabel
-        %127 = OpCompositeExtract %uint %target_indices 0
-        %128 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %127 %uint_13 %uint_0
-        %130 = OpCompositeExtract %v3float %value_param 0
-               OpStore %128 %130 None
-        %131 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %127 %uint_13 %uint_1
-        %132 = OpCompositeExtract %v3float %value_param 1
-               OpStore %131 %132 None
+        %216 = OpLabel
+        %217 = OpCompositeExtract %uint %target_indices 0
+        %218 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %217 %uint_13 %uint_0
+        %220 = OpCompositeExtract %v3float %value_param 0
+               OpStore %218 %220 None
+        %221 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %217 %uint_13 %uint_1
+        %222 = OpCompositeExtract %v3float %value_param 1
+               OpStore %221 %222 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %135
+%tint_store_and_preserve_padding_0 = OpFunction %void None %225
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat3v3float
-        %136 = OpLabel
-        %137 = OpCompositeExtract %uint %target_indices_0 0
-        %138 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %137 %uint_16 %uint_0
-        %140 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %138 %140 None
-        %141 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %137 %uint_16 %uint_1
-        %142 = OpCompositeExtract %v3float %value_param_0 1
-               OpStore %141 %142 None
-        %143 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %137 %uint_16 %uint_2
-        %144 = OpCompositeExtract %v3float %value_param_0 2
-               OpStore %143 %144 None
+        %226 = OpLabel
+        %227 = OpCompositeExtract %uint %target_indices_0 0
+        %228 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %227 %uint_16 %uint_0
+        %230 = OpCompositeExtract %v3float %value_param_0 0
+               OpStore %228 %230 None
+        %231 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %227 %uint_16 %uint_1
+        %232 = OpCompositeExtract %v3float %value_param_0 1
+               OpStore %231 %232 None
+        %233 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %227 %uint_16 %uint_2
+        %234 = OpCompositeExtract %v3float %value_param_0 2
+               OpStore %233 %234 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %147
+%tint_store_and_preserve_padding_1 = OpFunction %void None %237
 %target_indices_1 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat4v3float
-        %148 = OpLabel
-        %149 = OpCompositeExtract %uint %target_indices_1 0
-        %150 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %149 %uint_19 %uint_0
-        %152 = OpCompositeExtract %v3float %value_param_1 0
-               OpStore %150 %152 None
-        %153 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %149 %uint_19 %uint_1
-        %154 = OpCompositeExtract %v3float %value_param_1 1
-               OpStore %153 %154 None
-        %155 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %149 %uint_19 %uint_2
-        %156 = OpCompositeExtract %v3float %value_param_1 2
-               OpStore %155 %156 None
-        %157 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %149 %uint_19 %uint_3
-        %158 = OpCompositeExtract %v3float %value_param_1 3
-               OpStore %157 %158 None
+        %238 = OpLabel
+        %239 = OpCompositeExtract %uint %target_indices_1 0
+        %240 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %239 %uint_19 %uint_0
+        %242 = OpCompositeExtract %v3float %value_param_1 0
+               OpStore %240 %242 None
+        %243 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %239 %uint_19 %uint_1
+        %244 = OpCompositeExtract %v3float %value_param_1 1
+               OpStore %243 %244 None
+        %245 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %239 %uint_19 %uint_2
+        %246 = OpCompositeExtract %v3float %value_param_1 2
+               OpStore %245 %246 None
+        %247 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %239 %uint_19 %uint_3
+        %248 = OpCompositeExtract %v3float %value_param_1 3
+               OpStore %247 %248 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_2 = OpFunction %void None %161
+%tint_store_and_preserve_padding_2 = OpFunction %void None %251
 %target_indices_2 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_2 = OpFunctionParameter %_arr_v3float_uint_2
-        %162 = OpLabel
-        %163 = OpVariable %_ptr_Function__arr_v3float_uint_2 Function
-               OpStore %163 %value_param_2
-        %165 = OpCompositeExtract %uint %target_indices_2 0
-               OpBranch %166
-        %166 = OpLabel
-               OpBranch %169
-        %169 = OpLabel
-        %171 = OpPhi %uint %uint_0 %166 %172 %168
-               OpLoopMerge %170 %168 None
-               OpBranch %167
-        %167 = OpLabel
-        %173 = OpUGreaterThanEqual %bool %171 %uint_2
-               OpSelectionMerge %175 None
-               OpBranchConditional %173 %176 %175
-        %176 = OpLabel
-               OpBranch %170
-        %175 = OpLabel
-        %177 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %165 %uint_21 %171
-        %179 = OpAccessChain %_ptr_Function_v3float %163 %171
-        %181 = OpLoad %v3float %179 None
-               OpStore %177 %181 None
-               OpBranch %168
-        %168 = OpLabel
-        %172 = OpIAdd %uint %171 %uint_1
-               OpBranch %169
-        %170 = OpLabel
+        %252 = OpLabel
+        %253 = OpVariable %_ptr_Function__arr_v3float_uint_2 Function
+               OpStore %253 %value_param_2
+        %255 = OpCompositeExtract %uint %target_indices_2 0
+               OpBranch %256
+        %256 = OpLabel
+               OpBranch %259
+        %259 = OpLabel
+        %261 = OpPhi %uint %uint_0 %256 %262 %258
+               OpLoopMerge %260 %258 None
+               OpBranch %257
+        %257 = OpLabel
+        %263 = OpUGreaterThanEqual %bool %261 %uint_2
+               OpSelectionMerge %265 None
+               OpBranchConditional %263 %266 %265
+        %266 = OpLabel
+               OpBranch %260
+        %265 = OpLabel
+        %267 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %255 %uint_21 %261
+        %269 = OpAccessChain %_ptr_Function_v3float %253 %261
+        %271 = OpLoad %v3float %269 None
+               OpStore %267 %271 None
+               OpBranch %258
+        %258 = OpLabel
+        %262 = OpIAdd %uint %261 %uint_1
+               OpBranch %259
+        %260 = OpLabel
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %183
-        %184 = OpLabel
-        %185 = OpLoad %uint %main_local_invocation_index_Input None
-        %186 = OpFunctionCall %void %main_inner %185
+       %main = OpFunction %void None %273
+        %274 = OpLabel
+        %275 = OpLoad %uint %main_local_invocation_index_Input None
+        %276 = OpFunctionCall %void %main_inner %275
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.dxc.hlsl
index 38a7f03..3a819e2 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.dxc.hlsl
@@ -131,44 +131,47 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((800u * idx), asuint(0.0f));
-  sb.Store(((800u * idx) + 4u), asuint(0));
-  sb.Store(((800u * idx) + 8u), asuint(0u));
-  sb.Store<float16_t>(((800u * idx) + 12u), float16_t(0.0h));
-  sb.Store2(((800u * idx) + 16u), asuint((0.0f).xx));
-  sb.Store2(((800u * idx) + 24u), asuint(int2((0).xx)));
-  sb.Store2(((800u * idx) + 32u), asuint((0u).xx));
-  sb.Store<vector<float16_t, 2> >(((800u * idx) + 40u), (float16_t(0.0h)).xx);
-  sb.Store3(((800u * idx) + 48u), asuint((0.0f).xxx));
-  sb.Store3(((800u * idx) + 64u), asuint(int3((0).xxx)));
-  sb.Store3(((800u * idx) + 80u), asuint((0u).xxx));
-  sb.Store<vector<float16_t, 3> >(((800u * idx) + 96u), (float16_t(0.0h)).xxx);
-  sb.Store4(((800u * idx) + 112u), asuint((0.0f).xxxx));
-  sb.Store4(((800u * idx) + 128u), asuint(int4((0).xxxx)));
-  sb.Store4(((800u * idx) + 144u), asuint((0u).xxxx));
-  sb.Store<vector<float16_t, 4> >(((800u * idx) + 160u), (float16_t(0.0h)).xxxx);
-  sb_store_16(((800u * idx) + 168u), float2x2((0.0f).xx, (0.0f).xx));
-  sb_store_17(((800u * idx) + 192u), float2x3((0.0f).xxx, (0.0f).xxx));
-  sb_store_18(((800u * idx) + 224u), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  sb_store_19(((800u * idx) + 256u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_20(((800u * idx) + 288u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_21(((800u * idx) + 336u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  sb_store_22(((800u * idx) + 384u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  sb_store_23(((800u * idx) + 416u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  sb_store_24(((800u * idx) + 480u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  sb_store_25(((800u * idx) + 544u), matrix<float16_t, 2, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  sb_store_26(((800u * idx) + 552u), matrix<float16_t, 2, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  sb_store_27(((800u * idx) + 568u), matrix<float16_t, 2, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  sb_store_28(((800u * idx) + 584u), matrix<float16_t, 3, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  sb_store_29(((800u * idx) + 600u), matrix<float16_t, 3, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  sb_store_30(((800u * idx) + 624u), matrix<float16_t, 3, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  sb_store_31(((800u * idx) + 648u), matrix<float16_t, 4, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  sb_store_32(((800u * idx) + 664u), matrix<float16_t, 4, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  sb_store_33(((800u * idx) + 696u), matrix<float16_t, 4, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  float3 tint_symbol_2[2] = (float3[2])0;
-  sb_store_34(((800u * idx) + 736u), tint_symbol_2);
-  matrix<float16_t, 4, 2> tint_symbol_3[2] = (matrix<float16_t, 4, 2>[2])0;
-  sb_store_35(((800u * idx) + 768u), tint_symbol_3);
+  uint tint_symbol_3 = 0u;
+  sb.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 800u);
+  sb.Store((800u * min(idx, (tint_symbol_4 - 1u))), asuint(0.0f));
+  sb.Store(((800u * min(idx, (tint_symbol_4 - 1u))) + 4u), asuint(0));
+  sb.Store(((800u * min(idx, (tint_symbol_4 - 1u))) + 8u), asuint(0u));
+  sb.Store<float16_t>(((800u * min(idx, (tint_symbol_4 - 1u))) + 12u), float16_t(0.0h));
+  sb.Store2(((800u * min(idx, (tint_symbol_4 - 1u))) + 16u), asuint((0.0f).xx));
+  sb.Store2(((800u * min(idx, (tint_symbol_4 - 1u))) + 24u), asuint(int2((0).xx)));
+  sb.Store2(((800u * min(idx, (tint_symbol_4 - 1u))) + 32u), asuint((0u).xx));
+  sb.Store<vector<float16_t, 2> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 40u), (float16_t(0.0h)).xx);
+  sb.Store3(((800u * min(idx, (tint_symbol_4 - 1u))) + 48u), asuint((0.0f).xxx));
+  sb.Store3(((800u * min(idx, (tint_symbol_4 - 1u))) + 64u), asuint(int3((0).xxx)));
+  sb.Store3(((800u * min(idx, (tint_symbol_4 - 1u))) + 80u), asuint((0u).xxx));
+  sb.Store<vector<float16_t, 3> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 96u), (float16_t(0.0h)).xxx);
+  sb.Store4(((800u * min(idx, (tint_symbol_4 - 1u))) + 112u), asuint((0.0f).xxxx));
+  sb.Store4(((800u * min(idx, (tint_symbol_4 - 1u))) + 128u), asuint(int4((0).xxxx)));
+  sb.Store4(((800u * min(idx, (tint_symbol_4 - 1u))) + 144u), asuint((0u).xxxx));
+  sb.Store<vector<float16_t, 4> >(((800u * min(idx, (tint_symbol_4 - 1u))) + 160u), (float16_t(0.0h)).xxxx);
+  sb_store_16(((800u * min(idx, (tint_symbol_4 - 1u))) + 168u), float2x2((0.0f).xx, (0.0f).xx));
+  sb_store_17(((800u * min(idx, (tint_symbol_4 - 1u))) + 192u), float2x3((0.0f).xxx, (0.0f).xxx));
+  sb_store_18(((800u * min(idx, (tint_symbol_4 - 1u))) + 224u), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  sb_store_19(((800u * min(idx, (tint_symbol_4 - 1u))) + 256u), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_20(((800u * min(idx, (tint_symbol_4 - 1u))) + 288u), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_21(((800u * min(idx, (tint_symbol_4 - 1u))) + 336u), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  sb_store_22(((800u * min(idx, (tint_symbol_4 - 1u))) + 384u), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  sb_store_23(((800u * min(idx, (tint_symbol_4 - 1u))) + 416u), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  sb_store_24(((800u * min(idx, (tint_symbol_4 - 1u))) + 480u), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  sb_store_25(((800u * min(idx, (tint_symbol_4 - 1u))) + 544u), matrix<float16_t, 2, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  sb_store_26(((800u * min(idx, (tint_symbol_4 - 1u))) + 552u), matrix<float16_t, 2, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  sb_store_27(((800u * min(idx, (tint_symbol_4 - 1u))) + 568u), matrix<float16_t, 2, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  sb_store_28(((800u * min(idx, (tint_symbol_4 - 1u))) + 584u), matrix<float16_t, 3, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  sb_store_29(((800u * min(idx, (tint_symbol_4 - 1u))) + 600u), matrix<float16_t, 3, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  sb_store_30(((800u * min(idx, (tint_symbol_4 - 1u))) + 624u), matrix<float16_t, 3, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  sb_store_31(((800u * min(idx, (tint_symbol_4 - 1u))) + 648u), matrix<float16_t, 4, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  sb_store_32(((800u * min(idx, (tint_symbol_4 - 1u))) + 664u), matrix<float16_t, 4, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  sb_store_33(((800u * min(idx, (tint_symbol_4 - 1u))) + 696u), matrix<float16_t, 4, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  float3 tint_symbol_5[2] = (float3[2])0;
+  sb_store_34(((800u * min(idx, (tint_symbol_4 - 1u))) + 736u), tint_symbol_5);
+  matrix<float16_t, 4, 2> tint_symbol_6[2] = (matrix<float16_t, 4, 2>[2])0;
+  sb_store_35(((800u * min(idx, (tint_symbol_4 - 1u))) + 768u), tint_symbol_6);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
index 4e67ebd..d36c070 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.glsl
@@ -106,42 +106,71 @@
   sb.arr[target_indices[0u]].mat2x3_f32[1u] = value_param[1u];
 }
 void tint_symbol_inner(uint idx) {
-  sb.arr[idx].scalar_f32 = 0.0f;
-  sb.arr[idx].scalar_i32 = 0;
-  sb.arr[idx].scalar_u32 = 0u;
-  sb.arr[idx].scalar_f16 = 0.0hf;
-  sb.arr[idx].vec2_f32 = vec2(0.0f);
-  sb.arr[idx].vec2_i32 = ivec2(0);
-  sb.arr[idx].vec2_u32 = uvec2(0u);
-  sb.arr[idx].vec2_f16 = f16vec2(0.0hf);
-  sb.arr[idx].vec3_f32 = vec3(0.0f);
-  sb.arr[idx].vec3_i32 = ivec3(0);
-  sb.arr[idx].vec3_u32 = uvec3(0u);
-  sb.arr[idx].vec3_f16 = f16vec3(0.0hf);
-  sb.arr[idx].vec4_f32 = vec4(0.0f);
-  sb.arr[idx].vec4_i32 = ivec4(0);
-  sb.arr[idx].vec4_u32 = uvec4(0u);
-  sb.arr[idx].vec4_f16 = f16vec4(0.0hf);
-  sb.arr[idx].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding(uint[1](idx), mat2x3(vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
-  sb.arr[idx].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding_1(uint[1](idx), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  sb.arr[idx].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
-  tint_store_and_preserve_padding_2(uint[1](idx), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  sb.arr[idx].mat2x2_f16 = f16mat2(f16vec2(0.0hf), f16vec2(0.0hf));
-  tint_store_and_preserve_padding_3(uint[1](idx), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
-  sb.arr[idx].mat2x4_f16 = f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf));
-  sb.arr[idx].mat3x2_f16 = f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  tint_store_and_preserve_padding_4(uint[1](idx), f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
-  sb.arr[idx].mat3x4_f16 = f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
-  sb.arr[idx].mat4x2_f16 = f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
-  tint_store_and_preserve_padding_5(uint[1](idx), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
-  sb.arr[idx].mat4x4_f16 = f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
-  tint_store_and_preserve_padding_6(uint[1](idx), vec3[2](vec3(0.0f), vec3(0.0f)));
-  sb.arr[idx].arr2_mat4x2_f16 = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
+  uint v_2 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_2].scalar_f32 = 0.0f;
+  uint v_3 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_3].scalar_i32 = 0;
+  uint v_4 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_4].scalar_u32 = 0u;
+  uint v_5 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_5].scalar_f16 = 0.0hf;
+  uint v_6 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_6].vec2_f32 = vec2(0.0f);
+  uint v_7 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_7].vec2_i32 = ivec2(0);
+  uint v_8 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_8].vec2_u32 = uvec2(0u);
+  uint v_9 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_9].vec2_f16 = f16vec2(0.0hf);
+  uint v_10 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_10].vec3_f32 = vec3(0.0f);
+  uint v_11 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_11].vec3_i32 = ivec3(0);
+  uint v_12 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_12].vec3_u32 = uvec3(0u);
+  uint v_13 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_13].vec3_f16 = f16vec3(0.0hf);
+  uint v_14 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_14].vec4_f32 = vec4(0.0f);
+  uint v_15 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_15].vec4_i32 = ivec4(0);
+  uint v_16 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_16].vec4_u32 = uvec4(0u);
+  uint v_17 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_17].vec4_f16 = f16vec4(0.0hf);
+  uint v_18 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_18].mat2x2_f32 = mat2(vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat2x3(vec3(0.0f), vec3(0.0f)));
+  uint v_19 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_19].mat2x4_f32 = mat2x4(vec4(0.0f), vec4(0.0f));
+  uint v_20 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_20].mat3x2_f32 = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding_1(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
+  uint v_21 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_21].mat3x4_f32 = mat3x4(vec4(0.0f), vec4(0.0f), vec4(0.0f));
+  uint v_22 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_22].mat4x2_f32 = mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f));
+  tint_store_and_preserve_padding_2(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
+  uint v_23 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_23].mat4x4_f32 = mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
+  uint v_24 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_24].mat2x2_f16 = f16mat2(f16vec2(0.0hf), f16vec2(0.0hf));
+  tint_store_and_preserve_padding_3(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
+  uint v_25 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_25].mat2x4_f16 = f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf));
+  uint v_26 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_26].mat3x2_f16 = f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
+  tint_store_and_preserve_padding_4(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
+  uint v_27 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_27].mat3x4_f16 = f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
+  uint v_28 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_28].mat4x2_f16 = f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf));
+  tint_store_and_preserve_padding_5(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
+  uint v_29 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_29].mat4x4_f16 = f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf));
+  tint_store_and_preserve_padding_6(uint[1](min(idx, (uint(sb.arr.length()) - 1u))), vec3[2](vec3(0.0f), vec3(0.0f)));
+  uint v_30 = min(idx, (uint(sb.arr.length()) - 1u));
+  sb.arr[v_30].arr2_mat4x2_f16 = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.dxc.hlsl
index 18469fa..9ed780a 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.dxc.hlsl
@@ -149,44 +149,119 @@
 }
 
 void main_inner(uint idx) {
-  sb.Store((0u + (idx * 800u)), asuint(0.0f));
-  sb.Store((4u + (idx * 800u)), asuint(int(0)));
-  sb.Store((8u + (idx * 800u)), 0u);
-  sb.Store<float16_t>((12u + (idx * 800u)), float16_t(0.0h));
-  sb.Store2((16u + (idx * 800u)), asuint((0.0f).xx));
-  sb.Store2((24u + (idx * 800u)), asuint(int2((int(0)).xx)));
-  sb.Store2((32u + (idx * 800u)), (0u).xx);
-  sb.Store<vector<float16_t, 2> >((40u + (idx * 800u)), (float16_t(0.0h)).xx);
-  sb.Store3((48u + (idx * 800u)), asuint((0.0f).xxx));
-  sb.Store3((64u + (idx * 800u)), asuint(int3((int(0)).xxx)));
-  sb.Store3((80u + (idx * 800u)), (0u).xxx);
-  sb.Store<vector<float16_t, 3> >((96u + (idx * 800u)), (float16_t(0.0h)).xxx);
-  sb.Store4((112u + (idx * 800u)), asuint((0.0f).xxxx));
-  sb.Store4((128u + (idx * 800u)), asuint(int4((int(0)).xxxx)));
-  sb.Store4((144u + (idx * 800u)), (0u).xxxx);
-  sb.Store<vector<float16_t, 4> >((160u + (idx * 800u)), (float16_t(0.0h)).xxxx);
-  v_23((168u + (idx * 800u)), float2x2((0.0f).xx, (0.0f).xx));
-  v_22((192u + (idx * 800u)), float2x3((0.0f).xxx, (0.0f).xxx));
-  v_21((224u + (idx * 800u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
-  v_20((256u + (idx * 800u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_19((288u + (idx * 800u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_18((336u + (idx * 800u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  v_17((384u + (idx * 800u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
-  v_16((416u + (idx * 800u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
-  v_15((480u + (idx * 800u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
-  v_14((544u + (idx * 800u)), matrix<float16_t, 2, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  v_13((552u + (idx * 800u)), matrix<float16_t, 2, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  v_12((568u + (idx * 800u)), matrix<float16_t, 2, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  v_11((584u + (idx * 800u)), matrix<float16_t, 3, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  v_10((600u + (idx * 800u)), matrix<float16_t, 3, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  v_9((624u + (idx * 800u)), matrix<float16_t, 3, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  v((648u + (idx * 800u)), matrix<float16_t, 4, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
-  v_8((664u + (idx * 800u)), matrix<float16_t, 4, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
-  v_7((696u + (idx * 800u)), matrix<float16_t, 4, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
-  float3 v_24[2] = (float3[2])0;
-  v_4((736u + (idx * 800u)), v_24);
-  matrix<float16_t, 4, 2> v_25[2] = (matrix<float16_t, 4, 2>[2])0;
-  v_1((768u + (idx * 800u)), v_25);
+  uint v_24 = 0u;
+  sb.GetDimensions(v_24);
+  sb.Store((0u + (min(idx, ((v_24 / 800u) - 1u)) * 800u)), asuint(0.0f));
+  uint v_25 = 0u;
+  sb.GetDimensions(v_25);
+  sb.Store((4u + (min(idx, ((v_25 / 800u) - 1u)) * 800u)), asuint(int(0)));
+  uint v_26 = 0u;
+  sb.GetDimensions(v_26);
+  sb.Store((8u + (min(idx, ((v_26 / 800u) - 1u)) * 800u)), 0u);
+  uint v_27 = 0u;
+  sb.GetDimensions(v_27);
+  sb.Store<float16_t>((12u + (min(idx, ((v_27 / 800u) - 1u)) * 800u)), float16_t(0.0h));
+  uint v_28 = 0u;
+  sb.GetDimensions(v_28);
+  sb.Store2((16u + (min(idx, ((v_28 / 800u) - 1u)) * 800u)), asuint((0.0f).xx));
+  uint v_29 = 0u;
+  sb.GetDimensions(v_29);
+  uint v_30 = (24u + (min(idx, ((v_29 / 800u) - 1u)) * 800u));
+  sb.Store2(v_30, asuint(int2((int(0)).xx)));
+  uint v_31 = 0u;
+  sb.GetDimensions(v_31);
+  sb.Store2((32u + (min(idx, ((v_31 / 800u) - 1u)) * 800u)), (0u).xx);
+  uint v_32 = 0u;
+  sb.GetDimensions(v_32);
+  sb.Store<vector<float16_t, 2> >((40u + (min(idx, ((v_32 / 800u) - 1u)) * 800u)), (float16_t(0.0h)).xx);
+  uint v_33 = 0u;
+  sb.GetDimensions(v_33);
+  sb.Store3((48u + (min(idx, ((v_33 / 800u) - 1u)) * 800u)), asuint((0.0f).xxx));
+  uint v_34 = 0u;
+  sb.GetDimensions(v_34);
+  uint v_35 = (64u + (min(idx, ((v_34 / 800u) - 1u)) * 800u));
+  sb.Store3(v_35, asuint(int3((int(0)).xxx)));
+  uint v_36 = 0u;
+  sb.GetDimensions(v_36);
+  sb.Store3((80u + (min(idx, ((v_36 / 800u) - 1u)) * 800u)), (0u).xxx);
+  uint v_37 = 0u;
+  sb.GetDimensions(v_37);
+  sb.Store<vector<float16_t, 3> >((96u + (min(idx, ((v_37 / 800u) - 1u)) * 800u)), (float16_t(0.0h)).xxx);
+  uint v_38 = 0u;
+  sb.GetDimensions(v_38);
+  sb.Store4((112u + (min(idx, ((v_38 / 800u) - 1u)) * 800u)), asuint((0.0f).xxxx));
+  uint v_39 = 0u;
+  sb.GetDimensions(v_39);
+  uint v_40 = (128u + (min(idx, ((v_39 / 800u) - 1u)) * 800u));
+  sb.Store4(v_40, asuint(int4((int(0)).xxxx)));
+  uint v_41 = 0u;
+  sb.GetDimensions(v_41);
+  sb.Store4((144u + (min(idx, ((v_41 / 800u) - 1u)) * 800u)), (0u).xxxx);
+  uint v_42 = 0u;
+  sb.GetDimensions(v_42);
+  sb.Store<vector<float16_t, 4> >((160u + (min(idx, ((v_42 / 800u) - 1u)) * 800u)), (float16_t(0.0h)).xxxx);
+  uint v_43 = 0u;
+  sb.GetDimensions(v_43);
+  v_23((168u + (min(idx, ((v_43 / 800u) - 1u)) * 800u)), float2x2((0.0f).xx, (0.0f).xx));
+  uint v_44 = 0u;
+  sb.GetDimensions(v_44);
+  v_22((192u + (min(idx, ((v_44 / 800u) - 1u)) * 800u)), float2x3((0.0f).xxx, (0.0f).xxx));
+  uint v_45 = 0u;
+  sb.GetDimensions(v_45);
+  v_21((224u + (min(idx, ((v_45 / 800u) - 1u)) * 800u)), float2x4((0.0f).xxxx, (0.0f).xxxx));
+  uint v_46 = 0u;
+  sb.GetDimensions(v_46);
+  v_20((256u + (min(idx, ((v_46 / 800u) - 1u)) * 800u)), float3x2((0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_47 = 0u;
+  sb.GetDimensions(v_47);
+  v_19((288u + (min(idx, ((v_47 / 800u) - 1u)) * 800u)), float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_48 = 0u;
+  sb.GetDimensions(v_48);
+  v_18((336u + (min(idx, ((v_48 / 800u) - 1u)) * 800u)), float3x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_49 = 0u;
+  sb.GetDimensions(v_49);
+  v_17((384u + (min(idx, ((v_49 / 800u) - 1u)) * 800u)), float4x2((0.0f).xx, (0.0f).xx, (0.0f).xx, (0.0f).xx));
+  uint v_50 = 0u;
+  sb.GetDimensions(v_50);
+  v_16((416u + (min(idx, ((v_50 / 800u) - 1u)) * 800u)), float4x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx, (0.0f).xxx));
+  uint v_51 = 0u;
+  sb.GetDimensions(v_51);
+  v_15((480u + (min(idx, ((v_51 / 800u) - 1u)) * 800u)), float4x4((0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx, (0.0f).xxxx));
+  uint v_52 = 0u;
+  sb.GetDimensions(v_52);
+  v_14((544u + (min(idx, ((v_52 / 800u) - 1u)) * 800u)), matrix<float16_t, 2, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  uint v_53 = 0u;
+  sb.GetDimensions(v_53);
+  v_13((552u + (min(idx, ((v_53 / 800u) - 1u)) * 800u)), matrix<float16_t, 2, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  uint v_54 = 0u;
+  sb.GetDimensions(v_54);
+  v_12((568u + (min(idx, ((v_54 / 800u) - 1u)) * 800u)), matrix<float16_t, 2, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  uint v_55 = 0u;
+  sb.GetDimensions(v_55);
+  v_11((584u + (min(idx, ((v_55 / 800u) - 1u)) * 800u)), matrix<float16_t, 3, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  uint v_56 = 0u;
+  sb.GetDimensions(v_56);
+  v_10((600u + (min(idx, ((v_56 / 800u) - 1u)) * 800u)), matrix<float16_t, 3, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  uint v_57 = 0u;
+  sb.GetDimensions(v_57);
+  v_9((624u + (min(idx, ((v_57 / 800u) - 1u)) * 800u)), matrix<float16_t, 3, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  uint v_58 = 0u;
+  sb.GetDimensions(v_58);
+  v((648u + (min(idx, ((v_58 / 800u) - 1u)) * 800u)), matrix<float16_t, 4, 2>((float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx, (float16_t(0.0h)).xx));
+  uint v_59 = 0u;
+  sb.GetDimensions(v_59);
+  v_8((664u + (min(idx, ((v_59 / 800u) - 1u)) * 800u)), matrix<float16_t, 4, 3>((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx));
+  uint v_60 = 0u;
+  sb.GetDimensions(v_60);
+  v_7((696u + (min(idx, ((v_60 / 800u) - 1u)) * 800u)), matrix<float16_t, 4, 4>((float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx, (float16_t(0.0h)).xxxx));
+  uint v_61 = 0u;
+  sb.GetDimensions(v_61);
+  float3 v_62[2] = (float3[2])0;
+  v_4((736u + (min(idx, ((v_61 / 800u) - 1u)) * 800u)), v_62);
+  uint v_63 = 0u;
+  sb.GetDimensions(v_63);
+  matrix<float16_t, 4, 2> v_64[2] = (matrix<float16_t, 4, 2>[2])0;
+  v_1((768u + (min(idx, ((v_63 / 800u) - 1u)) * 800u)), v_64);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.msl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.msl
index e5473dd..ba3dcdd 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 packed_1;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad_1;
@@ -78,6 +81,7 @@
 
 struct tint_module_vars_struct {
   device S_packed_vec3* sb;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_store_and_preserve_padding_6(device tint_array<tint_packed_vec3_f32_array_element, 2>* const target, tint_array<float3, 2> value_param) {
@@ -85,6 +89,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 2u)) {
         break;
@@ -135,45 +140,49 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.sb).arr[idx].scalar_f32 = 0.0f;
-  (*tint_module_vars.sb).arr[idx].scalar_i32 = 0;
-  (*tint_module_vars.sb).arr[idx].scalar_u32 = 0u;
-  (*tint_module_vars.sb).arr[idx].scalar_f16 = 0.0h;
-  (*tint_module_vars.sb).arr[idx].vec2_f32 = float2(0.0f);
-  (*tint_module_vars.sb).arr[idx].vec2_i32 = int2(0);
-  (*tint_module_vars.sb).arr[idx].vec2_u32 = uint2(0u);
-  (*tint_module_vars.sb).arr[idx].vec2_f16 = half2(0.0h);
-  (*tint_module_vars.sb).arr[idx].vec3_f32 = packed_float3(float3(0.0f));
-  (*tint_module_vars.sb).arr[idx].vec3_i32 = packed_int3(int3(0));
-  (*tint_module_vars.sb).arr[idx].vec3_u32 = packed_uint3(uint3(0u));
-  (*tint_module_vars.sb).arr[idx].vec3_f16 = packed_half3(half3(0.0h));
-  (*tint_module_vars.sb).arr[idx].vec4_f32 = float4(0.0f);
-  (*tint_module_vars.sb).arr[idx].vec4_i32 = int4(0);
-  (*tint_module_vars.sb).arr[idx].vec4_u32 = uint4(0u);
-  (*tint_module_vars.sb).arr[idx].vec4_f16 = half4(0.0h);
-  (*tint_module_vars.sb).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding((&(*tint_module_vars.sb).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
-  (*tint_module_vars.sb).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.sb).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
-  (*tint_module_vars.sb).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.sb).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*tint_module_vars.sb).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
-  (*tint_module_vars.sb).arr[idx].mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
-  tint_store_and_preserve_padding_3((&(*tint_module_vars.sb).arr[idx].mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
-  (*tint_module_vars.sb).arr[idx].mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
-  (*tint_module_vars.sb).arr[idx].mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
-  tint_store_and_preserve_padding_4((&(*tint_module_vars.sb).arr[idx].mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
-  (*tint_module_vars.sb).arr[idx].mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
-  (*tint_module_vars.sb).arr[idx].mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
-  tint_store_and_preserve_padding_5((&(*tint_module_vars.sb).arr[idx].mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
-  (*tint_module_vars.sb).arr[idx].mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
-  tint_store_and_preserve_padding_6((&(*tint_module_vars.sb).arr[idx].arr2_vec3_f32), tint_array<float3, 2>{});
-  (*tint_module_vars.sb).arr[idx].arr2_mat4x2_f16 = tint_array<half4x2, 2>{};
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_f32 = 0.0f;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_i32 = 0;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_u32 = 0u;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].scalar_f16 = 0.0h;
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_f32 = float2(0.0f);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_i32 = int2(0);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_u32 = uint2(0u);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec2_f16 = half2(0.0h);
+  device packed_float3* const v_2 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_f32);
+  (*v_2) = packed_float3(float3(0.0f));
+  device packed_int3* const v_3 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_i32);
+  (*v_3) = packed_int3(int3(0));
+  device packed_uint3* const v_4 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_u32);
+  (*v_4) = packed_uint3(uint3(0u));
+  device packed_half3* const v_5 = (&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec3_f16);
+  (*v_5) = packed_half3(half3(0.0h));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_f32 = float4(0.0f);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_i32 = int4(0);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_u32 = uint4(0u);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].vec4_f16 = half4(0.0h);
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
+  tint_store_and_preserve_padding_3((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
+  tint_store_and_preserve_padding_4((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
+  tint_store_and_preserve_padding_5((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
+  tint_store_and_preserve_padding_6((&(*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].arr2_vec3_f32), tint_array<float3, 2>{});
+  (*tint_module_vars.sb).arr[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 800u) - 1u))].arr2_mat4x2_f16 = tint_array<half4x2, 2>{};
 }
 
-kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], device S_packed_vec3* sb [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb};
+kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], device S_packed_vec3* sb [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(idx, tint_module_vars);
 }
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
index b5afec9..bafe021 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -77,6 +80,10 @@
   /* 0x0000 */ tint_array<Inner_tint_packed_vec3, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Inner {
   float scalar_f32;
   int scalar_i32;
@@ -158,53 +165,54 @@
 
 void assign_and_preserve_padding_6(device tint_array<tint_packed_vec3_f32_array_element, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    (*(dest))[i].elements = packed_float3(value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(dest))[min(i, 1u)].elements = packed_float3(value[min(i, 1u)]);
   }
 }
 
-void tint_symbol_inner(uint idx, device S_tint_packed_vec3* const tint_symbol_3) {
-  (*(tint_symbol_3)).arr[idx].scalar_f32 = 0.0f;
-  (*(tint_symbol_3)).arr[idx].scalar_i32 = 0;
-  (*(tint_symbol_3)).arr[idx].scalar_u32 = 0u;
-  (*(tint_symbol_3)).arr[idx].scalar_f16 = 0.0h;
-  (*(tint_symbol_3)).arr[idx].vec2_f32 = float2(0.0f);
-  (*(tint_symbol_3)).arr[idx].vec2_i32 = int2(0);
-  (*(tint_symbol_3)).arr[idx].vec2_u32 = uint2(0u);
-  (*(tint_symbol_3)).arr[idx].vec2_f16 = half2(0.0h);
-  (*(tint_symbol_3)).arr[idx].vec3_f32 = packed_float3(0.0f);
-  (*(tint_symbol_3)).arr[idx].vec3_i32 = packed_int3(0);
-  (*(tint_symbol_3)).arr[idx].vec3_u32 = packed_uint3(0u);
-  (*(tint_symbol_3)).arr[idx].vec3_f16 = packed_half3(0.0h);
-  (*(tint_symbol_3)).arr[idx].vec4_f32 = float4(0.0f);
-  (*(tint_symbol_3)).arr[idx].vec4_i32 = int4(0);
-  (*(tint_symbol_3)).arr[idx].vec4_u32 = uint4(0u);
-  (*(tint_symbol_3)).arr[idx].vec4_f16 = half4(0.0h);
-  (*(tint_symbol_3)).arr[idx].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding(&((*(tint_symbol_3)).arr[idx].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_3)).arr[idx].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding_1(&((*(tint_symbol_3)).arr[idx].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_3)).arr[idx].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
-  assign_and_preserve_padding_2(&((*(tint_symbol_3)).arr[idx].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
-  (*(tint_symbol_3)).arr[idx].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
-  (*(tint_symbol_3)).arr[idx].mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
-  assign_and_preserve_padding_3(&((*(tint_symbol_3)).arr[idx].mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
-  (*(tint_symbol_3)).arr[idx].mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
-  (*(tint_symbol_3)).arr[idx].mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
-  assign_and_preserve_padding_4(&((*(tint_symbol_3)).arr[idx].mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
-  (*(tint_symbol_3)).arr[idx].mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
-  (*(tint_symbol_3)).arr[idx].mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
-  assign_and_preserve_padding_5(&((*(tint_symbol_3)).arr[idx].mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
-  (*(tint_symbol_3)).arr[idx].mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
+void tint_symbol_inner(uint idx, device S_tint_packed_vec3* const tint_symbol_3, const constant TintArrayLengths* const tint_symbol_4) {
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_f32 = 0.0f;
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_i32 = 0;
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_u32 = 0u;
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].scalar_f16 = 0.0h;
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_f32 = float2(0.0f);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_i32 = int2(0);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_u32 = uint2(0u);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec2_f16 = half2(0.0h);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_f32 = packed_float3(0.0f);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_i32 = packed_int3(0);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_u32 = packed_uint3(0u);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec3_f16 = packed_half3(0.0h);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_f32 = float4(0.0f);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_i32 = int4(0);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_u32 = uint4(0u);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].vec4_f16 = half4(0.0h);
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f32 = float2x2(float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f32), float2x3(float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f32 = float2x4(float4(0.0f), float4(0.0f));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f32 = float3x2(float2(0.0f), float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding_1(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f32), float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f32 = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f32 = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
+  assign_and_preserve_padding_2(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f32), float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f32 = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x2_f16 = half2x2(half2(0.0h), half2(0.0h));
+  assign_and_preserve_padding_3(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x3_f16), half2x3(half3(0.0h), half3(0.0h)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat2x4_f16 = half2x4(half4(0.0h), half4(0.0h));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x2_f16 = half3x2(half2(0.0h), half2(0.0h), half2(0.0h));
+  assign_and_preserve_padding_4(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x3_f16), half3x3(half3(0.0h), half3(0.0h), half3(0.0h)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat3x4_f16 = half3x4(half4(0.0h), half4(0.0h), half4(0.0h));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x2_f16 = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
+  assign_and_preserve_padding_5(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x3_f16), half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].mat4x4_f16 = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
   tint_array<float3, 2> const tint_symbol_1 = tint_array<float3, 2>{};
-  assign_and_preserve_padding_6(&((*(tint_symbol_3)).arr[idx].arr2_vec3_f32), tint_symbol_1);
+  assign_and_preserve_padding_6(&((*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].arr2_vec3_f32), tint_symbol_1);
   tint_array<half4x2, 2> const tint_symbol_2 = tint_array<half4x2, 2>{};
-  (*(tint_symbol_3)).arr[idx].arr2_mat4x2_f16 = tint_symbol_2;
+  (*(tint_symbol_3)).arr[min(idx, ((((*(tint_symbol_4)).array_lengths[0u][0u] - 0u) / 800u) - 1u))].arr2_mat4x2_f16 = tint_symbol_2;
 }
 
-kernel void tint_symbol(device S_tint_packed_vec3* tint_symbol_4 [[buffer(0)]], uint idx [[thread_index_in_threadgroup]]) {
-  tint_symbol_inner(idx, tint_symbol_4);
+kernel void tint_symbol(device S_tint_packed_vec3* tint_symbol_5 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_6 [[buffer(30)]], uint idx [[thread_index_in_threadgroup]]) {
+  tint_symbol_inner(idx, tint_symbol_5, tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
index b2216a4..df8e627 100644
--- a/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/dynamic_index/write_f16.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 293
+; Bound: 439
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %57 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -205,11 +206,12 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %48 = OpTypeFunction %void %uint
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_Inner = OpTypePointer StorageBuffer %_runtimearr_Inner
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
     %float_0 = OpConstant %float 0
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-     %uint_1 = OpConstant %uint 1
       %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -217,313 +219,457 @@
 %half_0x0p_0 = OpConstant %half 0x0p+0
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
      %uint_4 = OpConstant %uint 4
-         %67 = OpConstantNull %v2float
+         %89 = OpConstantNull %v2float
 %_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
      %uint_5 = OpConstant %uint 5
-         %71 = OpConstantNull %v2int
+         %97 = OpConstantNull %v2int
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_6 = OpConstant %uint 6
-         %75 = OpConstantNull %v2uint
+        %105 = OpConstantNull %v2uint
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
      %uint_7 = OpConstant %uint 7
-         %79 = OpConstantNull %v2half
+        %113 = OpConstantNull %v2half
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
      %uint_8 = OpConstant %uint 8
-         %83 = OpConstantNull %v3float
+        %121 = OpConstantNull %v3float
 %_ptr_StorageBuffer_v3int = OpTypePointer StorageBuffer %v3int
      %uint_9 = OpConstant %uint 9
-         %87 = OpConstantNull %v3int
+        %129 = OpConstantNull %v3int
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
     %uint_10 = OpConstant %uint 10
-         %91 = OpConstantNull %v3uint
+        %137 = OpConstantNull %v3uint
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
     %uint_11 = OpConstant %uint 11
-         %95 = OpConstantNull %v3half
+        %145 = OpConstantNull %v3half
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
     %uint_12 = OpConstant %uint 12
-         %99 = OpConstantNull %v4float
+        %153 = OpConstantNull %v4float
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
     %uint_13 = OpConstant %uint 13
-        %103 = OpConstantNull %v4int
+        %161 = OpConstantNull %v4int
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
     %uint_14 = OpConstant %uint 14
-        %107 = OpConstantNull %v4uint
+        %169 = OpConstantNull %v4uint
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
     %uint_15 = OpConstant %uint 15
-        %111 = OpConstantNull %v4half
+        %177 = OpConstantNull %v4half
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
     %uint_16 = OpConstant %uint 16
-        %115 = OpConstantNull %mat2v2float
+        %185 = OpConstantNull %mat2v2float
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-        %120 = OpConstantNull %mat2v3float
+        %194 = OpConstantNull %mat2v3float
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
     %uint_18 = OpConstant %uint 18
-        %124 = OpConstantNull %mat2v4float
+        %202 = OpConstantNull %mat2v4float
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
     %uint_19 = OpConstant %uint 19
-        %128 = OpConstantNull %mat3v2float
-        %132 = OpConstantNull %mat3v3float
+        %210 = OpConstantNull %mat3v2float
+        %218 = OpConstantNull %mat3v3float
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
     %uint_21 = OpConstant %uint 21
-        %136 = OpConstantNull %mat3v4float
+        %226 = OpConstantNull %mat3v4float
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
     %uint_22 = OpConstant %uint 22
-        %140 = OpConstantNull %mat4v2float
-        %144 = OpConstantNull %mat4v3float
+        %234 = OpConstantNull %mat4v2float
+        %242 = OpConstantNull %mat4v3float
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
     %uint_24 = OpConstant %uint 24
-        %148 = OpConstantNull %mat4v4float
+        %250 = OpConstantNull %mat4v4float
 %_ptr_StorageBuffer_mat2v2half = OpTypePointer StorageBuffer %mat2v2half
     %uint_25 = OpConstant %uint 25
-        %152 = OpConstantNull %mat2v2half
-        %156 = OpConstantNull %mat2v3half
+        %258 = OpConstantNull %mat2v2half
+        %266 = OpConstantNull %mat2v3half
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
     %uint_27 = OpConstant %uint 27
-        %160 = OpConstantNull %mat2v4half
+        %274 = OpConstantNull %mat2v4half
 %_ptr_StorageBuffer_mat3v2half = OpTypePointer StorageBuffer %mat3v2half
     %uint_28 = OpConstant %uint 28
-        %164 = OpConstantNull %mat3v2half
-        %168 = OpConstantNull %mat3v3half
+        %282 = OpConstantNull %mat3v2half
+        %290 = OpConstantNull %mat3v3half
 %_ptr_StorageBuffer_mat3v4half = OpTypePointer StorageBuffer %mat3v4half
     %uint_30 = OpConstant %uint 30
-        %172 = OpConstantNull %mat3v4half
+        %298 = OpConstantNull %mat3v4half
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
     %uint_31 = OpConstant %uint 31
-        %176 = OpConstantNull %mat4v2half
-        %180 = OpConstantNull %mat4v3half
+        %306 = OpConstantNull %mat4v2half
+        %314 = OpConstantNull %mat4v3half
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
     %uint_33 = OpConstant %uint 33
-        %184 = OpConstantNull %mat4v4half
-        %188 = OpConstantNull %_arr_v3float_uint_2
+        %322 = OpConstantNull %mat4v4half
+        %330 = OpConstantNull %_arr_v3float_uint_2
 %_ptr_StorageBuffer__arr_mat4v2half_uint_2 = OpTypePointer StorageBuffer %_arr_mat4v2half_uint_2
     %uint_35 = OpConstant %uint 35
-        %192 = OpConstantNull %_arr_mat4v2half_uint_2
-        %195 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+        %338 = OpConstantNull %_arr_mat4v2half_uint_2
+        %341 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
     %uint_17 = OpConstant %uint 17
-        %205 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+        %351 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
     %uint_20 = OpConstant %uint 20
-        %217 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+        %363 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
     %uint_23 = OpConstant %uint 23
-        %231 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
+        %377 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
     %uint_26 = OpConstant %uint 26
-        %241 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
+        %387 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
     %uint_29 = OpConstant %uint 29
-        %253 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
+        %399 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
     %uint_32 = OpConstant %uint 32
-        %267 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
+        %413 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_v3float_uint_2
 %_ptr_Function__arr_v3float_uint_2 = OpTypePointer Function %_arr_v3float_uint_2
        %bool = OpTypeBool
     %uint_34 = OpConstant %uint 34
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %289 = OpTypeFunction %void
+        %435 = OpTypeFunction %void
  %main_inner = OpFunction %void None %48
         %idx = OpFunctionParameter %uint
          %49 = OpLabel
-         %50 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %idx %uint_0
-               OpStore %50 %float_0 None
-         %54 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %idx %uint_1
-               OpStore %54 %int_0 None
-         %58 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %idx %uint_2
-               OpStore %58 %uint_0 None
-         %60 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %idx %uint_3
-               OpStore %60 %half_0x0p_0 None
-         %64 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %idx %uint_4
-               OpStore %64 %67 None
-         %68 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %idx %uint_5
-               OpStore %68 %71 None
-         %72 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %idx %uint_6
-               OpStore %72 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %idx %uint_7
-               OpStore %76 %79 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %idx %uint_8
-               OpStore %80 %83 None
-         %84 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %idx %uint_9
-               OpStore %84 %87 None
-         %88 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %idx %uint_10
-               OpStore %88 %91 None
-         %92 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %idx %uint_11
-               OpStore %92 %95 None
-         %96 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %idx %uint_12
-               OpStore %96 %99 None
-        %100 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %idx %uint_13
-               OpStore %100 %103 None
-        %104 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %idx %uint_14
-               OpStore %104 %107 None
-        %108 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %idx %uint_15
-               OpStore %108 %111 None
-        %112 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %idx %uint_16
-               OpStore %112 %115 None
-        %117 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %118 = OpFunctionCall %void %tint_store_and_preserve_padding %117 %120
-        %121 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %idx %uint_18
-               OpStore %121 %124 None
-        %125 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %idx %uint_19
-               OpStore %125 %128 None
-        %129 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %130 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %129 %132
-        %133 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %idx %uint_21
-               OpStore %133 %136 None
-        %137 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %idx %uint_22
-               OpStore %137 %140 None
-        %141 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %142 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %141 %144
-        %145 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %idx %uint_24
-               OpStore %145 %148 None
-        %149 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %idx %uint_25
-               OpStore %149 %152 None
-        %153 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %154 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %153 %156
-        %157 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %idx %uint_27
-               OpStore %157 %160 None
-        %161 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %idx %uint_28
-               OpStore %161 %164 None
-        %165 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %166 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %165 %168
-        %169 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %idx %uint_30
-               OpStore %169 %172 None
-        %173 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %idx %uint_31
-               OpStore %173 %176 None
-        %177 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %178 = OpFunctionCall %void %tint_store_and_preserve_padding_4 %177 %180
-        %181 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %idx %uint_33
-               OpStore %181 %184 None
-        %185 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %186 = OpFunctionCall %void %tint_store_and_preserve_padding_5 %185 %188
-        %189 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %idx %uint_35
-               OpStore %189 %192 None
+         %50 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %53 = OpArrayLength %uint %sb 0
+         %54 = OpISub %uint %53 %uint_1
+         %56 = OpExtInst %uint %57 UMin %idx %54
+         %58 = OpAccessChain %_ptr_StorageBuffer_float %sb %uint_0 %56 %uint_0
+               OpStore %58 %float_0 None
+         %61 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %62 = OpArrayLength %uint %sb 0
+         %63 = OpISub %uint %62 %uint_1
+         %64 = OpExtInst %uint %57 UMin %idx %63
+         %65 = OpAccessChain %_ptr_StorageBuffer_int %sb %uint_0 %64 %uint_1
+               OpStore %65 %int_0 None
+         %68 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %69 = OpArrayLength %uint %sb 0
+         %70 = OpISub %uint %69 %uint_1
+         %71 = OpExtInst %uint %57 UMin %idx %70
+         %72 = OpAccessChain %_ptr_StorageBuffer_uint %sb %uint_0 %71 %uint_2
+               OpStore %72 %uint_0 None
+         %74 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %75 = OpArrayLength %uint %sb 0
+         %76 = OpISub %uint %75 %uint_1
+         %77 = OpExtInst %uint %57 UMin %idx %76
+         %78 = OpAccessChain %_ptr_StorageBuffer_half %sb %uint_0 %77 %uint_3
+               OpStore %78 %half_0x0p_0 None
+         %82 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %83 = OpArrayLength %uint %sb 0
+         %84 = OpISub %uint %83 %uint_1
+         %85 = OpExtInst %uint %57 UMin %idx %84
+         %86 = OpAccessChain %_ptr_StorageBuffer_v2float %sb %uint_0 %85 %uint_4
+               OpStore %86 %89 None
+         %90 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %91 = OpArrayLength %uint %sb 0
+         %92 = OpISub %uint %91 %uint_1
+         %93 = OpExtInst %uint %57 UMin %idx %92
+         %94 = OpAccessChain %_ptr_StorageBuffer_v2int %sb %uint_0 %93 %uint_5
+               OpStore %94 %97 None
+         %98 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+         %99 = OpArrayLength %uint %sb 0
+        %100 = OpISub %uint %99 %uint_1
+        %101 = OpExtInst %uint %57 UMin %idx %100
+        %102 = OpAccessChain %_ptr_StorageBuffer_v2uint %sb %uint_0 %101 %uint_6
+               OpStore %102 %105 None
+        %106 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %107 = OpArrayLength %uint %sb 0
+        %108 = OpISub %uint %107 %uint_1
+        %109 = OpExtInst %uint %57 UMin %idx %108
+        %110 = OpAccessChain %_ptr_StorageBuffer_v2half %sb %uint_0 %109 %uint_7
+               OpStore %110 %113 None
+        %114 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %115 = OpArrayLength %uint %sb 0
+        %116 = OpISub %uint %115 %uint_1
+        %117 = OpExtInst %uint %57 UMin %idx %116
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %117 %uint_8
+               OpStore %118 %121 None
+        %122 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %123 = OpArrayLength %uint %sb 0
+        %124 = OpISub %uint %123 %uint_1
+        %125 = OpExtInst %uint %57 UMin %idx %124
+        %126 = OpAccessChain %_ptr_StorageBuffer_v3int %sb %uint_0 %125 %uint_9
+               OpStore %126 %129 None
+        %130 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %131 = OpArrayLength %uint %sb 0
+        %132 = OpISub %uint %131 %uint_1
+        %133 = OpExtInst %uint %57 UMin %idx %132
+        %134 = OpAccessChain %_ptr_StorageBuffer_v3uint %sb %uint_0 %133 %uint_10
+               OpStore %134 %137 None
+        %138 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %139 = OpArrayLength %uint %sb 0
+        %140 = OpISub %uint %139 %uint_1
+        %141 = OpExtInst %uint %57 UMin %idx %140
+        %142 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %141 %uint_11
+               OpStore %142 %145 None
+        %146 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %147 = OpArrayLength %uint %sb 0
+        %148 = OpISub %uint %147 %uint_1
+        %149 = OpExtInst %uint %57 UMin %idx %148
+        %150 = OpAccessChain %_ptr_StorageBuffer_v4float %sb %uint_0 %149 %uint_12
+               OpStore %150 %153 None
+        %154 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %155 = OpArrayLength %uint %sb 0
+        %156 = OpISub %uint %155 %uint_1
+        %157 = OpExtInst %uint %57 UMin %idx %156
+        %158 = OpAccessChain %_ptr_StorageBuffer_v4int %sb %uint_0 %157 %uint_13
+               OpStore %158 %161 None
+        %162 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %163 = OpArrayLength %uint %sb 0
+        %164 = OpISub %uint %163 %uint_1
+        %165 = OpExtInst %uint %57 UMin %idx %164
+        %166 = OpAccessChain %_ptr_StorageBuffer_v4uint %sb %uint_0 %165 %uint_14
+               OpStore %166 %169 None
+        %170 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %171 = OpArrayLength %uint %sb 0
+        %172 = OpISub %uint %171 %uint_1
+        %173 = OpExtInst %uint %57 UMin %idx %172
+        %174 = OpAccessChain %_ptr_StorageBuffer_v4half %sb %uint_0 %173 %uint_15
+               OpStore %174 %177 None
+        %178 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %179 = OpArrayLength %uint %sb 0
+        %180 = OpISub %uint %179 %uint_1
+        %181 = OpExtInst %uint %57 UMin %idx %180
+        %182 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %sb %uint_0 %181 %uint_16
+               OpStore %182 %185 None
+        %186 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %187 = OpArrayLength %uint %sb 0
+        %188 = OpISub %uint %187 %uint_1
+        %189 = OpExtInst %uint %57 UMin %idx %188
+        %191 = OpCompositeConstruct %_arr_uint_uint_1 %189
+        %192 = OpFunctionCall %void %tint_store_and_preserve_padding %191 %194
+        %195 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %196 = OpArrayLength %uint %sb 0
+        %197 = OpISub %uint %196 %uint_1
+        %198 = OpExtInst %uint %57 UMin %idx %197
+        %199 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %sb %uint_0 %198 %uint_18
+               OpStore %199 %202 None
+        %203 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %204 = OpArrayLength %uint %sb 0
+        %205 = OpISub %uint %204 %uint_1
+        %206 = OpExtInst %uint %57 UMin %idx %205
+        %207 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %sb %uint_0 %206 %uint_19
+               OpStore %207 %210 None
+        %211 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %212 = OpArrayLength %uint %sb 0
+        %213 = OpISub %uint %212 %uint_1
+        %214 = OpExtInst %uint %57 UMin %idx %213
+        %215 = OpCompositeConstruct %_arr_uint_uint_1 %214
+        %216 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %215 %218
+        %219 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %220 = OpArrayLength %uint %sb 0
+        %221 = OpISub %uint %220 %uint_1
+        %222 = OpExtInst %uint %57 UMin %idx %221
+        %223 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %sb %uint_0 %222 %uint_21
+               OpStore %223 %226 None
+        %227 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %228 = OpArrayLength %uint %sb 0
+        %229 = OpISub %uint %228 %uint_1
+        %230 = OpExtInst %uint %57 UMin %idx %229
+        %231 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %sb %uint_0 %230 %uint_22
+               OpStore %231 %234 None
+        %235 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %236 = OpArrayLength %uint %sb 0
+        %237 = OpISub %uint %236 %uint_1
+        %238 = OpExtInst %uint %57 UMin %idx %237
+        %239 = OpCompositeConstruct %_arr_uint_uint_1 %238
+        %240 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %239 %242
+        %243 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %244 = OpArrayLength %uint %sb 0
+        %245 = OpISub %uint %244 %uint_1
+        %246 = OpExtInst %uint %57 UMin %idx %245
+        %247 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %sb %uint_0 %246 %uint_24
+               OpStore %247 %250 None
+        %251 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %252 = OpArrayLength %uint %sb 0
+        %253 = OpISub %uint %252 %uint_1
+        %254 = OpExtInst %uint %57 UMin %idx %253
+        %255 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %sb %uint_0 %254 %uint_25
+               OpStore %255 %258 None
+        %259 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %260 = OpArrayLength %uint %sb 0
+        %261 = OpISub %uint %260 %uint_1
+        %262 = OpExtInst %uint %57 UMin %idx %261
+        %263 = OpCompositeConstruct %_arr_uint_uint_1 %262
+        %264 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %263 %266
+        %267 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %268 = OpArrayLength %uint %sb 0
+        %269 = OpISub %uint %268 %uint_1
+        %270 = OpExtInst %uint %57 UMin %idx %269
+        %271 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %sb %uint_0 %270 %uint_27
+               OpStore %271 %274 None
+        %275 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %276 = OpArrayLength %uint %sb 0
+        %277 = OpISub %uint %276 %uint_1
+        %278 = OpExtInst %uint %57 UMin %idx %277
+        %279 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %sb %uint_0 %278 %uint_28
+               OpStore %279 %282 None
+        %283 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %284 = OpArrayLength %uint %sb 0
+        %285 = OpISub %uint %284 %uint_1
+        %286 = OpExtInst %uint %57 UMin %idx %285
+        %287 = OpCompositeConstruct %_arr_uint_uint_1 %286
+        %288 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %287 %290
+        %291 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %292 = OpArrayLength %uint %sb 0
+        %293 = OpISub %uint %292 %uint_1
+        %294 = OpExtInst %uint %57 UMin %idx %293
+        %295 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %sb %uint_0 %294 %uint_30
+               OpStore %295 %298 None
+        %299 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %300 = OpArrayLength %uint %sb 0
+        %301 = OpISub %uint %300 %uint_1
+        %302 = OpExtInst %uint %57 UMin %idx %301
+        %303 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %sb %uint_0 %302 %uint_31
+               OpStore %303 %306 None
+        %307 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %308 = OpArrayLength %uint %sb 0
+        %309 = OpISub %uint %308 %uint_1
+        %310 = OpExtInst %uint %57 UMin %idx %309
+        %311 = OpCompositeConstruct %_arr_uint_uint_1 %310
+        %312 = OpFunctionCall %void %tint_store_and_preserve_padding_4 %311 %314
+        %315 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %316 = OpArrayLength %uint %sb 0
+        %317 = OpISub %uint %316 %uint_1
+        %318 = OpExtInst %uint %57 UMin %idx %317
+        %319 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %sb %uint_0 %318 %uint_33
+               OpStore %319 %322 None
+        %323 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %324 = OpArrayLength %uint %sb 0
+        %325 = OpISub %uint %324 %uint_1
+        %326 = OpExtInst %uint %57 UMin %idx %325
+        %327 = OpCompositeConstruct %_arr_uint_uint_1 %326
+        %328 = OpFunctionCall %void %tint_store_and_preserve_padding_5 %327 %330
+        %331 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Inner %sb %uint_0
+        %332 = OpArrayLength %uint %sb 0
+        %333 = OpISub %uint %332 %uint_1
+        %334 = OpExtInst %uint %57 UMin %idx %333
+        %335 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_2 %sb %uint_0 %334 %uint_35
+               OpStore %335 %338 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %195
+%tint_store_and_preserve_padding = OpFunction %void None %341
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param = OpFunctionParameter %mat2v3float
-        %196 = OpLabel
-        %197 = OpCompositeExtract %uint %target_indices 0
-        %198 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %197 %uint_17 %uint_0
-        %200 = OpCompositeExtract %v3float %value_param 0
-               OpStore %198 %200 None
-        %201 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %197 %uint_17 %uint_1
-        %202 = OpCompositeExtract %v3float %value_param 1
-               OpStore %201 %202 None
+        %342 = OpLabel
+        %343 = OpCompositeExtract %uint %target_indices 0
+        %344 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %343 %uint_17 %uint_0
+        %346 = OpCompositeExtract %v3float %value_param 0
+               OpStore %344 %346 None
+        %347 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %343 %uint_17 %uint_1
+        %348 = OpCompositeExtract %v3float %value_param 1
+               OpStore %347 %348 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %205
+%tint_store_and_preserve_padding_0 = OpFunction %void None %351
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat3v3float
-        %206 = OpLabel
-        %207 = OpCompositeExtract %uint %target_indices_0 0
-        %208 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %207 %uint_20 %uint_0
-        %210 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %208 %210 None
-        %211 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %207 %uint_20 %uint_1
-        %212 = OpCompositeExtract %v3float %value_param_0 1
-               OpStore %211 %212 None
-        %213 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %207 %uint_20 %uint_2
-        %214 = OpCompositeExtract %v3float %value_param_0 2
-               OpStore %213 %214 None
+        %352 = OpLabel
+        %353 = OpCompositeExtract %uint %target_indices_0 0
+        %354 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %353 %uint_20 %uint_0
+        %356 = OpCompositeExtract %v3float %value_param_0 0
+               OpStore %354 %356 None
+        %357 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %353 %uint_20 %uint_1
+        %358 = OpCompositeExtract %v3float %value_param_0 1
+               OpStore %357 %358 None
+        %359 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %353 %uint_20 %uint_2
+        %360 = OpCompositeExtract %v3float %value_param_0 2
+               OpStore %359 %360 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %217
+%tint_store_and_preserve_padding_1 = OpFunction %void None %363
 %target_indices_1 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat4v3float
-        %218 = OpLabel
-        %219 = OpCompositeExtract %uint %target_indices_1 0
-        %220 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %219 %uint_23 %uint_0
-        %222 = OpCompositeExtract %v3float %value_param_1 0
-               OpStore %220 %222 None
-        %223 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %219 %uint_23 %uint_1
-        %224 = OpCompositeExtract %v3float %value_param_1 1
-               OpStore %223 %224 None
-        %225 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %219 %uint_23 %uint_2
-        %226 = OpCompositeExtract %v3float %value_param_1 2
-               OpStore %225 %226 None
-        %227 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %219 %uint_23 %uint_3
-        %228 = OpCompositeExtract %v3float %value_param_1 3
-               OpStore %227 %228 None
+        %364 = OpLabel
+        %365 = OpCompositeExtract %uint %target_indices_1 0
+        %366 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %365 %uint_23 %uint_0
+        %368 = OpCompositeExtract %v3float %value_param_1 0
+               OpStore %366 %368 None
+        %369 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %365 %uint_23 %uint_1
+        %370 = OpCompositeExtract %v3float %value_param_1 1
+               OpStore %369 %370 None
+        %371 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %365 %uint_23 %uint_2
+        %372 = OpCompositeExtract %v3float %value_param_1 2
+               OpStore %371 %372 None
+        %373 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %365 %uint_23 %uint_3
+        %374 = OpCompositeExtract %v3float %value_param_1 3
+               OpStore %373 %374 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_2 = OpFunction %void None %231
+%tint_store_and_preserve_padding_2 = OpFunction %void None %377
 %target_indices_2 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_2 = OpFunctionParameter %mat2v3half
-        %232 = OpLabel
-        %233 = OpCompositeExtract %uint %target_indices_2 0
-        %234 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %233 %uint_26 %uint_0
-        %236 = OpCompositeExtract %v3half %value_param_2 0
-               OpStore %234 %236 None
-        %237 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %233 %uint_26 %uint_1
-        %238 = OpCompositeExtract %v3half %value_param_2 1
-               OpStore %237 %238 None
+        %378 = OpLabel
+        %379 = OpCompositeExtract %uint %target_indices_2 0
+        %380 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %379 %uint_26 %uint_0
+        %382 = OpCompositeExtract %v3half %value_param_2 0
+               OpStore %380 %382 None
+        %383 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %379 %uint_26 %uint_1
+        %384 = OpCompositeExtract %v3half %value_param_2 1
+               OpStore %383 %384 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_3 = OpFunction %void None %241
+%tint_store_and_preserve_padding_3 = OpFunction %void None %387
 %target_indices_3 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_3 = OpFunctionParameter %mat3v3half
-        %242 = OpLabel
-        %243 = OpCompositeExtract %uint %target_indices_3 0
-        %244 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %243 %uint_29 %uint_0
-        %246 = OpCompositeExtract %v3half %value_param_3 0
-               OpStore %244 %246 None
-        %247 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %243 %uint_29 %uint_1
-        %248 = OpCompositeExtract %v3half %value_param_3 1
-               OpStore %247 %248 None
-        %249 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %243 %uint_29 %uint_2
-        %250 = OpCompositeExtract %v3half %value_param_3 2
-               OpStore %249 %250 None
+        %388 = OpLabel
+        %389 = OpCompositeExtract %uint %target_indices_3 0
+        %390 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %389 %uint_29 %uint_0
+        %392 = OpCompositeExtract %v3half %value_param_3 0
+               OpStore %390 %392 None
+        %393 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %389 %uint_29 %uint_1
+        %394 = OpCompositeExtract %v3half %value_param_3 1
+               OpStore %393 %394 None
+        %395 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %389 %uint_29 %uint_2
+        %396 = OpCompositeExtract %v3half %value_param_3 2
+               OpStore %395 %396 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_4 = OpFunction %void None %253
+%tint_store_and_preserve_padding_4 = OpFunction %void None %399
 %target_indices_4 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_4 = OpFunctionParameter %mat4v3half
-        %254 = OpLabel
-        %255 = OpCompositeExtract %uint %target_indices_4 0
-        %256 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %255 %uint_32 %uint_0
-        %258 = OpCompositeExtract %v3half %value_param_4 0
-               OpStore %256 %258 None
-        %259 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %255 %uint_32 %uint_1
-        %260 = OpCompositeExtract %v3half %value_param_4 1
-               OpStore %259 %260 None
-        %261 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %255 %uint_32 %uint_2
-        %262 = OpCompositeExtract %v3half %value_param_4 2
-               OpStore %261 %262 None
-        %263 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %255 %uint_32 %uint_3
-        %264 = OpCompositeExtract %v3half %value_param_4 3
-               OpStore %263 %264 None
+        %400 = OpLabel
+        %401 = OpCompositeExtract %uint %target_indices_4 0
+        %402 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %401 %uint_32 %uint_0
+        %404 = OpCompositeExtract %v3half %value_param_4 0
+               OpStore %402 %404 None
+        %405 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %401 %uint_32 %uint_1
+        %406 = OpCompositeExtract %v3half %value_param_4 1
+               OpStore %405 %406 None
+        %407 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %401 %uint_32 %uint_2
+        %408 = OpCompositeExtract %v3half %value_param_4 2
+               OpStore %407 %408 None
+        %409 = OpAccessChain %_ptr_StorageBuffer_v3half %sb %uint_0 %401 %uint_32 %uint_3
+        %410 = OpCompositeExtract %v3half %value_param_4 3
+               OpStore %409 %410 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_5 = OpFunction %void None %267
+%tint_store_and_preserve_padding_5 = OpFunction %void None %413
 %target_indices_5 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_5 = OpFunctionParameter %_arr_v3float_uint_2
-        %268 = OpLabel
-        %269 = OpVariable %_ptr_Function__arr_v3float_uint_2 Function
-               OpStore %269 %value_param_5
-        %271 = OpCompositeExtract %uint %target_indices_5 0
-               OpBranch %272
-        %272 = OpLabel
-               OpBranch %275
-        %275 = OpLabel
-        %277 = OpPhi %uint %uint_0 %272 %278 %274
-               OpLoopMerge %276 %274 None
-               OpBranch %273
-        %273 = OpLabel
-        %279 = OpUGreaterThanEqual %bool %277 %uint_2
-               OpSelectionMerge %281 None
-               OpBranchConditional %279 %282 %281
-        %282 = OpLabel
-               OpBranch %276
-        %281 = OpLabel
-        %283 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %271 %uint_34 %277
-        %285 = OpAccessChain %_ptr_Function_v3float %269 %277
-        %287 = OpLoad %v3float %285 None
-               OpStore %283 %287 None
-               OpBranch %274
-        %274 = OpLabel
-        %278 = OpIAdd %uint %277 %uint_1
-               OpBranch %275
-        %276 = OpLabel
+        %414 = OpLabel
+        %415 = OpVariable %_ptr_Function__arr_v3float_uint_2 Function
+               OpStore %415 %value_param_5
+        %417 = OpCompositeExtract %uint %target_indices_5 0
+               OpBranch %418
+        %418 = OpLabel
+               OpBranch %421
+        %421 = OpLabel
+        %423 = OpPhi %uint %uint_0 %418 %424 %420
+               OpLoopMerge %422 %420 None
+               OpBranch %419
+        %419 = OpLabel
+        %425 = OpUGreaterThanEqual %bool %423 %uint_2
+               OpSelectionMerge %427 None
+               OpBranchConditional %425 %428 %427
+        %428 = OpLabel
+               OpBranch %422
+        %427 = OpLabel
+        %429 = OpAccessChain %_ptr_StorageBuffer_v3float %sb %uint_0 %417 %uint_34 %423
+        %431 = OpAccessChain %_ptr_Function_v3float %415 %423
+        %433 = OpLoad %v3float %431 None
+               OpStore %429 %433 None
+               OpBranch %420
+        %420 = OpLabel
+        %424 = OpIAdd %uint %423 %uint_1
+               OpBranch %421
+        %422 = OpLabel
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %289
-        %290 = OpLabel
-        %291 = OpLoad %uint %main_local_invocation_index_Input None
-        %292 = OpFunctionCall %void %main_inner %291
+       %main = OpFunction %void None %435
+        %436 = OpLabel
+        %437 = OpLoad %uint %main_local_invocation_index_Input None
+        %438 = OpFunctionCall %void %main_inner %437
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/static_index/read.wgsl.expected.glsl b/test/tint/buffer/storage/static_index/read.wgsl.expected.glsl
index 1f86f00..629e730 100644
--- a/test/tint/buffer/storage/static_index/read.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/static_index/read.wgsl.expected.glsl
@@ -88,14 +88,14 @@
   int v_7 = (v_6 + int(vec3_u32[1u]));
   int v_8 = ((v_7 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_9 = (v_8 + int(vec4_u32[2u]));
-  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  v_1.inner = (((v_18 + tint_f32_to_i32(arr2_vec3_f32[0][0u])) + struct_inner.scalar_i32) + array_struct_inner[0].scalar_i32);
+  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  v_1.inner = (((v_18 + tint_f32_to_i32(arr2_vec3_f32[0u][0u])) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32);
 }
diff --git a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.dxc.hlsl
index 0def477..9b4538f 100644
--- a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.dxc.hlsl
@@ -130,15 +130,15 @@
   int v_25 = (v_24 + int(vec3_u32.y));
   int v_26 = ((v_25 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_27 = (v_26 + int(vec4_u32.z));
-  int v_28 = (v_27 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_29 = (v_28 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_30 = (v_29 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_31 = (v_30 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_32 = (v_31 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_33 = (v_32 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_34 = (v_33 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_35 = (v_34 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_36 = (v_35 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((((v_36 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_28 = (v_27 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_29 = (v_28 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_30 = (v_29 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_31 = (v_30 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_32 = (v_31 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_33 = (v_32 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_34 = (v_33 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_35 = (v_34 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_36 = (v_35 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((((v_36 + tint_f32_to_i32(arr2_vec3_f32[0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.fxc.hlsl
index 0def477..9b4538f 100644
--- a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.fxc.hlsl
@@ -130,15 +130,15 @@
   int v_25 = (v_24 + int(vec3_u32.y));
   int v_26 = ((v_25 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_27 = (v_26 + int(vec4_u32.z));
-  int v_28 = (v_27 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_29 = (v_28 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_30 = (v_29 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_31 = (v_30 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_32 = (v_31 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_33 = (v_32 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_34 = (v_33 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_35 = (v_34 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_36 = (v_35 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((((v_36 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_28 = (v_27 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_29 = (v_28 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_30 = (v_29 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_31 = (v_30 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_32 = (v_31 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_33 = (v_32 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_34 = (v_33 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_35 = (v_34 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_36 = (v_35 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((((v_36 + tint_f32_to_i32(arr2_vec3_f32[0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.msl b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.msl
index 6bfd190..612011a 100644
--- a/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/static_index/read.wgsl.expected.ir.msl
@@ -114,14 +114,14 @@
   int const v_15 = as_type<int>((as_type<uint>(v_14) + as_type<uint>(int(vec3_u32[1u]))));
   int const v_16 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_15) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_17 = as_type<int>((as_type<uint>(v_16) + as_type<uint>(int(vec4_u32[2u]))));
-  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0].scalar_i32)));
+  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0u].scalar_i32)));
 }
diff --git a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.glsl b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.glsl
index 2bccd8a..22828b3 100644
--- a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.glsl
@@ -129,24 +129,24 @@
   int v_11 = ((v_10 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_12 = (v_11 + int(vec4_u32[2u]));
   int v_13 = (v_12 + tint_f16_to_i32(vec4_f16[2u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_19 = (v_18 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_20 = (v_19 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_21 = (v_20 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_22 = (v_21 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  int v_23 = (v_22 + tint_f16_to_i32(mat2x2_f16[0][0u]));
-  int v_24 = (v_23 + tint_f16_to_i32(mat2x3_f16[0][0u]));
-  int v_25 = (v_24 + tint_f16_to_i32(mat2x4_f16[0][0u]));
-  int v_26 = (v_25 + tint_f16_to_i32(mat3x2_f16[0][0u]));
-  int v_27 = (v_26 + tint_f16_to_i32(mat3x3_f16[0][0u]));
-  int v_28 = (v_27 + tint_f16_to_i32(mat3x4_f16[0][0u]));
-  int v_29 = (v_28 + tint_f16_to_i32(mat4x2_f16[0][0u]));
-  int v_30 = (v_29 + tint_f16_to_i32(mat4x3_f16[0][0u]));
-  int v_31 = (v_30 + tint_f16_to_i32(mat4x4_f16[0][0u]));
-  int v_32 = (v_31 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
-  v_1.inner = (((v_32 + tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u])) + struct_inner.scalar_i32) + array_struct_inner[0].scalar_i32);
+  int v_14 = (v_13 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_15 = (v_14 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_16 = (v_15 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_17 = (v_16 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_18 = (v_17 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_19 = (v_18 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_20 = (v_19 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_21 = (v_20 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_22 = (v_21 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  int v_23 = (v_22 + tint_f16_to_i32(mat2x2_f16[0u][0u]));
+  int v_24 = (v_23 + tint_f16_to_i32(mat2x3_f16[0u][0u]));
+  int v_25 = (v_24 + tint_f16_to_i32(mat2x4_f16[0u][0u]));
+  int v_26 = (v_25 + tint_f16_to_i32(mat3x2_f16[0u][0u]));
+  int v_27 = (v_26 + tint_f16_to_i32(mat3x3_f16[0u][0u]));
+  int v_28 = (v_27 + tint_f16_to_i32(mat3x4_f16[0u][0u]));
+  int v_29 = (v_28 + tint_f16_to_i32(mat4x2_f16[0u][0u]));
+  int v_30 = (v_29 + tint_f16_to_i32(mat4x3_f16[0u][0u]));
+  int v_31 = (v_30 + tint_f16_to_i32(mat4x4_f16[0u][0u]));
+  int v_32 = (v_31 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
+  v_1.inner = (((v_32 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u])) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32);
 }
diff --git a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
index 4e81581..89b58eb 100644
--- a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
@@ -211,25 +211,25 @@
   int v_42 = ((v_41 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_43 = (v_42 + int(vec4_u32.z));
   int v_44 = (v_43 + tint_f16_to_i32(vec4_f16.z));
-  int v_45 = (v_44 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_46 = (v_45 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_47 = (v_46 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_48 = (v_47 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_49 = (v_48 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_50 = (v_49 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_51 = (v_50 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_52 = (v_51 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_53 = (v_52 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  int v_54 = (v_53 + tint_f16_to_i32(mat2x2_f16[int(0)].x));
-  int v_55 = (v_54 + tint_f16_to_i32(mat2x3_f16[int(0)].x));
-  int v_56 = (v_55 + tint_f16_to_i32(mat2x4_f16[int(0)].x));
-  int v_57 = (v_56 + tint_f16_to_i32(mat3x2_f16[int(0)].x));
-  int v_58 = (v_57 + tint_f16_to_i32(mat3x3_f16[int(0)].x));
-  int v_59 = (v_58 + tint_f16_to_i32(mat3x4_f16[int(0)].x));
-  int v_60 = (v_59 + tint_f16_to_i32(mat4x2_f16[int(0)].x));
-  int v_61 = (v_60 + tint_f16_to_i32(mat4x3_f16[int(0)].x));
-  int v_62 = (v_61 + tint_f16_to_i32(mat4x4_f16[int(0)].x));
-  int v_63 = (v_62 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x));
-  s.Store(0u, asuint((((v_63 + tint_f16_to_i32(arr2_mat4x2_f16[int(0)][int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_45 = (v_44 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_46 = (v_45 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_47 = (v_46 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_48 = (v_47 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_49 = (v_48 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_50 = (v_49 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_51 = (v_50 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_52 = (v_51 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_53 = (v_52 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  int v_54 = (v_53 + tint_f16_to_i32(mat2x2_f16[0u].x));
+  int v_55 = (v_54 + tint_f16_to_i32(mat2x3_f16[0u].x));
+  int v_56 = (v_55 + tint_f16_to_i32(mat2x4_f16[0u].x));
+  int v_57 = (v_56 + tint_f16_to_i32(mat3x2_f16[0u].x));
+  int v_58 = (v_57 + tint_f16_to_i32(mat3x3_f16[0u].x));
+  int v_59 = (v_58 + tint_f16_to_i32(mat3x4_f16[0u].x));
+  int v_60 = (v_59 + tint_f16_to_i32(mat4x2_f16[0u].x));
+  int v_61 = (v_60 + tint_f16_to_i32(mat4x3_f16[0u].x));
+  int v_62 = (v_61 + tint_f16_to_i32(mat4x4_f16[0u].x));
+  int v_63 = (v_62 + tint_f32_to_i32(arr2_vec3_f32[0u].x));
+  s.Store(0u, asuint((((v_63 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.msl b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.msl
index 08ef76f..edd7a97 100644
--- a/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/static_index/read_f16.wgsl.expected.ir.msl
@@ -170,24 +170,24 @@
   int const v_28 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_27) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_29 = as_type<int>((as_type<uint>(v_28) + as_type<uint>(int(vec4_u32[2u]))));
   int const v_30 = as_type<int>((as_type<uint>(v_29) + as_type<uint>(tint_f16_to_i32(vec4_f16[2u]))));
-  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0][0u]))));
-  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0][0u]))));
-  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0][0u]))));
-  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0][0u]))));
-  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0][0u]))));
-  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0][0u]))));
-  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0][0u]))));
-  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0][0u]))));
-  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0][0u]))));
-  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0].scalar_i32)));
+  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0u][0u]))));
+  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0u][0u]))));
+  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0u][0u]))));
+  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0u][0u]))));
+  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0u][0u]))));
+  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0u][0u]))));
+  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0u][0u]))));
+  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0u][0u]))));
+  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0u][0u]))));
+  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0u].scalar_i32)));
 }
diff --git a/test/tint/buffer/storage/static_index/write.wgsl.expected.ir.msl b/test/tint/buffer/storage/static_index/write.wgsl.expected.ir.msl
index 4b1417c..5fee146 100644
--- a/test/tint/buffer/storage/static_index/write.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/static_index/write.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Inner {
   /* 0x0000 */ int scalar_i32;
   /* 0x0004 */ float scalar_f32;
@@ -66,6 +69,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 2u)) {
         break;
diff --git a/test/tint/buffer/storage/static_index/write.wgsl.expected.msl b/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
index 7f0d7eb..058a12f 100644
--- a/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
+++ b/test/tint/buffer/storage/static_index/write.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -105,7 +108,8 @@
 
 void assign_and_preserve_padding_3(device tint_array<tint_packed_vec3_f32_array_element, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    (*(dest))[i].elements = packed_float3(value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(dest))[min(i, 1u)].elements = packed_float3(value[min(i, 1u)]);
   }
 }
 
diff --git a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.ir.msl b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.ir.msl
index 30736b2..f6d86f4 100644
--- a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.ir.msl
@@ -20,6 +20,9 @@
   /* 0x000a */ tint_array<int8_t, 2> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 packed;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad_1;
@@ -97,6 +100,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -115,6 +119,7 @@
     uint v_2 = 0u;
     v_2 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 2u)) {
         break;
diff --git a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
index 5ffea48..0399b09 100644
--- a/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/static_index/write_f16.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -162,7 +165,8 @@
 
 void assign_and_preserve_padding_6(device tint_array<tint_packed_vec3_f32_array_element, 2>* const dest, tint_array<float3, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    (*(dest))[i].elements = packed_float3(value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(dest))[min(i, 1u)].elements = packed_float3(value[min(i, 1u)]);
   }
 }
 
@@ -174,7 +178,8 @@
 
 void assign_and_preserve_padding_8(device tint_array<Inner, 4>* const dest, tint_array<Inner, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_7(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false_1);
+    assign_and_preserve_padding_7(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.dxc.hlsl
index d1a0ea6..9b4e4e8 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.dxc.hlsl
@@ -3,6 +3,12 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store<float16_t>(0u, tint_symbol.Load<float16_t>(0u));
+  uint tint_symbol_3 = 0u;
+  tint_symbol_1.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 2u);
+  uint tint_symbol_6 = 0u;
+  tint_symbol.GetDimensions(tint_symbol_6);
+  uint tint_symbol_7 = (tint_symbol_6 / 2u);
+  tint_symbol_1.Store<float16_t>((2u * min(0u, (tint_symbol_4 - 1u))), tint_symbol.Load<float16_t>((2u * min(0u, (tint_symbol_7 - 1u)))));
   return;
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.glsl b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.glsl
index 333fb9c..6c8b941 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.glsl
@@ -11,5 +11,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  v_1.inner[0] = v.inner[0];
+  uint v_2 = (uint(v_1.inner.length()) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  uint v_4 = (uint(v.inner.length()) - 1u);
+  uint v_5 = min(uint(0), v_4);
+  v_1.inner[v_3] = v.inner[v_5];
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.dxc.hlsl
index 301bcd2..f580891 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.dxc.hlsl
@@ -3,6 +3,13 @@
 RWByteAddressBuffer tint_symbol_1 : register(u1);
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store<float16_t>(0u, tint_symbol.Load<float16_t>(0u));
+  uint v = 0u;
+  tint_symbol_1.GetDimensions(v);
+  uint v_1 = ((v / 2u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 2u);
+  uint v_3 = 0u;
+  tint_symbol.GetDimensions(v_3);
+  uint v_4 = ((v_3 / 2u) - 1u);
+  tint_symbol_1.Store<float16_t>((0u + v_2), tint_symbol.Load<float16_t>((0u + (min(uint(int(0)), v_4) * 2u))));
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.msl b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.msl
index 8e41d1c..d57c9c3 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.ir.msl
@@ -16,9 +16,13 @@
 struct tint_module_vars_struct {
   const device tint_array<half, 1>* in;
   device tint_array<half, 1>* out;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-kernel void tint_symbol(const device tint_array<half, 1>* in [[buffer(1)]], device tint_array<half, 1>* out [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.in=in, .out=out};
-  (*tint_module_vars.out)[0] = (*tint_module_vars.in)[0];
+kernel void tint_symbol(const device tint_array<half, 1>* in [[buffer(1)]], device tint_array<half, 1>* out [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.in=in, .out=out, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] / 2u) - 1u);
+  device half* const v_1 = (&(*tint_module_vars.out)[min(uint(0), v)]);
+  uint const v_2 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 2u) - 1u);
+  (*v_1) = (*tint_module_vars.in)[min(uint(0), v_2)];
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.msl b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.msl
index b6b4ed5..87e2d0d 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.msl
@@ -18,12 +18,16 @@
   /* 0x0000 */ tint_array<half, 1> arr;
 };
 
-struct tint_symbol_4 {
+struct tint_symbol_5 {
   /* 0x0000 */ tint_array<half, 1> arr;
 };
 
-kernel void tint_symbol(device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const device tint_symbol_4* tint_symbol_3 [[buffer(1)]]) {
-  (*(tint_symbol_1)).arr[0] = (*(tint_symbol_3)).arr[0];
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+kernel void tint_symbol(device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]], const device tint_symbol_5* tint_symbol_4 [[buffer(1)]]) {
+  (*(tint_symbol_1)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][1u] / 2u) - 1u))] = (*(tint_symbol_4)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][0u] / 2u) - 1u))];
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.spvasm b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.spvasm
index 96f0680..060e5eb 100644
--- a/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/runtime_array_f16.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 22
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,17 +37,30 @@
           %6 = OpVariable %_ptr_StorageBuffer_out_block StorageBuffer
        %void = OpTypeVoid
          %11 = OpTypeFunction %void
-%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
+%_ptr_StorageBuffer__runtimearr_half = OpTypePointer StorageBuffer %_runtimearr_half
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
+%_ptr_StorageBuffer__runtimearr_half_0 = OpTypePointer StorageBuffer %_runtimearr_half
 %_ptr_StorageBuffer_half_0 = OpTypePointer StorageBuffer %half
        %main = OpFunction %void None %11
          %12 = OpLabel
-         %13 = OpAccessChain %_ptr_StorageBuffer_half %6 %uint_0 %int_0
-         %19 = OpAccessChain %_ptr_StorageBuffer_half_0 %1 %uint_0 %int_0
-         %21 = OpLoad %half %19 None
-               OpStore %13 %21 None
+         %13 = OpAccessChain %_ptr_StorageBuffer__runtimearr_half %6 %uint_0
+         %17 = OpArrayLength %uint %6 0
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_0
+         %23 = OpExtInst %uint %24 UMin %20 %18
+         %25 = OpAccessChain %_ptr_StorageBuffer_half %6 %uint_0 %23
+         %27 = OpAccessChain %_ptr_StorageBuffer__runtimearr_half_0 %1 %uint_0
+         %29 = OpArrayLength %uint %1 0
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_0
+         %32 = OpExtInst %uint %24 UMin %31 %30
+         %33 = OpAccessChain %_ptr_StorageBuffer_half_0 %1 %uint_0 %32
+         %35 = OpLoad %half %33 None
+               OpStore %25 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.dxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.dxc.hlsl
index cf2f27b..9144227 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.dxc.hlsl
@@ -3,6 +3,12 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store(0u, asuint(asfloat(tint_symbol.Load(0u))));
+  uint tint_symbol_3 = 0u;
+  tint_symbol_1.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
+  uint tint_symbol_6 = 0u;
+  tint_symbol.GetDimensions(tint_symbol_6);
+  uint tint_symbol_7 = (tint_symbol_6 / 4u);
+  tint_symbol_1.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(asfloat(tint_symbol.Load((4u * min(0u, (tint_symbol_7 - 1u)))))));
   return;
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.fxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.fxc.hlsl
index cf2f27b..9144227 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.fxc.hlsl
@@ -3,6 +3,12 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store(0u, asuint(asfloat(tint_symbol.Load(0u))));
+  uint tint_symbol_3 = 0u;
+  tint_symbol_1.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
+  uint tint_symbol_6 = 0u;
+  tint_symbol.GetDimensions(tint_symbol_6);
+  uint tint_symbol_7 = (tint_symbol_6 / 4u);
+  tint_symbol_1.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(asfloat(tint_symbol.Load((4u * min(0u, (tint_symbol_7 - 1u)))))));
   return;
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.glsl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.glsl
index 9925ce9..38405fc 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.glsl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.glsl
@@ -10,5 +10,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  v_1.inner[0] = v.inner[0];
+  uint v_2 = (uint(v_1.inner.length()) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  uint v_4 = (uint(v.inner.length()) - 1u);
+  uint v_5 = min(uint(0), v_4);
+  v_1.inner[v_3] = v.inner[v_5];
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.dxc.hlsl
index 0638383..ef5d590 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.dxc.hlsl
@@ -3,6 +3,13 @@
 RWByteAddressBuffer tint_symbol_1 : register(u1);
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store(0u, asuint(asfloat(tint_symbol.Load(0u))));
+  uint v = 0u;
+  tint_symbol_1.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  uint v_3 = 0u;
+  tint_symbol.GetDimensions(v_3);
+  uint v_4 = ((v_3 / 4u) - 1u);
+  tint_symbol_1.Store((0u + v_2), asuint(asfloat(tint_symbol.Load((0u + (min(uint(int(0)), v_4) * 4u))))));
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.fxc.hlsl
index 0638383..ef5d590 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.fxc.hlsl
@@ -3,6 +3,13 @@
 RWByteAddressBuffer tint_symbol_1 : register(u1);
 [numthreads(1, 1, 1)]
 void main() {
-  tint_symbol_1.Store(0u, asuint(asfloat(tint_symbol.Load(0u))));
+  uint v = 0u;
+  tint_symbol_1.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  uint v_3 = 0u;
+  tint_symbol.GetDimensions(v_3);
+  uint v_4 = ((v_3 / 4u) - 1u);
+  tint_symbol_1.Store((0u + v_2), asuint(asfloat(tint_symbol.Load((0u + (min(uint(int(0)), v_4) * 4u))))));
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.msl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.msl
index 94b8d00..70e0b17 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.msl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.ir.msl
@@ -16,9 +16,13 @@
 struct tint_module_vars_struct {
   const device tint_array<float, 1>* in;
   device tint_array<float, 1>* out;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-kernel void tint_symbol(const device tint_array<float, 1>* in [[buffer(1)]], device tint_array<float, 1>* out [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.in=in, .out=out};
-  (*tint_module_vars.out)[0] = (*tint_module_vars.in)[0];
+kernel void tint_symbol(const device tint_array<float, 1>* in [[buffer(1)]], device tint_array<float, 1>* out [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.in=in, .out=out, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] / 4u) - 1u);
+  device float* const v_1 = (&(*tint_module_vars.out)[min(uint(0), v)]);
+  uint const v_2 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  (*v_1) = (*tint_module_vars.in)[min(uint(0), v_2)];
 }
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.msl b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.msl
index 65ac123..7125c4a 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.msl
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.msl
@@ -18,12 +18,16 @@
   /* 0x0000 */ tint_array<float, 1> arr;
 };
 
-struct tint_symbol_4 {
+struct tint_symbol_5 {
   /* 0x0000 */ tint_array<float, 1> arr;
 };
 
-kernel void tint_symbol(device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const device tint_symbol_4* tint_symbol_3 [[buffer(1)]]) {
-  (*(tint_symbol_1)).arr[0] = (*(tint_symbol_3)).arr[0];
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+kernel void tint_symbol(device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]], const device tint_symbol_5* tint_symbol_4 [[buffer(1)]]) {
+  (*(tint_symbol_1)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][1u] / 4u) - 1u))] = (*(tint_symbol_4)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][0u] / 4u) - 1u))];
   return;
 }
 
diff --git a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.spvasm b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.spvasm
index 389fdcf..576f4de 100644
--- a/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.spvasm
+++ b/test/tint/buffer/storage/types/runtime_array_f32.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 22
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -33,17 +34,30 @@
           %6 = OpVariable %_ptr_StorageBuffer_out_block StorageBuffer
        %void = OpTypeVoid
          %11 = OpTypeFunction %void
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float_0 = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float_0 = OpTypePointer StorageBuffer %float
        %main = OpFunction %void None %11
          %12 = OpLabel
-         %13 = OpAccessChain %_ptr_StorageBuffer_float %6 %uint_0 %int_0
-         %19 = OpAccessChain %_ptr_StorageBuffer_float_0 %1 %uint_0 %int_0
-         %21 = OpLoad %float %19 None
-               OpStore %13 %21 None
+         %13 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %6 %uint_0
+         %17 = OpArrayLength %uint %6 0
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_0
+         %23 = OpExtInst %uint %24 UMin %20 %18
+         %25 = OpAccessChain %_ptr_StorageBuffer_float %6 %uint_0 %23
+         %27 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float_0 %1 %uint_0
+         %29 = OpArrayLength %uint %1 0
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_0
+         %32 = OpExtInst %uint %24 UMin %31 %30
+         %33 = OpAccessChain %_ptr_StorageBuffer_float_0 %1 %uint_0 %32
+         %35 = OpLoad %float %33 None
+               OpStore %25 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.dxc.hlsl
index dfbe53a..894c5d9 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.dxc.hlsl
@@ -96,43 +96,43 @@
 }
 
 void main_inner(uint idx) {
-  const uint scalar_offset_28 = ((544u * idx)) / 4;
+  const uint scalar_offset_28 = ((544u * min(idx, 7u))) / 4;
   float scalar_f32 = asfloat(ub[scalar_offset_28 / 4][scalar_offset_28 % 4]);
-  const uint scalar_offset_29 = (((544u * idx) + 4u)) / 4;
+  const uint scalar_offset_29 = (((544u * min(idx, 7u)) + 4u)) / 4;
   int scalar_i32 = asint(ub[scalar_offset_29 / 4][scalar_offset_29 % 4]);
-  const uint scalar_offset_30 = (((544u * idx) + 8u)) / 4;
+  const uint scalar_offset_30 = (((544u * min(idx, 7u)) + 8u)) / 4;
   uint scalar_u32 = ub[scalar_offset_30 / 4][scalar_offset_30 % 4];
-  const uint scalar_offset_31 = (((544u * idx) + 16u)) / 4;
+  const uint scalar_offset_31 = (((544u * min(idx, 7u)) + 16u)) / 4;
   uint4 ubo_load_9 = ub[scalar_offset_31 / 4];
   float2 vec2_f32 = asfloat(((scalar_offset_31 & 2) ? ubo_load_9.zw : ubo_load_9.xy));
-  const uint scalar_offset_32 = (((544u * idx) + 24u)) / 4;
+  const uint scalar_offset_32 = (((544u * min(idx, 7u)) + 24u)) / 4;
   uint4 ubo_load_10 = ub[scalar_offset_32 / 4];
   int2 vec2_i32 = asint(((scalar_offset_32 & 2) ? ubo_load_10.zw : ubo_load_10.xy));
-  const uint scalar_offset_33 = (((544u * idx) + 32u)) / 4;
+  const uint scalar_offset_33 = (((544u * min(idx, 7u)) + 32u)) / 4;
   uint4 ubo_load_11 = ub[scalar_offset_33 / 4];
   uint2 vec2_u32 = ((scalar_offset_33 & 2) ? ubo_load_11.zw : ubo_load_11.xy);
-  const uint scalar_offset_34 = (((544u * idx) + 48u)) / 4;
+  const uint scalar_offset_34 = (((544u * min(idx, 7u)) + 48u)) / 4;
   float3 vec3_f32 = asfloat(ub[scalar_offset_34 / 4].xyz);
-  const uint scalar_offset_35 = (((544u * idx) + 64u)) / 4;
+  const uint scalar_offset_35 = (((544u * min(idx, 7u)) + 64u)) / 4;
   int3 vec3_i32 = asint(ub[scalar_offset_35 / 4].xyz);
-  const uint scalar_offset_36 = (((544u * idx) + 80u)) / 4;
+  const uint scalar_offset_36 = (((544u * min(idx, 7u)) + 80u)) / 4;
   uint3 vec3_u32 = ub[scalar_offset_36 / 4].xyz;
-  const uint scalar_offset_37 = (((544u * idx) + 96u)) / 4;
+  const uint scalar_offset_37 = (((544u * min(idx, 7u)) + 96u)) / 4;
   float4 vec4_f32 = asfloat(ub[scalar_offset_37 / 4]);
-  const uint scalar_offset_38 = (((544u * idx) + 112u)) / 4;
+  const uint scalar_offset_38 = (((544u * min(idx, 7u)) + 112u)) / 4;
   int4 vec4_i32 = asint(ub[scalar_offset_38 / 4]);
-  const uint scalar_offset_39 = (((544u * idx) + 128u)) / 4;
+  const uint scalar_offset_39 = (((544u * min(idx, 7u)) + 128u)) / 4;
   uint4 vec4_u32 = ub[scalar_offset_39 / 4];
-  float2x2 mat2x2_f32 = ub_load_12(((544u * idx) + 144u));
-  float2x3 mat2x3_f32 = ub_load_13(((544u * idx) + 160u));
-  float2x4 mat2x4_f32 = ub_load_14(((544u * idx) + 192u));
-  float3x2 mat3x2_f32 = ub_load_15(((544u * idx) + 224u));
-  float3x3 mat3x3_f32 = ub_load_16(((544u * idx) + 256u));
-  float3x4 mat3x4_f32 = ub_load_17(((544u * idx) + 304u));
-  float4x2 mat4x2_f32 = ub_load_18(((544u * idx) + 352u));
-  float4x3 mat4x3_f32 = ub_load_19(((544u * idx) + 384u));
-  float4x4 mat4x4_f32 = ub_load_20(((544u * idx) + 448u));
-  float3 arr2_vec3_f32[2] = ub_load_21(((544u * idx) + 512u));
+  float2x2 mat2x2_f32 = ub_load_12(((544u * min(idx, 7u)) + 144u));
+  float2x3 mat2x3_f32 = ub_load_13(((544u * min(idx, 7u)) + 160u));
+  float2x4 mat2x4_f32 = ub_load_14(((544u * min(idx, 7u)) + 192u));
+  float3x2 mat3x2_f32 = ub_load_15(((544u * min(idx, 7u)) + 224u));
+  float3x3 mat3x3_f32 = ub_load_16(((544u * min(idx, 7u)) + 256u));
+  float3x4 mat3x4_f32 = ub_load_17(((544u * min(idx, 7u)) + 304u));
+  float4x2 mat4x2_f32 = ub_load_18(((544u * min(idx, 7u)) + 352u));
+  float4x3 mat4x3_f32 = ub_load_19(((544u * min(idx, 7u)) + 384u));
+  float4x4 mat4x4_f32 = ub_load_20(((544u * min(idx, 7u)) + 448u));
+  float3 arr2_vec3_f32[2] = ub_load_21(((544u * min(idx, 7u)) + 512u));
   s.Store(0u, asuint((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + tint_ftoi(arr2_vec3_f32[0].x))));
 }
 
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.fxc.hlsl
index dfbe53a..894c5d9 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.fxc.hlsl
@@ -96,43 +96,43 @@
 }
 
 void main_inner(uint idx) {
-  const uint scalar_offset_28 = ((544u * idx)) / 4;
+  const uint scalar_offset_28 = ((544u * min(idx, 7u))) / 4;
   float scalar_f32 = asfloat(ub[scalar_offset_28 / 4][scalar_offset_28 % 4]);
-  const uint scalar_offset_29 = (((544u * idx) + 4u)) / 4;
+  const uint scalar_offset_29 = (((544u * min(idx, 7u)) + 4u)) / 4;
   int scalar_i32 = asint(ub[scalar_offset_29 / 4][scalar_offset_29 % 4]);
-  const uint scalar_offset_30 = (((544u * idx) + 8u)) / 4;
+  const uint scalar_offset_30 = (((544u * min(idx, 7u)) + 8u)) / 4;
   uint scalar_u32 = ub[scalar_offset_30 / 4][scalar_offset_30 % 4];
-  const uint scalar_offset_31 = (((544u * idx) + 16u)) / 4;
+  const uint scalar_offset_31 = (((544u * min(idx, 7u)) + 16u)) / 4;
   uint4 ubo_load_9 = ub[scalar_offset_31 / 4];
   float2 vec2_f32 = asfloat(((scalar_offset_31 & 2) ? ubo_load_9.zw : ubo_load_9.xy));
-  const uint scalar_offset_32 = (((544u * idx) + 24u)) / 4;
+  const uint scalar_offset_32 = (((544u * min(idx, 7u)) + 24u)) / 4;
   uint4 ubo_load_10 = ub[scalar_offset_32 / 4];
   int2 vec2_i32 = asint(((scalar_offset_32 & 2) ? ubo_load_10.zw : ubo_load_10.xy));
-  const uint scalar_offset_33 = (((544u * idx) + 32u)) / 4;
+  const uint scalar_offset_33 = (((544u * min(idx, 7u)) + 32u)) / 4;
   uint4 ubo_load_11 = ub[scalar_offset_33 / 4];
   uint2 vec2_u32 = ((scalar_offset_33 & 2) ? ubo_load_11.zw : ubo_load_11.xy);
-  const uint scalar_offset_34 = (((544u * idx) + 48u)) / 4;
+  const uint scalar_offset_34 = (((544u * min(idx, 7u)) + 48u)) / 4;
   float3 vec3_f32 = asfloat(ub[scalar_offset_34 / 4].xyz);
-  const uint scalar_offset_35 = (((544u * idx) + 64u)) / 4;
+  const uint scalar_offset_35 = (((544u * min(idx, 7u)) + 64u)) / 4;
   int3 vec3_i32 = asint(ub[scalar_offset_35 / 4].xyz);
-  const uint scalar_offset_36 = (((544u * idx) + 80u)) / 4;
+  const uint scalar_offset_36 = (((544u * min(idx, 7u)) + 80u)) / 4;
   uint3 vec3_u32 = ub[scalar_offset_36 / 4].xyz;
-  const uint scalar_offset_37 = (((544u * idx) + 96u)) / 4;
+  const uint scalar_offset_37 = (((544u * min(idx, 7u)) + 96u)) / 4;
   float4 vec4_f32 = asfloat(ub[scalar_offset_37 / 4]);
-  const uint scalar_offset_38 = (((544u * idx) + 112u)) / 4;
+  const uint scalar_offset_38 = (((544u * min(idx, 7u)) + 112u)) / 4;
   int4 vec4_i32 = asint(ub[scalar_offset_38 / 4]);
-  const uint scalar_offset_39 = (((544u * idx) + 128u)) / 4;
+  const uint scalar_offset_39 = (((544u * min(idx, 7u)) + 128u)) / 4;
   uint4 vec4_u32 = ub[scalar_offset_39 / 4];
-  float2x2 mat2x2_f32 = ub_load_12(((544u * idx) + 144u));
-  float2x3 mat2x3_f32 = ub_load_13(((544u * idx) + 160u));
-  float2x4 mat2x4_f32 = ub_load_14(((544u * idx) + 192u));
-  float3x2 mat3x2_f32 = ub_load_15(((544u * idx) + 224u));
-  float3x3 mat3x3_f32 = ub_load_16(((544u * idx) + 256u));
-  float3x4 mat3x4_f32 = ub_load_17(((544u * idx) + 304u));
-  float4x2 mat4x2_f32 = ub_load_18(((544u * idx) + 352u));
-  float4x3 mat4x3_f32 = ub_load_19(((544u * idx) + 384u));
-  float4x4 mat4x4_f32 = ub_load_20(((544u * idx) + 448u));
-  float3 arr2_vec3_f32[2] = ub_load_21(((544u * idx) + 512u));
+  float2x2 mat2x2_f32 = ub_load_12(((544u * min(idx, 7u)) + 144u));
+  float2x3 mat2x3_f32 = ub_load_13(((544u * min(idx, 7u)) + 160u));
+  float2x4 mat2x4_f32 = ub_load_14(((544u * min(idx, 7u)) + 192u));
+  float3x2 mat3x2_f32 = ub_load_15(((544u * min(idx, 7u)) + 224u));
+  float3x3 mat3x3_f32 = ub_load_16(((544u * min(idx, 7u)) + 256u));
+  float3x4 mat3x4_f32 = ub_load_17(((544u * min(idx, 7u)) + 304u));
+  float4x2 mat4x2_f32 = ub_load_18(((544u * min(idx, 7u)) + 352u));
+  float4x3 mat4x3_f32 = ub_load_19(((544u * min(idx, 7u)) + 384u));
+  float4x4 mat4x4_f32 = ub_load_20(((544u * min(idx, 7u)) + 448u));
+  float3 arr2_vec3_f32[2] = ub_load_21(((544u * min(idx, 7u)) + 512u));
   s.Store(0u, asuint((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + tint_ftoi(arr2_vec3_f32[0].x))));
 }
 
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.glsl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.glsl
index 3997675..ff14a06 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.glsl
@@ -71,28 +71,28 @@
   return mix(2147483647, mix((-2147483647 - 1), int(value), (value >= -2147483648.0f)), (value <= 2147483520.0f));
 }
 void tint_symbol_inner(uint idx) {
-  float scalar_f32 = v.inner.arr[idx].scalar_f32;
-  int scalar_i32 = v.inner.arr[idx].scalar_i32;
-  uint scalar_u32 = v.inner.arr[idx].scalar_u32;
-  vec2 vec2_f32 = v.inner.arr[idx].vec2_f32;
-  ivec2 vec2_i32 = v.inner.arr[idx].vec2_i32;
-  uvec2 vec2_u32 = v.inner.arr[idx].vec2_u32;
-  vec3 vec3_f32 = v.inner.arr[idx].vec3_f32;
-  ivec3 vec3_i32 = v.inner.arr[idx].vec3_i32;
-  uvec3 vec3_u32 = v.inner.arr[idx].vec3_u32;
-  vec4 vec4_f32 = v.inner.arr[idx].vec4_f32;
-  ivec4 vec4_i32 = v.inner.arr[idx].vec4_i32;
-  uvec4 vec4_u32 = v.inner.arr[idx].vec4_u32;
-  mat2 mat2x2_f32 = mat2(v.inner.arr[idx].mat2x2_f32_col0, v.inner.arr[idx].mat2x2_f32_col1);
-  mat2x3 mat2x3_f32 = mat2x3(v.inner.arr[idx].mat2x3_f32_col0, v.inner.arr[idx].mat2x3_f32_col1);
-  mat2x4 mat2x4_f32 = v.inner.arr[idx].mat2x4_f32;
-  mat3x2 mat3x2_f32 = mat3x2(v.inner.arr[idx].mat3x2_f32_col0, v.inner.arr[idx].mat3x2_f32_col1, v.inner.arr[idx].mat3x2_f32_col2);
-  mat3 mat3x3_f32 = mat3(v.inner.arr[idx].mat3x3_f32_col0, v.inner.arr[idx].mat3x3_f32_col1, v.inner.arr[idx].mat3x3_f32_col2);
-  mat3x4 mat3x4_f32 = v.inner.arr[idx].mat3x4_f32;
-  mat4x2 mat4x2_f32 = mat4x2(v.inner.arr[idx].mat4x2_f32_col0, v.inner.arr[idx].mat4x2_f32_col1, v.inner.arr[idx].mat4x2_f32_col2, v.inner.arr[idx].mat4x2_f32_col3);
-  mat4x3 mat4x3_f32 = mat4x3(v.inner.arr[idx].mat4x3_f32_col0, v.inner.arr[idx].mat4x3_f32_col1, v.inner.arr[idx].mat4x3_f32_col2, v.inner.arr[idx].mat4x3_f32_col3);
-  mat4 mat4x4_f32 = v.inner.arr[idx].mat4x4_f32;
-  vec3 arr2_vec3_f32[2] = v.inner.arr[idx].arr2_vec3_f32;
+  float scalar_f32 = v.inner.arr[min(idx, 7u)].scalar_f32;
+  int scalar_i32 = v.inner.arr[min(idx, 7u)].scalar_i32;
+  uint scalar_u32 = v.inner.arr[min(idx, 7u)].scalar_u32;
+  vec2 vec2_f32 = v.inner.arr[min(idx, 7u)].vec2_f32;
+  ivec2 vec2_i32 = v.inner.arr[min(idx, 7u)].vec2_i32;
+  uvec2 vec2_u32 = v.inner.arr[min(idx, 7u)].vec2_u32;
+  vec3 vec3_f32 = v.inner.arr[min(idx, 7u)].vec3_f32;
+  ivec3 vec3_i32 = v.inner.arr[min(idx, 7u)].vec3_i32;
+  uvec3 vec3_u32 = v.inner.arr[min(idx, 7u)].vec3_u32;
+  vec4 vec4_f32 = v.inner.arr[min(idx, 7u)].vec4_f32;
+  ivec4 vec4_i32 = v.inner.arr[min(idx, 7u)].vec4_i32;
+  uvec4 vec4_u32 = v.inner.arr[min(idx, 7u)].vec4_u32;
+  mat2 mat2x2_f32 = mat2(v.inner.arr[min(idx, 7u)].mat2x2_f32_col0, v.inner.arr[min(idx, 7u)].mat2x2_f32_col1);
+  mat2x3 mat2x3_f32 = mat2x3(v.inner.arr[min(idx, 7u)].mat2x3_f32_col0, v.inner.arr[min(idx, 7u)].mat2x3_f32_col1);
+  mat2x4 mat2x4_f32 = v.inner.arr[min(idx, 7u)].mat2x4_f32;
+  mat3x2 mat3x2_f32 = mat3x2(v.inner.arr[min(idx, 7u)].mat3x2_f32_col0, v.inner.arr[min(idx, 7u)].mat3x2_f32_col1, v.inner.arr[min(idx, 7u)].mat3x2_f32_col2);
+  mat3 mat3x3_f32 = mat3(v.inner.arr[min(idx, 7u)].mat3x3_f32_col0, v.inner.arr[min(idx, 7u)].mat3x3_f32_col1, v.inner.arr[min(idx, 7u)].mat3x3_f32_col2);
+  mat3x4 mat3x4_f32 = v.inner.arr[min(idx, 7u)].mat3x4_f32;
+  mat4x2 mat4x2_f32 = mat4x2(v.inner.arr[min(idx, 7u)].mat4x2_f32_col0, v.inner.arr[min(idx, 7u)].mat4x2_f32_col1, v.inner.arr[min(idx, 7u)].mat4x2_f32_col2, v.inner.arr[min(idx, 7u)].mat4x2_f32_col3);
+  mat4x3 mat4x3_f32 = mat4x3(v.inner.arr[min(idx, 7u)].mat4x3_f32_col0, v.inner.arr[min(idx, 7u)].mat4x3_f32_col1, v.inner.arr[min(idx, 7u)].mat4x3_f32_col2, v.inner.arr[min(idx, 7u)].mat4x3_f32_col3);
+  mat4 mat4x4_f32 = v.inner.arr[min(idx, 7u)].mat4x4_f32;
+  vec3 arr2_vec3_f32[2] = v.inner.arr[min(idx, 7u)].arr2_vec3_f32;
   int v_2 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
   int v_3 = (v_2 + int(scalar_u32));
   int v_4 = ((v_3 + tint_f32_to_i32(vec2_f32[0u])) + vec2_i32[0u]);
@@ -101,16 +101,16 @@
   int v_7 = (v_6 + int(vec3_u32[1u]));
   int v_8 = ((v_7 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_9 = (v_8 + int(vec4_u32[2u]));
-  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  v_1.inner = (v_18 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
+  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  v_1.inner = (v_18 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
index f4360e4..fc20c61 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.dxc.hlsl
@@ -85,43 +85,43 @@
 }
 
 void main_inner(uint idx) {
-  uint v_28 = (544u * uint(idx));
+  uint v_28 = (544u * uint(min(idx, 7u)));
   float scalar_f32 = asfloat(ub[(v_28 / 16u)][((v_28 % 16u) / 4u)]);
-  uint v_29 = (4u + (544u * uint(idx)));
+  uint v_29 = (4u + (544u * uint(min(idx, 7u))));
   int scalar_i32 = asint(ub[(v_29 / 16u)][((v_29 % 16u) / 4u)]);
-  uint v_30 = (8u + (544u * uint(idx)));
+  uint v_30 = (8u + (544u * uint(min(idx, 7u))));
   uint scalar_u32 = ub[(v_30 / 16u)][((v_30 % 16u) / 4u)];
-  uint v_31 = (16u + (544u * uint(idx)));
+  uint v_31 = (16u + (544u * uint(min(idx, 7u))));
   uint4 v_32 = ub[(v_31 / 16u)];
   float2 vec2_f32 = asfloat((((((v_31 % 16u) / 4u) == 2u)) ? (v_32.zw) : (v_32.xy)));
-  uint v_33 = (24u + (544u * uint(idx)));
+  uint v_33 = (24u + (544u * uint(min(idx, 7u))));
   uint4 v_34 = ub[(v_33 / 16u)];
   int2 vec2_i32 = asint((((((v_33 % 16u) / 4u) == 2u)) ? (v_34.zw) : (v_34.xy)));
-  uint v_35 = (32u + (544u * uint(idx)));
+  uint v_35 = (32u + (544u * uint(min(idx, 7u))));
   uint4 v_36 = ub[(v_35 / 16u)];
   uint2 vec2_u32 = (((((v_35 % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy));
-  uint v_37 = ((48u + (544u * uint(idx))) / 16u);
+  uint v_37 = ((48u + (544u * uint(min(idx, 7u)))) / 16u);
   float3 vec3_f32 = asfloat(ub[v_37].xyz);
-  uint v_38 = ((64u + (544u * uint(idx))) / 16u);
+  uint v_38 = ((64u + (544u * uint(min(idx, 7u)))) / 16u);
   int3 vec3_i32 = asint(ub[v_38].xyz);
-  uint v_39 = ((80u + (544u * uint(idx))) / 16u);
+  uint v_39 = ((80u + (544u * uint(min(idx, 7u)))) / 16u);
   uint3 vec3_u32 = ub[v_39].xyz;
-  uint v_40 = ((96u + (544u * uint(idx))) / 16u);
+  uint v_40 = ((96u + (544u * uint(min(idx, 7u)))) / 16u);
   float4 vec4_f32 = asfloat(ub[v_40]);
-  uint v_41 = ((112u + (544u * uint(idx))) / 16u);
+  uint v_41 = ((112u + (544u * uint(min(idx, 7u)))) / 16u);
   int4 vec4_i32 = asint(ub[v_41]);
-  uint v_42 = ((128u + (544u * uint(idx))) / 16u);
+  uint v_42 = ((128u + (544u * uint(min(idx, 7u)))) / 16u);
   uint4 vec4_u32 = ub[v_42];
-  float2x2 mat2x2_f32 = v_24((144u + (544u * uint(idx))));
-  float2x3 mat2x3_f32 = v_23((160u + (544u * uint(idx))));
-  float2x4 mat2x4_f32 = v_22((192u + (544u * uint(idx))));
-  float3x2 mat3x2_f32 = v_16((224u + (544u * uint(idx))));
-  float3x3 mat3x3_f32 = v_15((256u + (544u * uint(idx))));
-  float3x4 mat3x4_f32 = v_14((304u + (544u * uint(idx))));
-  float4x2 mat4x2_f32 = v_6((352u + (544u * uint(idx))));
-  float4x3 mat4x3_f32 = v_5((384u + (544u * uint(idx))));
-  float4x4 mat4x4_f32 = v_4((448u + (544u * uint(idx))));
-  float3 arr2_vec3_f32[2] = v((512u + (544u * uint(idx))));
+  float2x2 mat2x2_f32 = v_24((144u + (544u * uint(min(idx, 7u)))));
+  float2x3 mat2x3_f32 = v_23((160u + (544u * uint(min(idx, 7u)))));
+  float2x4 mat2x4_f32 = v_22((192u + (544u * uint(min(idx, 7u)))));
+  float3x2 mat3x2_f32 = v_16((224u + (544u * uint(min(idx, 7u)))));
+  float3x3 mat3x3_f32 = v_15((256u + (544u * uint(min(idx, 7u)))));
+  float3x4 mat3x4_f32 = v_14((304u + (544u * uint(min(idx, 7u)))));
+  float4x2 mat4x2_f32 = v_6((352u + (544u * uint(min(idx, 7u)))));
+  float4x3 mat4x3_f32 = v_5((384u + (544u * uint(min(idx, 7u)))));
+  float4x4 mat4x4_f32 = v_4((448u + (544u * uint(min(idx, 7u)))));
+  float3 arr2_vec3_f32[2] = v((512u + (544u * uint(min(idx, 7u)))));
   int v_43 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
   int v_44 = (v_43 + int(scalar_u32));
   int v_45 = ((v_44 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
@@ -130,16 +130,16 @@
   int v_48 = (v_47 + int(vec3_u32.y));
   int v_49 = ((v_48 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_50 = (v_49 + int(vec4_u32.z));
-  int v_51 = (v_50 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_52 = (v_51 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_53 = (v_52 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_54 = (v_53 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_55 = (v_54 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_56 = (v_55 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_57 = (v_56 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_58 = (v_57 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_59 = (v_58 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((v_59 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x))));
+  int v_51 = (v_50 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_52 = (v_51 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_53 = (v_52 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_54 = (v_53 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_55 = (v_54 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_56 = (v_55 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_57 = (v_56 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_58 = (v_57 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_59 = (v_58 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((v_59 + tint_f32_to_i32(arr2_vec3_f32[0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
index f4360e4..fc20c61 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.fxc.hlsl
@@ -85,43 +85,43 @@
 }
 
 void main_inner(uint idx) {
-  uint v_28 = (544u * uint(idx));
+  uint v_28 = (544u * uint(min(idx, 7u)));
   float scalar_f32 = asfloat(ub[(v_28 / 16u)][((v_28 % 16u) / 4u)]);
-  uint v_29 = (4u + (544u * uint(idx)));
+  uint v_29 = (4u + (544u * uint(min(idx, 7u))));
   int scalar_i32 = asint(ub[(v_29 / 16u)][((v_29 % 16u) / 4u)]);
-  uint v_30 = (8u + (544u * uint(idx)));
+  uint v_30 = (8u + (544u * uint(min(idx, 7u))));
   uint scalar_u32 = ub[(v_30 / 16u)][((v_30 % 16u) / 4u)];
-  uint v_31 = (16u + (544u * uint(idx)));
+  uint v_31 = (16u + (544u * uint(min(idx, 7u))));
   uint4 v_32 = ub[(v_31 / 16u)];
   float2 vec2_f32 = asfloat((((((v_31 % 16u) / 4u) == 2u)) ? (v_32.zw) : (v_32.xy)));
-  uint v_33 = (24u + (544u * uint(idx)));
+  uint v_33 = (24u + (544u * uint(min(idx, 7u))));
   uint4 v_34 = ub[(v_33 / 16u)];
   int2 vec2_i32 = asint((((((v_33 % 16u) / 4u) == 2u)) ? (v_34.zw) : (v_34.xy)));
-  uint v_35 = (32u + (544u * uint(idx)));
+  uint v_35 = (32u + (544u * uint(min(idx, 7u))));
   uint4 v_36 = ub[(v_35 / 16u)];
   uint2 vec2_u32 = (((((v_35 % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy));
-  uint v_37 = ((48u + (544u * uint(idx))) / 16u);
+  uint v_37 = ((48u + (544u * uint(min(idx, 7u)))) / 16u);
   float3 vec3_f32 = asfloat(ub[v_37].xyz);
-  uint v_38 = ((64u + (544u * uint(idx))) / 16u);
+  uint v_38 = ((64u + (544u * uint(min(idx, 7u)))) / 16u);
   int3 vec3_i32 = asint(ub[v_38].xyz);
-  uint v_39 = ((80u + (544u * uint(idx))) / 16u);
+  uint v_39 = ((80u + (544u * uint(min(idx, 7u)))) / 16u);
   uint3 vec3_u32 = ub[v_39].xyz;
-  uint v_40 = ((96u + (544u * uint(idx))) / 16u);
+  uint v_40 = ((96u + (544u * uint(min(idx, 7u)))) / 16u);
   float4 vec4_f32 = asfloat(ub[v_40]);
-  uint v_41 = ((112u + (544u * uint(idx))) / 16u);
+  uint v_41 = ((112u + (544u * uint(min(idx, 7u)))) / 16u);
   int4 vec4_i32 = asint(ub[v_41]);
-  uint v_42 = ((128u + (544u * uint(idx))) / 16u);
+  uint v_42 = ((128u + (544u * uint(min(idx, 7u)))) / 16u);
   uint4 vec4_u32 = ub[v_42];
-  float2x2 mat2x2_f32 = v_24((144u + (544u * uint(idx))));
-  float2x3 mat2x3_f32 = v_23((160u + (544u * uint(idx))));
-  float2x4 mat2x4_f32 = v_22((192u + (544u * uint(idx))));
-  float3x2 mat3x2_f32 = v_16((224u + (544u * uint(idx))));
-  float3x3 mat3x3_f32 = v_15((256u + (544u * uint(idx))));
-  float3x4 mat3x4_f32 = v_14((304u + (544u * uint(idx))));
-  float4x2 mat4x2_f32 = v_6((352u + (544u * uint(idx))));
-  float4x3 mat4x3_f32 = v_5((384u + (544u * uint(idx))));
-  float4x4 mat4x4_f32 = v_4((448u + (544u * uint(idx))));
-  float3 arr2_vec3_f32[2] = v((512u + (544u * uint(idx))));
+  float2x2 mat2x2_f32 = v_24((144u + (544u * uint(min(idx, 7u)))));
+  float2x3 mat2x3_f32 = v_23((160u + (544u * uint(min(idx, 7u)))));
+  float2x4 mat2x4_f32 = v_22((192u + (544u * uint(min(idx, 7u)))));
+  float3x2 mat3x2_f32 = v_16((224u + (544u * uint(min(idx, 7u)))));
+  float3x3 mat3x3_f32 = v_15((256u + (544u * uint(min(idx, 7u)))));
+  float3x4 mat3x4_f32 = v_14((304u + (544u * uint(min(idx, 7u)))));
+  float4x2 mat4x2_f32 = v_6((352u + (544u * uint(min(idx, 7u)))));
+  float4x3 mat4x3_f32 = v_5((384u + (544u * uint(min(idx, 7u)))));
+  float4x4 mat4x4_f32 = v_4((448u + (544u * uint(min(idx, 7u)))));
+  float3 arr2_vec3_f32[2] = v((512u + (544u * uint(min(idx, 7u)))));
   int v_43 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
   int v_44 = (v_43 + int(scalar_u32));
   int v_45 = ((v_44 + tint_f32_to_i32(vec2_f32.x)) + vec2_i32.x);
@@ -130,16 +130,16 @@
   int v_48 = (v_47 + int(vec3_u32.y));
   int v_49 = ((v_48 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_50 = (v_49 + int(vec4_u32.z));
-  int v_51 = (v_50 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_52 = (v_51 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_53 = (v_52 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_54 = (v_53 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_55 = (v_54 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_56 = (v_55 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_57 = (v_56 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_58 = (v_57 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_59 = (v_58 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((v_59 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x))));
+  int v_51 = (v_50 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_52 = (v_51 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_53 = (v_52 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_54 = (v_53 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_55 = (v_54 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_56 = (v_55 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_57 = (v_56 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_58 = (v_57 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_59 = (v_58 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((v_59 + tint_f32_to_i32(arr2_vec3_f32[0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.msl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.msl
index 092f6b3..9e7df51 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.ir.msl
@@ -68,37 +68,37 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  float const scalar_f32 = (*tint_module_vars.ub).arr[idx].scalar_f32;
-  int const scalar_i32 = (*tint_module_vars.ub).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*tint_module_vars.ub).arr[idx].scalar_u32;
-  float2 const vec2_f32 = (*tint_module_vars.ub).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*tint_module_vars.ub).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*tint_module_vars.ub).arr[idx].vec2_u32;
-  float3 const vec3_f32 = float3((*tint_module_vars.ub).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*tint_module_vars.ub).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*tint_module_vars.ub).arr[idx].vec3_u32);
-  float4 const vec4_f32 = (*tint_module_vars.ub).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*tint_module_vars.ub).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*tint_module_vars.ub).arr[idx].vec4_u32;
-  float2x2 const mat2x2_f32 = (*tint_module_vars.ub).arr[idx].mat2x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.ub).arr[idx].mat2x3_f32;
+  float const scalar_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_f32;
+  int const scalar_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_i32;
+  uint const scalar_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_u32;
+  float2 const vec2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_f32;
+  int2 const vec2_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_i32;
+  uint2 const vec2_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_u32;
+  float3 const vec3_f32 = float3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_f32);
+  int3 const vec3_i32 = int3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_i32);
+  uint3 const vec3_u32 = uint3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_u32);
+  float4 const vec4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_f32;
+  int4 const vec4_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_i32;
+  uint4 const vec4_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_u32;
+  float2x2 const mat2x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x3_f32;
   float3 const v_2 = float3(v_1[0u].packed);
   float2x3 const mat2x3_f32 = float2x3(v_2, float3(v_1[1u].packed));
-  float2x4 const mat2x4_f32 = (*tint_module_vars.ub).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*tint_module_vars.ub).arr[idx].mat3x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.ub).arr[idx].mat3x3_f32;
+  float2x4 const mat2x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x3_f32;
   float3 const v_4 = float3(v_3[0u].packed);
   float3 const v_5 = float3(v_3[1u].packed);
   float3x3 const mat3x3_f32 = float3x3(v_4, v_5, float3(v_3[2u].packed));
-  float3x4 const mat3x4_f32 = (*tint_module_vars.ub).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*tint_module_vars.ub).arr[idx].mat4x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.ub).arr[idx].mat4x3_f32;
+  float3x4 const mat3x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x3_f32;
   float3 const v_7 = float3(v_6[0u].packed);
   float3 const v_8 = float3(v_6[1u].packed);
   float3 const v_9 = float3(v_6[2u].packed);
   float4x3 const mat4x3_f32 = float4x3(v_7, v_8, v_9, float3(v_6[3u].packed));
-  float4x4 const mat4x4_f32 = (*tint_module_vars.ub).arr[idx].mat4x4_f32;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.ub).arr[idx].arr2_vec3_f32));
+  float4x4 const mat4x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x4_f32;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.ub).arr[min(idx, 7u)].arr2_vec3_f32));
   int const v_10 = as_type<int>((as_type<uint>(tint_f32_to_i32(scalar_f32)) + as_type<uint>(scalar_i32)));
   int const v_11 = as_type<int>((as_type<uint>(v_10) + as_type<uint>(int(scalar_u32))));
   int const v_12 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_11) + as_type<uint>(tint_f32_to_i32(vec2_f32[0u]))))) + as_type<uint>(vec2_i32[0u])));
@@ -107,16 +107,16 @@
   int const v_15 = as_type<int>((as_type<uint>(v_14) + as_type<uint>(int(vec3_u32[1u]))));
   int const v_16 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_15) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_17 = as_type<int>((as_type<uint>(v_16) + as_type<uint>(int(vec4_u32[2u]))));
-  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
+  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
 }
 
 kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const constant S_packed_vec3* ub [[buffer(0)]], device int* s [[buffer(1)]]) {
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.msl b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.msl
index fddc71c..9e06777 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.msl
@@ -108,28 +108,28 @@
 };
 
 void tint_symbol_inner(uint idx, const constant S_tint_packed_vec3* const tint_symbol_1, device int* const tint_symbol_2) {
-  float const scalar_f32 = (*(tint_symbol_1)).arr[idx].scalar_f32;
-  int const scalar_i32 = (*(tint_symbol_1)).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*(tint_symbol_1)).arr[idx].scalar_u32;
-  float2 const vec2_f32 = (*(tint_symbol_1)).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*(tint_symbol_1)).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[idx].vec2_u32;
-  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[idx].vec3_u32);
-  float4 const vec4_f32 = (*(tint_symbol_1)).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*(tint_symbol_1)).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[idx].vec4_u32;
-  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[idx].mat2x2_f32;
-  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[idx].mat2x3_f32);
-  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[idx].mat3x2_f32;
-  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[idx].mat3x3_f32);
-  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[idx].mat4x2_f32;
-  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[idx].mat4x3_f32);
-  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[idx].mat4x4_f32;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[idx].arr2_vec3_f32);
+  float const scalar_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_f32;
+  int const scalar_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_i32;
+  uint const scalar_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_u32;
+  float2 const vec2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_f32;
+  int2 const vec2_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_i32;
+  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_u32;
+  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_f32);
+  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_i32);
+  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_u32);
+  float4 const vec4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_f32;
+  int4 const vec4_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_i32;
+  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_u32;
+  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x2_f32;
+  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[min(idx, 7u)].mat2x3_f32);
+  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x2_f32;
+  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[min(idx, 7u)].mat3x3_f32);
+  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x2_f32;
+  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[min(idx, 7u)].mat4x3_f32);
+  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x4_f32;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[min(idx, 7u)].arr2_vec3_f32);
   *(tint_symbol_2) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))));
 }
 
diff --git a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.spvasm b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.spvasm
index d685c34..2476e6f 100644
--- a/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/dynamic_index/read.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 242
+; Bound: 265
 ; Schema: 0
                OpCapability Shader
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -161,6 +162,7 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %33 = OpTypeFunction %void %uint
+     %uint_7 = OpConstant %uint 7
 %_ptr_Uniform_float = OpTypePointer Uniform %float
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
@@ -175,7 +177,6 @@
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_6 = OpConstant %uint 6
 %_ptr_Uniform_v3int = OpTypePointer Uniform %v3int
-     %uint_7 = OpConstant %uint 7
 %_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
      %uint_9 = OpConstant %uint 9
@@ -216,165 +217,187 @@
 %_ptr_Uniform__arr_v3float_uint_2 = OpTypePointer Uniform %_arr_v3float_uint_2
     %uint_33 = OpConstant %uint 33
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %225 = OpTypeFunction %int %float
+        %248 = OpTypeFunction %int %float
 %float_n2_14748365e_09 = OpConstant %float -2.14748365e+09
        %bool = OpTypeBool
 %int_n2147483648 = OpConstant %int -2147483648
 %float_2_14748352e_09 = OpConstant %float 2.14748352e+09
 %int_2147483647 = OpConstant %int 2147483647
-        %238 = OpTypeFunction %void
+        %261 = OpTypeFunction %void
  %main_inner = OpFunction %void None %33
         %idx = OpFunctionParameter %uint
          %34 = OpLabel
-         %35 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0 %idx %uint_0
- %scalar_f32 = OpLoad %float %35 None
-         %39 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0 %idx %uint_1
- %scalar_i32 = OpLoad %int %39 None
-         %43 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0 %idx %uint_2
- %scalar_u32 = OpLoad %uint %43 None
-         %46 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_3
-   %vec2_f32 = OpLoad %v2float %46 None
-         %50 = OpAccessChain %_ptr_Uniform_v2int %1 %uint_0 %uint_0 %idx %uint_4
-   %vec2_i32 = OpLoad %v2int %50 None
-         %54 = OpAccessChain %_ptr_Uniform_v2uint %1 %uint_0 %uint_0 %idx %uint_5
-   %vec2_u32 = OpLoad %v2uint %54 None
-         %58 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_6
-   %vec3_f32 = OpLoad %v3float %58 None
-         %62 = OpAccessChain %_ptr_Uniform_v3int %1 %uint_0 %uint_0 %idx %uint_7
-   %vec3_i32 = OpLoad %v3int %62 None
-         %66 = OpAccessChain %_ptr_Uniform_v3uint %1 %uint_0 %uint_0 %idx %uint_8
-   %vec3_u32 = OpLoad %v3uint %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %idx %uint_9
-   %vec4_f32 = OpLoad %v4float %69 None
-         %73 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %idx %uint_10
-   %vec4_i32 = OpLoad %v4int %73 None
-         %77 = OpAccessChain %_ptr_Uniform_v4uint %1 %uint_0 %uint_0 %idx %uint_11
-   %vec4_u32 = OpLoad %v4uint %77 None
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_12
-         %83 = OpLoad %v2float %81 None
-         %84 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_13
-         %86 = OpLoad %v2float %84 None
- %mat2x2_f32 = OpCompositeConstruct %mat2v2float %83 %86
-         %89 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_14
-         %91 = OpLoad %v3float %89 None
-         %92 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_15
-         %94 = OpLoad %v3float %92 None
- %mat2x3_f32 = OpCompositeConstruct %mat2v3float %91 %94
-         %97 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_0 %idx %uint_16
- %mat2x4_f32 = OpLoad %mat2v4float %97 None
-        %101 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_17
-        %103 = OpLoad %v2float %101 None
-        %104 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_18
-        %106 = OpLoad %v2float %104 None
-        %107 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_19
-        %109 = OpLoad %v2float %107 None
- %mat3x2_f32 = OpCompositeConstruct %mat3v2float %103 %106 %109
-        %112 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_20
-        %114 = OpLoad %v3float %112 None
-        %115 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_21
-        %117 = OpLoad %v3float %115 None
-        %118 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_22
-        %120 = OpLoad %v3float %118 None
- %mat3x3_f32 = OpCompositeConstruct %mat3v3float %114 %117 %120
-        %123 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_0 %idx %uint_23
- %mat3x4_f32 = OpLoad %mat3v4float %123 None
-        %127 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_24
-        %129 = OpLoad %v2float %127 None
-        %130 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_25
-        %132 = OpLoad %v2float %130 None
-        %133 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_26
-        %135 = OpLoad %v2float %133 None
-        %136 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_27
-        %138 = OpLoad %v2float %136 None
- %mat4x2_f32 = OpCompositeConstruct %mat4v2float %129 %132 %135 %138
-        %141 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_28
-        %143 = OpLoad %v3float %141 None
-        %144 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_29
-        %146 = OpLoad %v3float %144 None
-        %147 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_30
-        %149 = OpLoad %v3float %147 None
-        %150 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_31
-        %152 = OpLoad %v3float %150 None
- %mat4x3_f32 = OpCompositeConstruct %mat4v3float %143 %146 %149 %152
-        %155 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_0 %idx %uint_32
- %mat4x4_f32 = OpLoad %mat4v4float %155 None
-        %159 = OpAccessChain %_ptr_Uniform__arr_v3float_uint_2 %1 %uint_0 %uint_0 %idx %uint_33
-%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %159 None
-        %163 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
-        %165 = OpIAdd %int %163 %scalar_i32
-        %166 = OpBitcast %int %scalar_u32
-        %167 = OpIAdd %int %165 %166
-        %168 = OpCompositeExtract %float %vec2_f32 0
-        %169 = OpFunctionCall %int %tint_f32_to_i32 %168
-        %170 = OpIAdd %int %167 %169
-        %171 = OpCompositeExtract %int %vec2_i32 0
-        %172 = OpIAdd %int %170 %171
-        %173 = OpCompositeExtract %uint %vec2_u32 0
-        %174 = OpBitcast %int %173
-        %175 = OpIAdd %int %172 %174
-        %176 = OpCompositeExtract %float %vec3_f32 1
-        %177 = OpFunctionCall %int %tint_f32_to_i32 %176
-        %178 = OpIAdd %int %175 %177
-        %179 = OpCompositeExtract %int %vec3_i32 1
-        %180 = OpIAdd %int %178 %179
-        %181 = OpCompositeExtract %uint %vec3_u32 1
-        %182 = OpBitcast %int %181
-        %183 = OpIAdd %int %180 %182
-        %184 = OpCompositeExtract %float %vec4_f32 2
-        %185 = OpFunctionCall %int %tint_f32_to_i32 %184
-        %186 = OpIAdd %int %183 %185
-        %187 = OpCompositeExtract %int %vec4_i32 2
-        %188 = OpIAdd %int %186 %187
-        %189 = OpCompositeExtract %uint %vec4_u32 2
-        %190 = OpBitcast %int %189
-        %191 = OpIAdd %int %188 %190
-        %192 = OpCompositeExtract %float %mat2x2_f32 0 0
-        %193 = OpFunctionCall %int %tint_f32_to_i32 %192
-        %194 = OpIAdd %int %191 %193
-        %195 = OpCompositeExtract %float %mat2x3_f32 0 0
-        %196 = OpFunctionCall %int %tint_f32_to_i32 %195
-        %197 = OpIAdd %int %194 %196
-        %198 = OpCompositeExtract %float %mat2x4_f32 0 0
-        %199 = OpFunctionCall %int %tint_f32_to_i32 %198
-        %200 = OpIAdd %int %197 %199
-        %201 = OpCompositeExtract %float %mat3x2_f32 0 0
-        %202 = OpFunctionCall %int %tint_f32_to_i32 %201
-        %203 = OpIAdd %int %200 %202
-        %204 = OpCompositeExtract %float %mat3x3_f32 0 0
-        %205 = OpFunctionCall %int %tint_f32_to_i32 %204
+         %35 = OpExtInst %uint %36 UMin %idx %uint_7
+         %38 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0 %35 %uint_0
+ %scalar_f32 = OpLoad %float %38 None
+         %42 = OpExtInst %uint %36 UMin %idx %uint_7
+         %43 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0 %42 %uint_1
+ %scalar_i32 = OpLoad %int %43 None
+         %47 = OpExtInst %uint %36 UMin %idx %uint_7
+         %48 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0 %47 %uint_2
+ %scalar_u32 = OpLoad %uint %48 None
+         %51 = OpExtInst %uint %36 UMin %idx %uint_7
+         %52 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %51 %uint_3
+   %vec2_f32 = OpLoad %v2float %52 None
+         %56 = OpExtInst %uint %36 UMin %idx %uint_7
+         %57 = OpAccessChain %_ptr_Uniform_v2int %1 %uint_0 %uint_0 %56 %uint_4
+   %vec2_i32 = OpLoad %v2int %57 None
+         %61 = OpExtInst %uint %36 UMin %idx %uint_7
+         %62 = OpAccessChain %_ptr_Uniform_v2uint %1 %uint_0 %uint_0 %61 %uint_5
+   %vec2_u32 = OpLoad %v2uint %62 None
+         %66 = OpExtInst %uint %36 UMin %idx %uint_7
+         %67 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %66 %uint_6
+   %vec3_f32 = OpLoad %v3float %67 None
+         %71 = OpExtInst %uint %36 UMin %idx %uint_7
+         %72 = OpAccessChain %_ptr_Uniform_v3int %1 %uint_0 %uint_0 %71 %uint_7
+   %vec3_i32 = OpLoad %v3int %72 None
+         %75 = OpExtInst %uint %36 UMin %idx %uint_7
+         %76 = OpAccessChain %_ptr_Uniform_v3uint %1 %uint_0 %uint_0 %75 %uint_8
+   %vec3_u32 = OpLoad %v3uint %76 None
+         %79 = OpExtInst %uint %36 UMin %idx %uint_7
+         %80 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %79 %uint_9
+   %vec4_f32 = OpLoad %v4float %80 None
+         %84 = OpExtInst %uint %36 UMin %idx %uint_7
+         %85 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %84 %uint_10
+   %vec4_i32 = OpLoad %v4int %85 None
+         %89 = OpExtInst %uint %36 UMin %idx %uint_7
+         %90 = OpAccessChain %_ptr_Uniform_v4uint %1 %uint_0 %uint_0 %89 %uint_11
+   %vec4_u32 = OpLoad %v4uint %90 None
+         %94 = OpExtInst %uint %36 UMin %idx %uint_7
+         %95 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %94 %uint_12
+         %97 = OpLoad %v2float %95 None
+         %98 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %94 %uint_13
+        %100 = OpLoad %v2float %98 None
+ %mat2x2_f32 = OpCompositeConstruct %mat2v2float %97 %100
+        %103 = OpExtInst %uint %36 UMin %idx %uint_7
+        %104 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %103 %uint_14
+        %106 = OpLoad %v3float %104 None
+        %107 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %103 %uint_15
+        %109 = OpLoad %v3float %107 None
+ %mat2x3_f32 = OpCompositeConstruct %mat2v3float %106 %109
+        %112 = OpExtInst %uint %36 UMin %idx %uint_7
+        %113 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_0 %112 %uint_16
+ %mat2x4_f32 = OpLoad %mat2v4float %113 None
+        %117 = OpExtInst %uint %36 UMin %idx %uint_7
+        %118 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %117 %uint_17
+        %120 = OpLoad %v2float %118 None
+        %121 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %117 %uint_18
+        %123 = OpLoad %v2float %121 None
+        %124 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %117 %uint_19
+        %126 = OpLoad %v2float %124 None
+ %mat3x2_f32 = OpCompositeConstruct %mat3v2float %120 %123 %126
+        %129 = OpExtInst %uint %36 UMin %idx %uint_7
+        %130 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %129 %uint_20
+        %132 = OpLoad %v3float %130 None
+        %133 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %129 %uint_21
+        %135 = OpLoad %v3float %133 None
+        %136 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %129 %uint_22
+        %138 = OpLoad %v3float %136 None
+ %mat3x3_f32 = OpCompositeConstruct %mat3v3float %132 %135 %138
+        %141 = OpExtInst %uint %36 UMin %idx %uint_7
+        %142 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_0 %141 %uint_23
+ %mat3x4_f32 = OpLoad %mat3v4float %142 None
+        %146 = OpExtInst %uint %36 UMin %idx %uint_7
+        %147 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %146 %uint_24
+        %149 = OpLoad %v2float %147 None
+        %150 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %146 %uint_25
+        %152 = OpLoad %v2float %150 None
+        %153 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %146 %uint_26
+        %155 = OpLoad %v2float %153 None
+        %156 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %146 %uint_27
+        %158 = OpLoad %v2float %156 None
+ %mat4x2_f32 = OpCompositeConstruct %mat4v2float %149 %152 %155 %158
+        %161 = OpExtInst %uint %36 UMin %idx %uint_7
+        %162 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %161 %uint_28
+        %164 = OpLoad %v3float %162 None
+        %165 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %161 %uint_29
+        %167 = OpLoad %v3float %165 None
+        %168 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %161 %uint_30
+        %170 = OpLoad %v3float %168 None
+        %171 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %161 %uint_31
+        %173 = OpLoad %v3float %171 None
+ %mat4x3_f32 = OpCompositeConstruct %mat4v3float %164 %167 %170 %173
+        %176 = OpExtInst %uint %36 UMin %idx %uint_7
+        %177 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_0 %176 %uint_32
+ %mat4x4_f32 = OpLoad %mat4v4float %177 None
+        %181 = OpExtInst %uint %36 UMin %idx %uint_7
+        %182 = OpAccessChain %_ptr_Uniform__arr_v3float_uint_2 %1 %uint_0 %uint_0 %181 %uint_33
+%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %182 None
+        %186 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
+        %188 = OpIAdd %int %186 %scalar_i32
+        %189 = OpBitcast %int %scalar_u32
+        %190 = OpIAdd %int %188 %189
+        %191 = OpCompositeExtract %float %vec2_f32 0
+        %192 = OpFunctionCall %int %tint_f32_to_i32 %191
+        %193 = OpIAdd %int %190 %192
+        %194 = OpCompositeExtract %int %vec2_i32 0
+        %195 = OpIAdd %int %193 %194
+        %196 = OpCompositeExtract %uint %vec2_u32 0
+        %197 = OpBitcast %int %196
+        %198 = OpIAdd %int %195 %197
+        %199 = OpCompositeExtract %float %vec3_f32 1
+        %200 = OpFunctionCall %int %tint_f32_to_i32 %199
+        %201 = OpIAdd %int %198 %200
+        %202 = OpCompositeExtract %int %vec3_i32 1
+        %203 = OpIAdd %int %201 %202
+        %204 = OpCompositeExtract %uint %vec3_u32 1
+        %205 = OpBitcast %int %204
         %206 = OpIAdd %int %203 %205
-        %207 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %207 = OpCompositeExtract %float %vec4_f32 2
         %208 = OpFunctionCall %int %tint_f32_to_i32 %207
         %209 = OpIAdd %int %206 %208
-        %210 = OpCompositeExtract %float %mat4x2_f32 0 0
-        %211 = OpFunctionCall %int %tint_f32_to_i32 %210
-        %212 = OpIAdd %int %209 %211
-        %213 = OpCompositeExtract %float %mat4x3_f32 0 0
-        %214 = OpFunctionCall %int %tint_f32_to_i32 %213
-        %215 = OpIAdd %int %212 %214
-        %216 = OpCompositeExtract %float %mat4x4_f32 0 0
-        %217 = OpFunctionCall %int %tint_f32_to_i32 %216
-        %218 = OpIAdd %int %215 %217
-        %219 = OpCompositeExtract %float %arr2_vec3_f32 0 0
-        %220 = OpFunctionCall %int %tint_f32_to_i32 %219
-        %221 = OpIAdd %int %218 %220
-        %222 = OpAccessChain %_ptr_StorageBuffer_int %25 %uint_0
-               OpStore %222 %221 None
+        %210 = OpCompositeExtract %int %vec4_i32 2
+        %211 = OpIAdd %int %209 %210
+        %212 = OpCompositeExtract %uint %vec4_u32 2
+        %213 = OpBitcast %int %212
+        %214 = OpIAdd %int %211 %213
+        %215 = OpCompositeExtract %float %mat2x2_f32 0 0
+        %216 = OpFunctionCall %int %tint_f32_to_i32 %215
+        %217 = OpIAdd %int %214 %216
+        %218 = OpCompositeExtract %float %mat2x3_f32 0 0
+        %219 = OpFunctionCall %int %tint_f32_to_i32 %218
+        %220 = OpIAdd %int %217 %219
+        %221 = OpCompositeExtract %float %mat2x4_f32 0 0
+        %222 = OpFunctionCall %int %tint_f32_to_i32 %221
+        %223 = OpIAdd %int %220 %222
+        %224 = OpCompositeExtract %float %mat3x2_f32 0 0
+        %225 = OpFunctionCall %int %tint_f32_to_i32 %224
+        %226 = OpIAdd %int %223 %225
+        %227 = OpCompositeExtract %float %mat3x3_f32 0 0
+        %228 = OpFunctionCall %int %tint_f32_to_i32 %227
+        %229 = OpIAdd %int %226 %228
+        %230 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %231 = OpFunctionCall %int %tint_f32_to_i32 %230
+        %232 = OpIAdd %int %229 %231
+        %233 = OpCompositeExtract %float %mat4x2_f32 0 0
+        %234 = OpFunctionCall %int %tint_f32_to_i32 %233
+        %235 = OpIAdd %int %232 %234
+        %236 = OpCompositeExtract %float %mat4x3_f32 0 0
+        %237 = OpFunctionCall %int %tint_f32_to_i32 %236
+        %238 = OpIAdd %int %235 %237
+        %239 = OpCompositeExtract %float %mat4x4_f32 0 0
+        %240 = OpFunctionCall %int %tint_f32_to_i32 %239
+        %241 = OpIAdd %int %238 %240
+        %242 = OpCompositeExtract %float %arr2_vec3_f32 0 0
+        %243 = OpFunctionCall %int %tint_f32_to_i32 %242
+        %244 = OpIAdd %int %241 %243
+        %245 = OpAccessChain %_ptr_StorageBuffer_int %25 %uint_0
+               OpStore %245 %244 None
                OpReturn
                OpFunctionEnd
-%tint_f32_to_i32 = OpFunction %int None %225
+%tint_f32_to_i32 = OpFunction %int None %248
       %value = OpFunctionParameter %float
-        %226 = OpLabel
-        %227 = OpConvertFToS %int %value
-        %228 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
-        %231 = OpSelect %int %228 %227 %int_n2147483648
-        %233 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
-        %235 = OpSelect %int %233 %231 %int_2147483647
-               OpReturnValue %235
+        %249 = OpLabel
+        %250 = OpConvertFToS %int %value
+        %251 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
+        %254 = OpSelect %int %251 %250 %int_n2147483648
+        %256 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
+        %258 = OpSelect %int %256 %254 %int_2147483647
+               OpReturnValue %258
                OpFunctionEnd
-       %main = OpFunction %void None %238
-        %239 = OpLabel
-        %240 = OpLoad %uint %main_local_invocation_index_Input None
-        %241 = OpFunctionCall %void %main_inner %240
+       %main = OpFunction %void None %261
+        %262 = OpLabel
+        %263 = OpLoad %uint %main_local_invocation_index_Input None
+        %264 = OpFunctionCall %void %main_inner %263
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
index 99e5b22..ab86fe9 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.dxc.hlsl
@@ -251,71 +251,71 @@
 }
 
 void main_inner(uint idx) {
-  const uint scalar_offset_55 = ((800u * idx)) / 4;
+  const uint scalar_offset_55 = ((800u * min(idx, 7u))) / 4;
   float scalar_f32 = asfloat(ub[scalar_offset_55 / 4][scalar_offset_55 % 4]);
-  const uint scalar_offset_56 = (((800u * idx) + 4u)) / 4;
+  const uint scalar_offset_56 = (((800u * min(idx, 7u)) + 4u)) / 4;
   int scalar_i32 = asint(ub[scalar_offset_56 / 4][scalar_offset_56 % 4]);
-  const uint scalar_offset_57 = (((800u * idx) + 8u)) / 4;
+  const uint scalar_offset_57 = (((800u * min(idx, 7u)) + 8u)) / 4;
   uint scalar_u32 = ub[scalar_offset_57 / 4][scalar_offset_57 % 4];
-  const uint scalar_offset_bytes = (((800u * idx) + 12u));
+  const uint scalar_offset_bytes = (((800u * min(idx, 7u)) + 12u));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t scalar_f16 = float16_t(f16tof32(((ub[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
-  const uint scalar_offset_58 = (((800u * idx) + 16u)) / 4;
+  const uint scalar_offset_58 = (((800u * min(idx, 7u)) + 16u)) / 4;
   uint4 ubo_load_54 = ub[scalar_offset_58 / 4];
   float2 vec2_f32 = asfloat(((scalar_offset_58 & 2) ? ubo_load_54.zw : ubo_load_54.xy));
-  const uint scalar_offset_59 = (((800u * idx) + 24u)) / 4;
+  const uint scalar_offset_59 = (((800u * min(idx, 7u)) + 24u)) / 4;
   uint4 ubo_load_55 = ub[scalar_offset_59 / 4];
   int2 vec2_i32 = asint(((scalar_offset_59 & 2) ? ubo_load_55.zw : ubo_load_55.xy));
-  const uint scalar_offset_60 = (((800u * idx) + 32u)) / 4;
+  const uint scalar_offset_60 = (((800u * min(idx, 7u)) + 32u)) / 4;
   uint4 ubo_load_56 = ub[scalar_offset_60 / 4];
   uint2 vec2_u32 = ((scalar_offset_60 & 2) ? ubo_load_56.zw : ubo_load_56.xy);
-  const uint scalar_offset_61 = (((800u * idx) + 40u)) / 4;
+  const uint scalar_offset_61 = (((800u * min(idx, 7u)) + 40u)) / 4;
   uint ubo_load_57 = ub[scalar_offset_61 / 4][scalar_offset_61 % 4];
   vector<float16_t, 2> vec2_f16 = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_57 & 0xFFFF)), float16_t(f16tof32(ubo_load_57 >> 16)));
-  const uint scalar_offset_62 = (((800u * idx) + 48u)) / 4;
+  const uint scalar_offset_62 = (((800u * min(idx, 7u)) + 48u)) / 4;
   float3 vec3_f32 = asfloat(ub[scalar_offset_62 / 4].xyz);
-  const uint scalar_offset_63 = (((800u * idx) + 64u)) / 4;
+  const uint scalar_offset_63 = (((800u * min(idx, 7u)) + 64u)) / 4;
   int3 vec3_i32 = asint(ub[scalar_offset_63 / 4].xyz);
-  const uint scalar_offset_64 = (((800u * idx) + 80u)) / 4;
+  const uint scalar_offset_64 = (((800u * min(idx, 7u)) + 80u)) / 4;
   uint3 vec3_u32 = ub[scalar_offset_64 / 4].xyz;
-  const uint scalar_offset_65 = (((800u * idx) + 96u)) / 4;
+  const uint scalar_offset_65 = (((800u * min(idx, 7u)) + 96u)) / 4;
   uint4 ubo_load_59 = ub[scalar_offset_65 / 4];
   uint2 ubo_load_58 = ((scalar_offset_65 & 2) ? ubo_load_59.zw : ubo_load_59.xy);
   vector<float16_t, 2> ubo_load_58_xz = vector<float16_t, 2>(f16tof32(ubo_load_58 & 0xFFFF));
   float16_t ubo_load_58_y = f16tof32(ubo_load_58[0] >> 16);
   vector<float16_t, 3> vec3_f16 = vector<float16_t, 3>(ubo_load_58_xz[0], ubo_load_58_y, ubo_load_58_xz[1]);
-  const uint scalar_offset_66 = (((800u * idx) + 112u)) / 4;
+  const uint scalar_offset_66 = (((800u * min(idx, 7u)) + 112u)) / 4;
   float4 vec4_f32 = asfloat(ub[scalar_offset_66 / 4]);
-  const uint scalar_offset_67 = (((800u * idx) + 128u)) / 4;
+  const uint scalar_offset_67 = (((800u * min(idx, 7u)) + 128u)) / 4;
   int4 vec4_i32 = asint(ub[scalar_offset_67 / 4]);
-  const uint scalar_offset_68 = (((800u * idx) + 144u)) / 4;
+  const uint scalar_offset_68 = (((800u * min(idx, 7u)) + 144u)) / 4;
   uint4 vec4_u32 = ub[scalar_offset_68 / 4];
-  const uint scalar_offset_69 = (((800u * idx) + 160u)) / 4;
+  const uint scalar_offset_69 = (((800u * min(idx, 7u)) + 160u)) / 4;
   uint4 ubo_load_61 = ub[scalar_offset_69 / 4];
   uint2 ubo_load_60 = ((scalar_offset_69 & 2) ? ubo_load_61.zw : ubo_load_61.xy);
   vector<float16_t, 2> ubo_load_60_xz = vector<float16_t, 2>(f16tof32(ubo_load_60 & 0xFFFF));
   vector<float16_t, 2> ubo_load_60_yw = vector<float16_t, 2>(f16tof32(ubo_load_60 >> 16));
   vector<float16_t, 4> vec4_f16 = vector<float16_t, 4>(ubo_load_60_xz[0], ubo_load_60_yw[0], ubo_load_60_xz[1], ubo_load_60_yw[1]);
-  float2x2 mat2x2_f32 = ub_load_16(((800u * idx) + 168u));
-  float2x3 mat2x3_f32 = ub_load_17(((800u * idx) + 192u));
-  float2x4 mat2x4_f32 = ub_load_18(((800u * idx) + 224u));
-  float3x2 mat3x2_f32 = ub_load_19(((800u * idx) + 256u));
-  float3x3 mat3x3_f32 = ub_load_20(((800u * idx) + 288u));
-  float3x4 mat3x4_f32 = ub_load_21(((800u * idx) + 336u));
-  float4x2 mat4x2_f32 = ub_load_22(((800u * idx) + 384u));
-  float4x3 mat4x3_f32 = ub_load_23(((800u * idx) + 416u));
-  float4x4 mat4x4_f32 = ub_load_24(((800u * idx) + 480u));
-  matrix<float16_t, 2, 2> mat2x2_f16 = ub_load_25(((800u * idx) + 544u));
-  matrix<float16_t, 2, 3> mat2x3_f16 = ub_load_26(((800u * idx) + 552u));
-  matrix<float16_t, 2, 4> mat2x4_f16 = ub_load_27(((800u * idx) + 568u));
-  matrix<float16_t, 3, 2> mat3x2_f16 = ub_load_28(((800u * idx) + 584u));
-  matrix<float16_t, 3, 3> mat3x3_f16 = ub_load_29(((800u * idx) + 600u));
-  matrix<float16_t, 3, 4> mat3x4_f16 = ub_load_30(((800u * idx) + 624u));
-  matrix<float16_t, 4, 2> mat4x2_f16 = ub_load_31(((800u * idx) + 648u));
-  matrix<float16_t, 4, 3> mat4x3_f16 = ub_load_32(((800u * idx) + 664u));
-  matrix<float16_t, 4, 4> mat4x4_f16 = ub_load_33(((800u * idx) + 696u));
-  float3 arr2_vec3_f32[2] = ub_load_34(((800u * idx) + 736u));
-  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = ub_load_35(((800u * idx) + 768u));
+  float2x2 mat2x2_f32 = ub_load_16(((800u * min(idx, 7u)) + 168u));
+  float2x3 mat2x3_f32 = ub_load_17(((800u * min(idx, 7u)) + 192u));
+  float2x4 mat2x4_f32 = ub_load_18(((800u * min(idx, 7u)) + 224u));
+  float3x2 mat3x2_f32 = ub_load_19(((800u * min(idx, 7u)) + 256u));
+  float3x3 mat3x3_f32 = ub_load_20(((800u * min(idx, 7u)) + 288u));
+  float3x4 mat3x4_f32 = ub_load_21(((800u * min(idx, 7u)) + 336u));
+  float4x2 mat4x2_f32 = ub_load_22(((800u * min(idx, 7u)) + 384u));
+  float4x3 mat4x3_f32 = ub_load_23(((800u * min(idx, 7u)) + 416u));
+  float4x4 mat4x4_f32 = ub_load_24(((800u * min(idx, 7u)) + 480u));
+  matrix<float16_t, 2, 2> mat2x2_f16 = ub_load_25(((800u * min(idx, 7u)) + 544u));
+  matrix<float16_t, 2, 3> mat2x3_f16 = ub_load_26(((800u * min(idx, 7u)) + 552u));
+  matrix<float16_t, 2, 4> mat2x4_f16 = ub_load_27(((800u * min(idx, 7u)) + 568u));
+  matrix<float16_t, 3, 2> mat3x2_f16 = ub_load_28(((800u * min(idx, 7u)) + 584u));
+  matrix<float16_t, 3, 3> mat3x3_f16 = ub_load_29(((800u * min(idx, 7u)) + 600u));
+  matrix<float16_t, 3, 4> mat3x4_f16 = ub_load_30(((800u * min(idx, 7u)) + 624u));
+  matrix<float16_t, 4, 2> mat4x2_f16 = ub_load_31(((800u * min(idx, 7u)) + 648u));
+  matrix<float16_t, 4, 3> mat4x3_f16 = ub_load_32(((800u * min(idx, 7u)) + 664u));
+  matrix<float16_t, 4, 4> mat4x4_f16 = ub_load_33(((800u * min(idx, 7u)) + 696u));
+  float3 arr2_vec3_f32[2] = ub_load_34(((800u * min(idx, 7u)) + 736u));
+  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = ub_load_35(((800u * min(idx, 7u)) + 768u));
   s.Store(0u, asuint((((((((((((((((((((((((((((((((((((tint_ftoi(scalar_f32) + scalar_i32) + int(scalar_u32)) + int(scalar_f16)) + tint_ftoi(vec2_f32.x)) + vec2_i32.x) + int(vec2_u32.x)) + int(vec2_f16.x)) + tint_ftoi(vec3_f32.y)) + vec3_i32.y) + int(vec3_u32.y)) + int(vec3_f16.y)) + tint_ftoi(vec4_f32.z)) + vec4_i32.z) + int(vec4_u32.z)) + int(vec4_f16.z)) + tint_ftoi(mat2x2_f32[0].x)) + tint_ftoi(mat2x3_f32[0].x)) + tint_ftoi(mat2x4_f32[0].x)) + tint_ftoi(mat3x2_f32[0].x)) + tint_ftoi(mat3x3_f32[0].x)) + tint_ftoi(mat3x4_f32[0].x)) + tint_ftoi(mat4x2_f32[0].x)) + tint_ftoi(mat4x3_f32[0].x)) + tint_ftoi(mat4x4_f32[0].x)) + int(mat2x2_f16[0].x)) + int(mat2x3_f16[0].x)) + int(mat2x4_f16[0].x)) + int(mat3x2_f16[0].x)) + int(mat3x3_f16[0].x)) + int(mat3x4_f16[0].x)) + int(mat4x2_f16[0].x)) + int(mat4x3_f16[0].x)) + int(mat4x4_f16[0].x)) + tint_ftoi(arr2_vec3_f32[0].x)) + int(arr2_mat4x2_f16[0][0].x))));
 }
 
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.glsl b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.glsl
index c6967b2..71c29f3 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.glsl
@@ -119,42 +119,42 @@
   return mix(2147483647, mix((-2147483647 - 1), int(value), (value >= -2147483648.0f)), (value <= 2147483520.0f));
 }
 void tint_symbol_inner(uint idx) {
-  float scalar_f32 = v.inner.arr[idx].scalar_f32;
-  int scalar_i32 = v.inner.arr[idx].scalar_i32;
-  uint scalar_u32 = v.inner.arr[idx].scalar_u32;
-  float16_t scalar_f16 = v.inner.arr[idx].scalar_f16;
-  vec2 vec2_f32 = v.inner.arr[idx].vec2_f32;
-  ivec2 vec2_i32 = v.inner.arr[idx].vec2_i32;
-  uvec2 vec2_u32 = v.inner.arr[idx].vec2_u32;
-  f16vec2 vec2_f16 = v.inner.arr[idx].vec2_f16;
-  vec3 vec3_f32 = v.inner.arr[idx].vec3_f32;
-  ivec3 vec3_i32 = v.inner.arr[idx].vec3_i32;
-  uvec3 vec3_u32 = v.inner.arr[idx].vec3_u32;
-  f16vec3 vec3_f16 = v.inner.arr[idx].vec3_f16;
-  vec4 vec4_f32 = v.inner.arr[idx].vec4_f32;
-  ivec4 vec4_i32 = v.inner.arr[idx].vec4_i32;
-  uvec4 vec4_u32 = v.inner.arr[idx].vec4_u32;
-  f16vec4 vec4_f16 = v.inner.arr[idx].vec4_f16;
-  mat2 mat2x2_f32 = mat2(v.inner.arr[idx].mat2x2_f32_col0, v.inner.arr[idx].mat2x2_f32_col1);
-  mat2x3 mat2x3_f32 = mat2x3(v.inner.arr[idx].mat2x3_f32_col0, v.inner.arr[idx].mat2x3_f32_col1);
-  mat2x4 mat2x4_f32 = v.inner.arr[idx].mat2x4_f32;
-  mat3x2 mat3x2_f32 = mat3x2(v.inner.arr[idx].mat3x2_f32_col0, v.inner.arr[idx].mat3x2_f32_col1, v.inner.arr[idx].mat3x2_f32_col2);
-  mat3 mat3x3_f32 = mat3(v.inner.arr[idx].mat3x3_f32_col0, v.inner.arr[idx].mat3x3_f32_col1, v.inner.arr[idx].mat3x3_f32_col2);
-  mat3x4 mat3x4_f32 = v.inner.arr[idx].mat3x4_f32;
-  mat4x2 mat4x2_f32 = mat4x2(v.inner.arr[idx].mat4x2_f32_col0, v.inner.arr[idx].mat4x2_f32_col1, v.inner.arr[idx].mat4x2_f32_col2, v.inner.arr[idx].mat4x2_f32_col3);
-  mat4x3 mat4x3_f32 = mat4x3(v.inner.arr[idx].mat4x3_f32_col0, v.inner.arr[idx].mat4x3_f32_col1, v.inner.arr[idx].mat4x3_f32_col2, v.inner.arr[idx].mat4x3_f32_col3);
-  mat4 mat4x4_f32 = v.inner.arr[idx].mat4x4_f32;
-  f16mat2 mat2x2_f16 = f16mat2(v.inner.arr[idx].mat2x2_f16_col0, v.inner.arr[idx].mat2x2_f16_col1);
-  f16mat2x3 mat2x3_f16 = f16mat2x3(v.inner.arr[idx].mat2x3_f16_col0, v.inner.arr[idx].mat2x3_f16_col1);
-  f16mat2x4 mat2x4_f16 = f16mat2x4(v.inner.arr[idx].mat2x4_f16_col0, v.inner.arr[idx].mat2x4_f16_col1);
-  f16mat3x2 mat3x2_f16 = f16mat3x2(v.inner.arr[idx].mat3x2_f16_col0, v.inner.arr[idx].mat3x2_f16_col1, v.inner.arr[idx].mat3x2_f16_col2);
-  f16mat3 mat3x3_f16 = f16mat3(v.inner.arr[idx].mat3x3_f16_col0, v.inner.arr[idx].mat3x3_f16_col1, v.inner.arr[idx].mat3x3_f16_col2);
-  f16mat3x4 mat3x4_f16 = f16mat3x4(v.inner.arr[idx].mat3x4_f16_col0, v.inner.arr[idx].mat3x4_f16_col1, v.inner.arr[idx].mat3x4_f16_col2);
-  f16mat4x2 mat4x2_f16 = f16mat4x2(v.inner.arr[idx].mat4x2_f16_col0, v.inner.arr[idx].mat4x2_f16_col1, v.inner.arr[idx].mat4x2_f16_col2, v.inner.arr[idx].mat4x2_f16_col3);
-  f16mat4x3 mat4x3_f16 = f16mat4x3(v.inner.arr[idx].mat4x3_f16_col0, v.inner.arr[idx].mat4x3_f16_col1, v.inner.arr[idx].mat4x3_f16_col2, v.inner.arr[idx].mat4x3_f16_col3);
-  f16mat4 mat4x4_f16 = f16mat4(v.inner.arr[idx].mat4x4_f16_col0, v.inner.arr[idx].mat4x4_f16_col1, v.inner.arr[idx].mat4x4_f16_col2, v.inner.arr[idx].mat4x4_f16_col3);
-  vec3 arr2_vec3_f32[2] = v.inner.arr[idx].arr2_vec3_f32;
-  mat4x2_f16_std140 v_2[2] = v.inner.arr[idx].arr2_mat4x2_f16;
+  float scalar_f32 = v.inner.arr[min(idx, 7u)].scalar_f32;
+  int scalar_i32 = v.inner.arr[min(idx, 7u)].scalar_i32;
+  uint scalar_u32 = v.inner.arr[min(idx, 7u)].scalar_u32;
+  float16_t scalar_f16 = v.inner.arr[min(idx, 7u)].scalar_f16;
+  vec2 vec2_f32 = v.inner.arr[min(idx, 7u)].vec2_f32;
+  ivec2 vec2_i32 = v.inner.arr[min(idx, 7u)].vec2_i32;
+  uvec2 vec2_u32 = v.inner.arr[min(idx, 7u)].vec2_u32;
+  f16vec2 vec2_f16 = v.inner.arr[min(idx, 7u)].vec2_f16;
+  vec3 vec3_f32 = v.inner.arr[min(idx, 7u)].vec3_f32;
+  ivec3 vec3_i32 = v.inner.arr[min(idx, 7u)].vec3_i32;
+  uvec3 vec3_u32 = v.inner.arr[min(idx, 7u)].vec3_u32;
+  f16vec3 vec3_f16 = v.inner.arr[min(idx, 7u)].vec3_f16;
+  vec4 vec4_f32 = v.inner.arr[min(idx, 7u)].vec4_f32;
+  ivec4 vec4_i32 = v.inner.arr[min(idx, 7u)].vec4_i32;
+  uvec4 vec4_u32 = v.inner.arr[min(idx, 7u)].vec4_u32;
+  f16vec4 vec4_f16 = v.inner.arr[min(idx, 7u)].vec4_f16;
+  mat2 mat2x2_f32 = mat2(v.inner.arr[min(idx, 7u)].mat2x2_f32_col0, v.inner.arr[min(idx, 7u)].mat2x2_f32_col1);
+  mat2x3 mat2x3_f32 = mat2x3(v.inner.arr[min(idx, 7u)].mat2x3_f32_col0, v.inner.arr[min(idx, 7u)].mat2x3_f32_col1);
+  mat2x4 mat2x4_f32 = v.inner.arr[min(idx, 7u)].mat2x4_f32;
+  mat3x2 mat3x2_f32 = mat3x2(v.inner.arr[min(idx, 7u)].mat3x2_f32_col0, v.inner.arr[min(idx, 7u)].mat3x2_f32_col1, v.inner.arr[min(idx, 7u)].mat3x2_f32_col2);
+  mat3 mat3x3_f32 = mat3(v.inner.arr[min(idx, 7u)].mat3x3_f32_col0, v.inner.arr[min(idx, 7u)].mat3x3_f32_col1, v.inner.arr[min(idx, 7u)].mat3x3_f32_col2);
+  mat3x4 mat3x4_f32 = v.inner.arr[min(idx, 7u)].mat3x4_f32;
+  mat4x2 mat4x2_f32 = mat4x2(v.inner.arr[min(idx, 7u)].mat4x2_f32_col0, v.inner.arr[min(idx, 7u)].mat4x2_f32_col1, v.inner.arr[min(idx, 7u)].mat4x2_f32_col2, v.inner.arr[min(idx, 7u)].mat4x2_f32_col3);
+  mat4x3 mat4x3_f32 = mat4x3(v.inner.arr[min(idx, 7u)].mat4x3_f32_col0, v.inner.arr[min(idx, 7u)].mat4x3_f32_col1, v.inner.arr[min(idx, 7u)].mat4x3_f32_col2, v.inner.arr[min(idx, 7u)].mat4x3_f32_col3);
+  mat4 mat4x4_f32 = v.inner.arr[min(idx, 7u)].mat4x4_f32;
+  f16mat2 mat2x2_f16 = f16mat2(v.inner.arr[min(idx, 7u)].mat2x2_f16_col0, v.inner.arr[min(idx, 7u)].mat2x2_f16_col1);
+  f16mat2x3 mat2x3_f16 = f16mat2x3(v.inner.arr[min(idx, 7u)].mat2x3_f16_col0, v.inner.arr[min(idx, 7u)].mat2x3_f16_col1);
+  f16mat2x4 mat2x4_f16 = f16mat2x4(v.inner.arr[min(idx, 7u)].mat2x4_f16_col0, v.inner.arr[min(idx, 7u)].mat2x4_f16_col1);
+  f16mat3x2 mat3x2_f16 = f16mat3x2(v.inner.arr[min(idx, 7u)].mat3x2_f16_col0, v.inner.arr[min(idx, 7u)].mat3x2_f16_col1, v.inner.arr[min(idx, 7u)].mat3x2_f16_col2);
+  f16mat3 mat3x3_f16 = f16mat3(v.inner.arr[min(idx, 7u)].mat3x3_f16_col0, v.inner.arr[min(idx, 7u)].mat3x3_f16_col1, v.inner.arr[min(idx, 7u)].mat3x3_f16_col2);
+  f16mat3x4 mat3x4_f16 = f16mat3x4(v.inner.arr[min(idx, 7u)].mat3x4_f16_col0, v.inner.arr[min(idx, 7u)].mat3x4_f16_col1, v.inner.arr[min(idx, 7u)].mat3x4_f16_col2);
+  f16mat4x2 mat4x2_f16 = f16mat4x2(v.inner.arr[min(idx, 7u)].mat4x2_f16_col0, v.inner.arr[min(idx, 7u)].mat4x2_f16_col1, v.inner.arr[min(idx, 7u)].mat4x2_f16_col2, v.inner.arr[min(idx, 7u)].mat4x2_f16_col3);
+  f16mat4x3 mat4x3_f16 = f16mat4x3(v.inner.arr[min(idx, 7u)].mat4x3_f16_col0, v.inner.arr[min(idx, 7u)].mat4x3_f16_col1, v.inner.arr[min(idx, 7u)].mat4x3_f16_col2, v.inner.arr[min(idx, 7u)].mat4x3_f16_col3);
+  f16mat4 mat4x4_f16 = f16mat4(v.inner.arr[min(idx, 7u)].mat4x4_f16_col0, v.inner.arr[min(idx, 7u)].mat4x4_f16_col1, v.inner.arr[min(idx, 7u)].mat4x4_f16_col2, v.inner.arr[min(idx, 7u)].mat4x4_f16_col3);
+  vec3 arr2_vec3_f32[2] = v.inner.arr[min(idx, 7u)].arr2_vec3_f32;
+  mat4x2_f16_std140 v_2[2] = v.inner.arr[min(idx, 7u)].arr2_mat4x2_f16;
   f16mat4x2 v_3[2] = f16mat4x2[2](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
   {
     uint v_4 = 0u;
@@ -184,26 +184,26 @@
   int v_15 = ((v_14 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_16 = (v_15 + int(vec4_u32[2u]));
   int v_17 = (v_16 + tint_f16_to_i32(vec4_f16[2u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_19 = (v_18 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_20 = (v_19 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_21 = (v_20 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_22 = (v_21 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_23 = (v_22 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_24 = (v_23 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_25 = (v_24 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_26 = (v_25 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  int v_27 = (v_26 + tint_f16_to_i32(mat2x2_f16[0][0u]));
-  int v_28 = (v_27 + tint_f16_to_i32(mat2x3_f16[0][0u]));
-  int v_29 = (v_28 + tint_f16_to_i32(mat2x4_f16[0][0u]));
-  int v_30 = (v_29 + tint_f16_to_i32(mat3x2_f16[0][0u]));
-  int v_31 = (v_30 + tint_f16_to_i32(mat3x3_f16[0][0u]));
-  int v_32 = (v_31 + tint_f16_to_i32(mat3x4_f16[0][0u]));
-  int v_33 = (v_32 + tint_f16_to_i32(mat4x2_f16[0][0u]));
-  int v_34 = (v_33 + tint_f16_to_i32(mat4x3_f16[0][0u]));
-  int v_35 = (v_34 + tint_f16_to_i32(mat4x4_f16[0][0u]));
-  int v_36 = (v_35 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
-  v_1.inner = (v_36 + tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]));
+  int v_18 = (v_17 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_19 = (v_18 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_20 = (v_19 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_21 = (v_20 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_22 = (v_21 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_23 = (v_22 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_24 = (v_23 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_25 = (v_24 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_26 = (v_25 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  int v_27 = (v_26 + tint_f16_to_i32(mat2x2_f16[0u][0u]));
+  int v_28 = (v_27 + tint_f16_to_i32(mat2x3_f16[0u][0u]));
+  int v_29 = (v_28 + tint_f16_to_i32(mat2x4_f16[0u][0u]));
+  int v_30 = (v_29 + tint_f16_to_i32(mat3x2_f16[0u][0u]));
+  int v_31 = (v_30 + tint_f16_to_i32(mat3x3_f16[0u][0u]));
+  int v_32 = (v_31 + tint_f16_to_i32(mat3x4_f16[0u][0u]));
+  int v_33 = (v_32 + tint_f16_to_i32(mat4x2_f16[0u][0u]));
+  int v_34 = (v_33 + tint_f16_to_i32(mat4x3_f16[0u][0u]));
+  int v_35 = (v_34 + tint_f16_to_i32(mat4x4_f16[0u][0u]));
+  int v_36 = (v_35 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
+  v_1.inner = (v_36 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
index 8e4bcf0..096973e 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.dxc.hlsl
@@ -203,64 +203,64 @@
 }
 
 void main_inner(uint idx) {
-  uint v_82 = (800u * uint(idx));
+  uint v_82 = (800u * uint(min(idx, 7u)));
   float scalar_f32 = asfloat(ub[(v_82 / 16u)][((v_82 % 16u) / 4u)]);
-  uint v_83 = (4u + (800u * uint(idx)));
+  uint v_83 = (4u + (800u * uint(min(idx, 7u))));
   int scalar_i32 = asint(ub[(v_83 / 16u)][((v_83 % 16u) / 4u)]);
-  uint v_84 = (8u + (800u * uint(idx)));
+  uint v_84 = (8u + (800u * uint(min(idx, 7u))));
   uint scalar_u32 = ub[(v_84 / 16u)][((v_84 % 16u) / 4u)];
-  uint v_85 = (12u + (800u * uint(idx)));
+  uint v_85 = (12u + (800u * uint(min(idx, 7u))));
   uint v_86 = ub[(v_85 / 16u)][((v_85 % 16u) / 4u)];
   float16_t scalar_f16 = float16_t(f16tof32((v_86 >> ((((v_85 % 4u) == 0u)) ? (0u) : (16u)))));
-  uint v_87 = (16u + (800u * uint(idx)));
+  uint v_87 = (16u + (800u * uint(min(idx, 7u))));
   uint4 v_88 = ub[(v_87 / 16u)];
   float2 vec2_f32 = asfloat((((((v_87 % 16u) / 4u) == 2u)) ? (v_88.zw) : (v_88.xy)));
-  uint v_89 = (24u + (800u * uint(idx)));
+  uint v_89 = (24u + (800u * uint(min(idx, 7u))));
   uint4 v_90 = ub[(v_89 / 16u)];
   int2 vec2_i32 = asint((((((v_89 % 16u) / 4u) == 2u)) ? (v_90.zw) : (v_90.xy)));
-  uint v_91 = (32u + (800u * uint(idx)));
+  uint v_91 = (32u + (800u * uint(min(idx, 7u))));
   uint4 v_92 = ub[(v_91 / 16u)];
   uint2 vec2_u32 = (((((v_91 % 16u) / 4u) == 2u)) ? (v_92.zw) : (v_92.xy));
-  uint v_93 = (40u + (800u * uint(idx)));
+  uint v_93 = (40u + (800u * uint(min(idx, 7u))));
   vector<float16_t, 2> vec2_f16 = tint_bitcast_to_f16(ub[(v_93 / 16u)][((v_93 % 16u) / 4u)]);
-  uint v_94 = ((48u + (800u * uint(idx))) / 16u);
+  uint v_94 = ((48u + (800u * uint(min(idx, 7u)))) / 16u);
   float3 vec3_f32 = asfloat(ub[v_94].xyz);
-  uint v_95 = ((64u + (800u * uint(idx))) / 16u);
+  uint v_95 = ((64u + (800u * uint(min(idx, 7u)))) / 16u);
   int3 vec3_i32 = asint(ub[v_95].xyz);
-  uint v_96 = ((80u + (800u * uint(idx))) / 16u);
+  uint v_96 = ((80u + (800u * uint(min(idx, 7u)))) / 16u);
   uint3 vec3_u32 = ub[v_96].xyz;
-  uint v_97 = (96u + (800u * uint(idx)));
+  uint v_97 = (96u + (800u * uint(min(idx, 7u))));
   uint4 v_98 = ub[(v_97 / 16u)];
   vector<float16_t, 3> vec3_f16 = tint_bitcast_to_f16_1((((((v_97 % 16u) / 4u) == 2u)) ? (v_98.zw) : (v_98.xy))).xyz;
-  uint v_99 = ((112u + (800u * uint(idx))) / 16u);
+  uint v_99 = ((112u + (800u * uint(min(idx, 7u)))) / 16u);
   float4 vec4_f32 = asfloat(ub[v_99]);
-  uint v_100 = ((128u + (800u * uint(idx))) / 16u);
+  uint v_100 = ((128u + (800u * uint(min(idx, 7u)))) / 16u);
   int4 vec4_i32 = asint(ub[v_100]);
-  uint v_101 = ((144u + (800u * uint(idx))) / 16u);
+  uint v_101 = ((144u + (800u * uint(min(idx, 7u)))) / 16u);
   uint4 vec4_u32 = ub[v_101];
-  uint v_102 = (160u + (800u * uint(idx)));
+  uint v_102 = (160u + (800u * uint(min(idx, 7u))));
   uint4 v_103 = ub[(v_102 / 16u)];
   vector<float16_t, 4> vec4_f16 = tint_bitcast_to_f16_1((((((v_102 % 16u) / 4u) == 2u)) ? (v_103.zw) : (v_103.xy)));
-  float2x2 mat2x2_f32 = v_78((168u + (800u * uint(idx))));
-  float2x3 mat2x3_f32 = v_77((192u + (800u * uint(idx))));
-  float2x4 mat2x4_f32 = v_76((224u + (800u * uint(idx))));
-  float3x2 mat3x2_f32 = v_70((256u + (800u * uint(idx))));
-  float3x3 mat3x3_f32 = v_69((288u + (800u * uint(idx))));
-  float3x4 mat3x4_f32 = v_68((336u + (800u * uint(idx))));
-  float4x2 mat4x2_f32 = v_60((384u + (800u * uint(idx))));
-  float4x3 mat4x3_f32 = v_59((416u + (800u * uint(idx))));
-  float4x4 mat4x4_f32 = v_58((480u + (800u * uint(idx))));
-  matrix<float16_t, 2, 2> mat2x2_f16 = v_56((544u + (800u * uint(idx))));
-  matrix<float16_t, 2, 3> mat2x3_f16 = v_52((552u + (800u * uint(idx))));
-  matrix<float16_t, 2, 4> mat2x4_f16 = v_48((568u + (800u * uint(idx))));
-  matrix<float16_t, 3, 2> mat3x2_f16 = v_45((584u + (800u * uint(idx))));
-  matrix<float16_t, 3, 3> mat3x3_f16 = v_39((600u + (800u * uint(idx))));
-  matrix<float16_t, 3, 4> mat3x4_f16 = v_33((624u + (800u * uint(idx))));
-  matrix<float16_t, 4, 2> mat4x2_f16 = v_2((648u + (800u * uint(idx))));
-  matrix<float16_t, 4, 3> mat4x3_f16 = v_25((664u + (800u * uint(idx))));
-  matrix<float16_t, 4, 4> mat4x4_f16 = v_17((696u + (800u * uint(idx))));
-  float3 arr2_vec3_f32[2] = v_10((736u + (800u * uint(idx))));
-  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = v_6((768u + (800u * uint(idx))));
+  float2x2 mat2x2_f32 = v_78((168u + (800u * uint(min(idx, 7u)))));
+  float2x3 mat2x3_f32 = v_77((192u + (800u * uint(min(idx, 7u)))));
+  float2x4 mat2x4_f32 = v_76((224u + (800u * uint(min(idx, 7u)))));
+  float3x2 mat3x2_f32 = v_70((256u + (800u * uint(min(idx, 7u)))));
+  float3x3 mat3x3_f32 = v_69((288u + (800u * uint(min(idx, 7u)))));
+  float3x4 mat3x4_f32 = v_68((336u + (800u * uint(min(idx, 7u)))));
+  float4x2 mat4x2_f32 = v_60((384u + (800u * uint(min(idx, 7u)))));
+  float4x3 mat4x3_f32 = v_59((416u + (800u * uint(min(idx, 7u)))));
+  float4x4 mat4x4_f32 = v_58((480u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 2, 2> mat2x2_f16 = v_56((544u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 2, 3> mat2x3_f16 = v_52((552u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 2, 4> mat2x4_f16 = v_48((568u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 3, 2> mat3x2_f16 = v_45((584u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 3, 3> mat3x3_f16 = v_39((600u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 3, 4> mat3x4_f16 = v_33((624u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 4, 2> mat4x2_f16 = v_2((648u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 4, 3> mat4x3_f16 = v_25((664u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 4, 4> mat4x4_f16 = v_17((696u + (800u * uint(min(idx, 7u)))));
+  float3 arr2_vec3_f32[2] = v_10((736u + (800u * uint(min(idx, 7u)))));
+  matrix<float16_t, 4, 2> arr2_mat4x2_f16[2] = v_6((768u + (800u * uint(min(idx, 7u)))));
   int v_104 = (tint_f32_to_i32(scalar_f32) + scalar_i32);
   int v_105 = (v_104 + int(scalar_u32));
   int v_106 = (v_105 + tint_f16_to_i32(scalar_f16));
@@ -273,26 +273,26 @@
   int v_113 = ((v_112 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_114 = (v_113 + int(vec4_u32.z));
   int v_115 = (v_114 + tint_f16_to_i32(vec4_f16.z));
-  int v_116 = (v_115 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_117 = (v_116 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_118 = (v_117 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_119 = (v_118 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_120 = (v_119 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_121 = (v_120 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_122 = (v_121 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_123 = (v_122 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_124 = (v_123 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  int v_125 = (v_124 + tint_f16_to_i32(mat2x2_f16[int(0)].x));
-  int v_126 = (v_125 + tint_f16_to_i32(mat2x3_f16[int(0)].x));
-  int v_127 = (v_126 + tint_f16_to_i32(mat2x4_f16[int(0)].x));
-  int v_128 = (v_127 + tint_f16_to_i32(mat3x2_f16[int(0)].x));
-  int v_129 = (v_128 + tint_f16_to_i32(mat3x3_f16[int(0)].x));
-  int v_130 = (v_129 + tint_f16_to_i32(mat3x4_f16[int(0)].x));
-  int v_131 = (v_130 + tint_f16_to_i32(mat4x2_f16[int(0)].x));
-  int v_132 = (v_131 + tint_f16_to_i32(mat4x3_f16[int(0)].x));
-  int v_133 = (v_132 + tint_f16_to_i32(mat4x4_f16[int(0)].x));
-  int v_134 = (v_133 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x));
-  s.Store(0u, asuint((v_134 + tint_f16_to_i32(arr2_mat4x2_f16[int(0)][int(0)].x))));
+  int v_116 = (v_115 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_117 = (v_116 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_118 = (v_117 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_119 = (v_118 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_120 = (v_119 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_121 = (v_120 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_122 = (v_121 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_123 = (v_122 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_124 = (v_123 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  int v_125 = (v_124 + tint_f16_to_i32(mat2x2_f16[0u].x));
+  int v_126 = (v_125 + tint_f16_to_i32(mat2x3_f16[0u].x));
+  int v_127 = (v_126 + tint_f16_to_i32(mat2x4_f16[0u].x));
+  int v_128 = (v_127 + tint_f16_to_i32(mat3x2_f16[0u].x));
+  int v_129 = (v_128 + tint_f16_to_i32(mat3x3_f16[0u].x));
+  int v_130 = (v_129 + tint_f16_to_i32(mat3x4_f16[0u].x));
+  int v_131 = (v_130 + tint_f16_to_i32(mat4x2_f16[0u].x));
+  int v_132 = (v_131 + tint_f16_to_i32(mat4x3_f16[0u].x));
+  int v_133 = (v_132 + tint_f16_to_i32(mat4x4_f16[0u].x));
+  int v_134 = (v_133 + tint_f32_to_i32(arr2_vec3_f32[0u].x));
+  s.Store(0u, asuint((v_134 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u].x))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.msl b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.msl
index 0245d85..d6a6ae1 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.ir.msl
@@ -95,60 +95,60 @@
 }
 
 void tint_symbol_inner(uint idx, tint_module_vars_struct tint_module_vars) {
-  float const scalar_f32 = (*tint_module_vars.ub).arr[idx].scalar_f32;
-  int const scalar_i32 = (*tint_module_vars.ub).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*tint_module_vars.ub).arr[idx].scalar_u32;
-  half const scalar_f16 = (*tint_module_vars.ub).arr[idx].scalar_f16;
-  float2 const vec2_f32 = (*tint_module_vars.ub).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*tint_module_vars.ub).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*tint_module_vars.ub).arr[idx].vec2_u32;
-  half2 const vec2_f16 = (*tint_module_vars.ub).arr[idx].vec2_f16;
-  float3 const vec3_f32 = float3((*tint_module_vars.ub).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*tint_module_vars.ub).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*tint_module_vars.ub).arr[idx].vec3_u32);
-  half3 const vec3_f16 = half3((*tint_module_vars.ub).arr[idx].vec3_f16);
-  float4 const vec4_f32 = (*tint_module_vars.ub).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*tint_module_vars.ub).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*tint_module_vars.ub).arr[idx].vec4_u32;
-  half4 const vec4_f16 = (*tint_module_vars.ub).arr[idx].vec4_f16;
-  float2x2 const mat2x2_f32 = (*tint_module_vars.ub).arr[idx].mat2x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.ub).arr[idx].mat2x3_f32;
+  float const scalar_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_f32;
+  int const scalar_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_i32;
+  uint const scalar_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_u32;
+  half const scalar_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].scalar_f16;
+  float2 const vec2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_f32;
+  int2 const vec2_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_i32;
+  uint2 const vec2_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_u32;
+  half2 const vec2_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec2_f16;
+  float3 const vec3_f32 = float3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_f32);
+  int3 const vec3_i32 = int3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_i32);
+  uint3 const vec3_u32 = uint3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_u32);
+  half3 const vec3_f16 = half3((*tint_module_vars.ub).arr[min(idx, 7u)].vec3_f16);
+  float4 const vec4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_f32;
+  int4 const vec4_i32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_i32;
+  uint4 const vec4_u32 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_u32;
+  half4 const vec4_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].vec4_f16;
+  float2x2 const mat2x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x3_f32;
   float3 const v_2 = float3(v_1[0u].packed);
   float2x3 const mat2x3_f32 = float2x3(v_2, float3(v_1[1u].packed));
-  float2x4 const mat2x4_f32 = (*tint_module_vars.ub).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*tint_module_vars.ub).arr[idx].mat3x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.ub).arr[idx].mat3x3_f32;
+  float2x4 const mat2x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_3 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x3_f32;
   float3 const v_4 = float3(v_3[0u].packed);
   float3 const v_5 = float3(v_3[1u].packed);
   float3x3 const mat3x3_f32 = float3x3(v_4, v_5, float3(v_3[2u].packed));
-  float3x4 const mat3x4_f32 = (*tint_module_vars.ub).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*tint_module_vars.ub).arr[idx].mat4x2_f32;
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.ub).arr[idx].mat4x3_f32;
+  float3x4 const mat3x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x2_f32;
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_6 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x3_f32;
   float3 const v_7 = float3(v_6[0u].packed);
   float3 const v_8 = float3(v_6[1u].packed);
   float3 const v_9 = float3(v_6[2u].packed);
   float4x3 const mat4x3_f32 = float4x3(v_7, v_8, v_9, float3(v_6[3u].packed));
-  float4x4 const mat4x4_f32 = (*tint_module_vars.ub).arr[idx].mat4x4_f32;
-  half2x2 const mat2x2_f16 = (*tint_module_vars.ub).arr[idx].mat2x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_10 = (*tint_module_vars.ub).arr[idx].mat2x3_f16;
+  float4x4 const mat4x4_f32 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x4_f32;
+  half2x2 const mat2x2_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_10 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x3_f16;
   half3 const v_11 = half3(v_10[0u].packed_1);
   half2x3 const mat2x3_f16 = half2x3(v_11, half3(v_10[1u].packed_1));
-  half2x4 const mat2x4_f16 = (*tint_module_vars.ub).arr[idx].mat2x4_f16;
-  half3x2 const mat3x2_f16 = (*tint_module_vars.ub).arr[idx].mat3x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_12 = (*tint_module_vars.ub).arr[idx].mat3x3_f16;
+  half2x4 const mat2x4_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat2x4_f16;
+  half3x2 const mat3x2_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_12 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x3_f16;
   half3 const v_13 = half3(v_12[0u].packed_1);
   half3 const v_14 = half3(v_12[1u].packed_1);
   half3x3 const mat3x3_f16 = half3x3(v_13, v_14, half3(v_12[2u].packed_1));
-  half3x4 const mat3x4_f16 = (*tint_module_vars.ub).arr[idx].mat3x4_f16;
-  half4x2 const mat4x2_f16 = (*tint_module_vars.ub).arr[idx].mat4x2_f16;
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_15 = (*tint_module_vars.ub).arr[idx].mat4x3_f16;
+  half3x4 const mat3x4_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat3x4_f16;
+  half4x2 const mat4x2_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x2_f16;
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_15 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x3_f16;
   half3 const v_16 = half3(v_15[0u].packed_1);
   half3 const v_17 = half3(v_15[1u].packed_1);
   half3 const v_18 = half3(v_15[2u].packed_1);
   half4x3 const mat4x3_f16 = half4x3(v_16, v_17, v_18, half3(v_15[3u].packed_1));
-  half4x4 const mat4x4_f16 = (*tint_module_vars.ub).arr[idx].mat4x4_f16;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.ub).arr[idx].arr2_vec3_f32));
-  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*tint_module_vars.ub).arr[idx].arr2_mat4x2_f16;
+  half4x4 const mat4x4_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].mat4x4_f16;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_load_array_packed_vec3((&(*tint_module_vars.ub).arr[min(idx, 7u)].arr2_vec3_f32));
+  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*tint_module_vars.ub).arr[min(idx, 7u)].arr2_mat4x2_f16;
   int const v_19 = as_type<int>((as_type<uint>(tint_f32_to_i32(scalar_f32)) + as_type<uint>(scalar_i32)));
   int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(int(scalar_u32))));
   int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f16_to_i32(scalar_f16))));
@@ -161,26 +161,26 @@
   int const v_28 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_27) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_29 = as_type<int>((as_type<uint>(v_28) + as_type<uint>(int(vec4_u32[2u]))));
   int const v_30 = as_type<int>((as_type<uint>(v_29) + as_type<uint>(tint_f16_to_i32(vec4_f16[2u]))));
-  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0][0u]))));
-  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0][0u]))));
-  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0][0u]))));
-  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0][0u]))));
-  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0][0u]))));
-  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0][0u]))));
-  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0][0u]))));
-  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0][0u]))));
-  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0][0u]))));
-  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]))));
+  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0u][0u]))));
+  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0u][0u]))));
+  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0u][0u]))));
+  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0u][0u]))));
+  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0u][0u]))));
+  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0u][0u]))));
+  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0u][0u]))));
+  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0u][0u]))));
+  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0u][0u]))));
+  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]))));
 }
 
 kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], const constant S_packed_vec3* ub [[buffer(0)]], device int* s [[buffer(1)]]) {
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.msl b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.msl
index eac9363..5255088 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.msl
@@ -160,42 +160,42 @@
 };
 
 void tint_symbol_inner(uint idx, const constant S_tint_packed_vec3* const tint_symbol_1, device int* const tint_symbol_2) {
-  float const scalar_f32 = (*(tint_symbol_1)).arr[idx].scalar_f32;
-  int const scalar_i32 = (*(tint_symbol_1)).arr[idx].scalar_i32;
-  uint const scalar_u32 = (*(tint_symbol_1)).arr[idx].scalar_u32;
-  half const scalar_f16 = (*(tint_symbol_1)).arr[idx].scalar_f16;
-  float2 const vec2_f32 = (*(tint_symbol_1)).arr[idx].vec2_f32;
-  int2 const vec2_i32 = (*(tint_symbol_1)).arr[idx].vec2_i32;
-  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[idx].vec2_u32;
-  half2 const vec2_f16 = (*(tint_symbol_1)).arr[idx].vec2_f16;
-  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[idx].vec3_f32);
-  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[idx].vec3_i32);
-  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[idx].vec3_u32);
-  half3 const vec3_f16 = half3((*(tint_symbol_1)).arr[idx].vec3_f16);
-  float4 const vec4_f32 = (*(tint_symbol_1)).arr[idx].vec4_f32;
-  int4 const vec4_i32 = (*(tint_symbol_1)).arr[idx].vec4_i32;
-  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[idx].vec4_u32;
-  half4 const vec4_f16 = (*(tint_symbol_1)).arr[idx].vec4_f16;
-  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[idx].mat2x2_f32;
-  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[idx].mat2x3_f32);
-  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[idx].mat2x4_f32;
-  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[idx].mat3x2_f32;
-  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[idx].mat3x3_f32);
-  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[idx].mat3x4_f32;
-  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[idx].mat4x2_f32;
-  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[idx].mat4x3_f32);
-  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[idx].mat4x4_f32;
-  half2x2 const mat2x2_f16 = (*(tint_symbol_1)).arr[idx].mat2x2_f16;
-  half2x3 const mat2x3_f16 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[idx].mat2x3_f16);
-  half2x4 const mat2x4_f16 = (*(tint_symbol_1)).arr[idx].mat2x4_f16;
-  half3x2 const mat3x2_f16 = (*(tint_symbol_1)).arr[idx].mat3x2_f16;
-  half3x3 const mat3x3_f16 = tint_unpack_vec3_in_composite_4((*(tint_symbol_1)).arr[idx].mat3x3_f16);
-  half3x4 const mat3x4_f16 = (*(tint_symbol_1)).arr[idx].mat3x4_f16;
-  half4x2 const mat4x2_f16 = (*(tint_symbol_1)).arr[idx].mat4x2_f16;
-  half4x3 const mat4x3_f16 = tint_unpack_vec3_in_composite_5((*(tint_symbol_1)).arr[idx].mat4x3_f16);
-  half4x4 const mat4x4_f16 = (*(tint_symbol_1)).arr[idx].mat4x4_f16;
-  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_6((*(tint_symbol_1)).arr[idx].arr2_vec3_f32);
-  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*(tint_symbol_1)).arr[idx].arr2_mat4x2_f16;
+  float const scalar_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_f32;
+  int const scalar_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_i32;
+  uint const scalar_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_u32;
+  half const scalar_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].scalar_f16;
+  float2 const vec2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_f32;
+  int2 const vec2_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_i32;
+  uint2 const vec2_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_u32;
+  half2 const vec2_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec2_f16;
+  float3 const vec3_f32 = float3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_f32);
+  int3 const vec3_i32 = int3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_i32);
+  uint3 const vec3_u32 = uint3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_u32);
+  half3 const vec3_f16 = half3((*(tint_symbol_1)).arr[min(idx, 7u)].vec3_f16);
+  float4 const vec4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_f32;
+  int4 const vec4_i32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_i32;
+  uint4 const vec4_u32 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_u32;
+  half4 const vec4_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].vec4_f16;
+  float2x2 const mat2x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x2_f32;
+  float2x3 const mat2x3_f32 = tint_unpack_vec3_in_composite((*(tint_symbol_1)).arr[min(idx, 7u)].mat2x3_f32);
+  float2x4 const mat2x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x4_f32;
+  float3x2 const mat3x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x2_f32;
+  float3x3 const mat3x3_f32 = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).arr[min(idx, 7u)].mat3x3_f32);
+  float3x4 const mat3x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x4_f32;
+  float4x2 const mat4x2_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x2_f32;
+  float4x3 const mat4x3_f32 = tint_unpack_vec3_in_composite_2((*(tint_symbol_1)).arr[min(idx, 7u)].mat4x3_f32);
+  float4x4 const mat4x4_f32 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x4_f32;
+  half2x2 const mat2x2_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x2_f16;
+  half2x3 const mat2x3_f16 = tint_unpack_vec3_in_composite_3((*(tint_symbol_1)).arr[min(idx, 7u)].mat2x3_f16);
+  half2x4 const mat2x4_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat2x4_f16;
+  half3x2 const mat3x2_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x2_f16;
+  half3x3 const mat3x3_f16 = tint_unpack_vec3_in_composite_4((*(tint_symbol_1)).arr[min(idx, 7u)].mat3x3_f16);
+  half3x4 const mat3x4_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat3x4_f16;
+  half4x2 const mat4x2_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x2_f16;
+  half4x3 const mat4x3_f16 = tint_unpack_vec3_in_composite_5((*(tint_symbol_1)).arr[min(idx, 7u)].mat4x3_f16);
+  half4x4 const mat4x4_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].mat4x4_f16;
+  tint_array<float3, 2> const arr2_vec3_f32 = tint_unpack_vec3_in_composite_6((*(tint_symbol_1)).arr[min(idx, 7u)].arr2_vec3_f32);
+  tint_array<half4x2, 2> const arr2_mat4x2_f16 = (*(tint_symbol_1)).arr[min(idx, 7u)].arr2_mat4x2_f16;
   *(tint_symbol_2) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(tint_ftoi(scalar_f32)) + as_type<uint>(scalar_i32)))) + as_type<uint>(int(scalar_u32))))) + as_type<uint>(int(scalar_f16))))) + as_type<uint>(tint_ftoi(vec2_f32[0]))))) + as_type<uint>(vec2_i32[0])))) + as_type<uint>(int(vec2_u32[0]))))) + as_type<uint>(int(vec2_f16[0]))))) + as_type<uint>(tint_ftoi(vec3_f32[1]))))) + as_type<uint>(vec3_i32[1])))) + as_type<uint>(int(vec3_u32[1]))))) + as_type<uint>(int(vec3_f16[1]))))) + as_type<uint>(tint_ftoi(vec4_f32[2]))))) + as_type<uint>(vec4_i32[2])))) + as_type<uint>(int(vec4_u32[2]))))) + as_type<uint>(int(vec4_f16[2]))))) + as_type<uint>(tint_ftoi(mat2x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat2x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat3x4_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x2_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x3_f32[0][0]))))) + as_type<uint>(tint_ftoi(mat4x4_f32[0][0]))))) + as_type<uint>(int(mat2x2_f16[0][0]))))) + as_type<uint>(int(mat2x3_f16[0][0]))))) + as_type<uint>(int(mat2x4_f16[0][0]))))) + as_type<uint>(int(mat3x2_f16[0][0]))))) + as_type<uint>(int(mat3x3_f16[0][0]))))) + as_type<uint>(int(mat3x4_f16[0][0]))))) + as_type<uint>(int(mat4x2_f16[0][0]))))) + as_type<uint>(int(mat4x3_f16[0][0]))))) + as_type<uint>(int(mat4x4_f16[0][0]))))) + as_type<uint>(tint_ftoi(arr2_vec3_f32[0][0]))))) + as_type<uint>(int(arr2_mat4x2_f16[0][0][0]))));
 }
 
diff --git a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.spvasm b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.spvasm
index 1924f12..6c0953f 100644
--- a/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/dynamic_index/read_f16.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 446
+; Bound: 483
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -261,6 +262,7 @@
 %main_local_invocation_index_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %39 = OpTypeFunction %void %uint
+     %uint_7 = OpConstant %uint 7
 %_ptr_Uniform_float = OpTypePointer Uniform %float
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
@@ -275,7 +277,6 @@
 %_ptr_Uniform_v2uint = OpTypePointer Uniform %v2uint
      %uint_6 = OpConstant %uint 6
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-     %uint_7 = OpConstant %uint 7
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Uniform_v3int = OpTypePointer Uniform %v3int
      %uint_9 = OpConstant %uint 9
@@ -364,328 +365,364 @@
 %_ptr_Function__arr_mat4x2_f16_std140_uint_2 = OpTypePointer Function %_arr_mat4x2_f16_std140_uint_2
 %_arr_mat4v2half_uint_2 = OpTypeArray %mat4v2half %uint_2
 %_ptr_Function__arr_mat4v2half_uint_2 = OpTypePointer Function %_arr_mat4v2half_uint_2
-        %293 = OpConstantNull %_arr_mat4v2half_uint_2
+        %330 = OpConstantNull %_arr_mat4v2half_uint_2
        %bool = OpTypeBool
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %420 = OpTypeFunction %int %float
+        %457 = OpTypeFunction %int %float
 %float_n2_14748365e_09 = OpConstant %float -2.14748365e+09
 %int_n2147483648 = OpConstant %int -2147483648
 %float_2_14748352e_09 = OpConstant %float 2.14748352e+09
 %int_2147483647 = OpConstant %int 2147483647
-        %432 = OpTypeFunction %int %half
+        %469 = OpTypeFunction %int %half
 %half_n0x1_ffcp_15 = OpConstant %half -0x1.ffcp+15
 %half_0x1_ffcp_15 = OpConstant %half 0x1.ffcp+15
-        %442 = OpTypeFunction %void
+        %479 = OpTypeFunction %void
  %main_inner = OpFunction %void None %39
         %idx = OpFunctionParameter %uint
          %40 = OpLabel
-        %288 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_2 Function
-        %290 = OpVariable %_ptr_Function__arr_mat4v2half_uint_2 Function %293
-         %41 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0 %idx %uint_0
- %scalar_f32 = OpLoad %float %41 None
-         %45 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0 %idx %uint_1
- %scalar_i32 = OpLoad %int %45 None
-         %49 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0 %idx %uint_2
- %scalar_u32 = OpLoad %uint %49 None
-         %52 = OpAccessChain %_ptr_Uniform_half %1 %uint_0 %uint_0 %idx %uint_3
- %scalar_f16 = OpLoad %half %52 None
-         %56 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_4
-   %vec2_f32 = OpLoad %v2float %56 None
-         %60 = OpAccessChain %_ptr_Uniform_v2int %1 %uint_0 %uint_0 %idx %uint_5
-   %vec2_i32 = OpLoad %v2int %60 None
-         %64 = OpAccessChain %_ptr_Uniform_v2uint %1 %uint_0 %uint_0 %idx %uint_6
-   %vec2_u32 = OpLoad %v2uint %64 None
-         %68 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_7
-   %vec2_f16 = OpLoad %v2half %68 None
-         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_8
-   %vec3_f32 = OpLoad %v3float %72 None
-         %75 = OpAccessChain %_ptr_Uniform_v3int %1 %uint_0 %uint_0 %idx %uint_9
-   %vec3_i32 = OpLoad %v3int %75 None
-         %79 = OpAccessChain %_ptr_Uniform_v3uint %1 %uint_0 %uint_0 %idx %uint_10
-   %vec3_u32 = OpLoad %v3uint %79 None
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_11
-   %vec3_f16 = OpLoad %v3half %83 None
-         %87 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %idx %uint_12
-   %vec4_f32 = OpLoad %v4float %87 None
-         %91 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %idx %uint_13
-   %vec4_i32 = OpLoad %v4int %91 None
-         %95 = OpAccessChain %_ptr_Uniform_v4uint %1 %uint_0 %uint_0 %idx %uint_14
-   %vec4_u32 = OpLoad %v4uint %95 None
-         %99 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_15
-   %vec4_f16 = OpLoad %v4half %99 None
-        %103 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_16
-        %105 = OpLoad %v2float %103 None
-        %106 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_17
-        %108 = OpLoad %v2float %106 None
- %mat2x2_f32 = OpCompositeConstruct %mat2v2float %105 %108
-        %111 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_18
-        %113 = OpLoad %v3float %111 None
-        %114 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_19
-        %116 = OpLoad %v3float %114 None
- %mat2x3_f32 = OpCompositeConstruct %mat2v3float %113 %116
-        %119 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_0 %idx %uint_20
- %mat2x4_f32 = OpLoad %mat2v4float %119 None
-        %123 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_21
-        %125 = OpLoad %v2float %123 None
-        %126 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_22
-        %128 = OpLoad %v2float %126 None
-        %129 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_23
-        %131 = OpLoad %v2float %129 None
- %mat3x2_f32 = OpCompositeConstruct %mat3v2float %125 %128 %131
-        %134 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_24
-        %136 = OpLoad %v3float %134 None
-        %137 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_25
-        %139 = OpLoad %v3float %137 None
-        %140 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_26
-        %142 = OpLoad %v3float %140 None
- %mat3x3_f32 = OpCompositeConstruct %mat3v3float %136 %139 %142
-        %145 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_0 %idx %uint_27
- %mat3x4_f32 = OpLoad %mat3v4float %145 None
-        %149 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_28
-        %151 = OpLoad %v2float %149 None
-        %152 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_29
-        %154 = OpLoad %v2float %152 None
-        %155 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_30
-        %157 = OpLoad %v2float %155 None
-        %158 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %idx %uint_31
-        %160 = OpLoad %v2float %158 None
- %mat4x2_f32 = OpCompositeConstruct %mat4v2float %151 %154 %157 %160
-        %163 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_32
-        %165 = OpLoad %v3float %163 None
-        %166 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_33
-        %168 = OpLoad %v3float %166 None
-        %169 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_34
-        %171 = OpLoad %v3float %169 None
-        %172 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %idx %uint_35
-        %174 = OpLoad %v3float %172 None
- %mat4x3_f32 = OpCompositeConstruct %mat4v3float %165 %168 %171 %174
-        %177 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_0 %idx %uint_36
- %mat4x4_f32 = OpLoad %mat4v4float %177 None
-        %181 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_37
-        %183 = OpLoad %v2half %181 None
-        %184 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_38
-        %186 = OpLoad %v2half %184 None
- %mat2x2_f16 = OpCompositeConstruct %mat2v2half %183 %186
-        %189 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_39
-        %191 = OpLoad %v3half %189 None
-        %192 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_40
-        %194 = OpLoad %v3half %192 None
- %mat2x3_f16 = OpCompositeConstruct %mat2v3half %191 %194
-        %197 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_41
-        %199 = OpLoad %v4half %197 None
-        %200 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_42
-        %202 = OpLoad %v4half %200 None
- %mat2x4_f16 = OpCompositeConstruct %mat2v4half %199 %202
-        %205 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_43
-        %207 = OpLoad %v2half %205 None
-        %208 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_44
+        %325 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_2 Function
+        %327 = OpVariable %_ptr_Function__arr_mat4v2half_uint_2 Function %330
+         %41 = OpExtInst %uint %42 UMin %idx %uint_7
+         %44 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0 %41 %uint_0
+ %scalar_f32 = OpLoad %float %44 None
+         %48 = OpExtInst %uint %42 UMin %idx %uint_7
+         %49 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0 %48 %uint_1
+ %scalar_i32 = OpLoad %int %49 None
+         %53 = OpExtInst %uint %42 UMin %idx %uint_7
+         %54 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0 %53 %uint_2
+ %scalar_u32 = OpLoad %uint %54 None
+         %57 = OpExtInst %uint %42 UMin %idx %uint_7
+         %58 = OpAccessChain %_ptr_Uniform_half %1 %uint_0 %uint_0 %57 %uint_3
+ %scalar_f16 = OpLoad %half %58 None
+         %62 = OpExtInst %uint %42 UMin %idx %uint_7
+         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %62 %uint_4
+   %vec2_f32 = OpLoad %v2float %63 None
+         %67 = OpExtInst %uint %42 UMin %idx %uint_7
+         %68 = OpAccessChain %_ptr_Uniform_v2int %1 %uint_0 %uint_0 %67 %uint_5
+   %vec2_i32 = OpLoad %v2int %68 None
+         %72 = OpExtInst %uint %42 UMin %idx %uint_7
+         %73 = OpAccessChain %_ptr_Uniform_v2uint %1 %uint_0 %uint_0 %72 %uint_6
+   %vec2_u32 = OpLoad %v2uint %73 None
+         %77 = OpExtInst %uint %42 UMin %idx %uint_7
+         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %77 %uint_7
+   %vec2_f16 = OpLoad %v2half %78 None
+         %81 = OpExtInst %uint %42 UMin %idx %uint_7
+         %82 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %81 %uint_8
+   %vec3_f32 = OpLoad %v3float %82 None
+         %85 = OpExtInst %uint %42 UMin %idx %uint_7
+         %86 = OpAccessChain %_ptr_Uniform_v3int %1 %uint_0 %uint_0 %85 %uint_9
+   %vec3_i32 = OpLoad %v3int %86 None
+         %90 = OpExtInst %uint %42 UMin %idx %uint_7
+         %91 = OpAccessChain %_ptr_Uniform_v3uint %1 %uint_0 %uint_0 %90 %uint_10
+   %vec3_u32 = OpLoad %v3uint %91 None
+         %95 = OpExtInst %uint %42 UMin %idx %uint_7
+         %96 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %95 %uint_11
+   %vec3_f16 = OpLoad %v3half %96 None
+        %100 = OpExtInst %uint %42 UMin %idx %uint_7
+        %101 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %100 %uint_12
+   %vec4_f32 = OpLoad %v4float %101 None
+        %105 = OpExtInst %uint %42 UMin %idx %uint_7
+        %106 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %105 %uint_13
+   %vec4_i32 = OpLoad %v4int %106 None
+        %110 = OpExtInst %uint %42 UMin %idx %uint_7
+        %111 = OpAccessChain %_ptr_Uniform_v4uint %1 %uint_0 %uint_0 %110 %uint_14
+   %vec4_u32 = OpLoad %v4uint %111 None
+        %115 = OpExtInst %uint %42 UMin %idx %uint_7
+        %116 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %115 %uint_15
+   %vec4_f16 = OpLoad %v4half %116 None
+        %120 = OpExtInst %uint %42 UMin %idx %uint_7
+        %121 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %120 %uint_16
+        %123 = OpLoad %v2float %121 None
+        %124 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %120 %uint_17
+        %126 = OpLoad %v2float %124 None
+ %mat2x2_f32 = OpCompositeConstruct %mat2v2float %123 %126
+        %129 = OpExtInst %uint %42 UMin %idx %uint_7
+        %130 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %129 %uint_18
+        %132 = OpLoad %v3float %130 None
+        %133 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %129 %uint_19
+        %135 = OpLoad %v3float %133 None
+ %mat2x3_f32 = OpCompositeConstruct %mat2v3float %132 %135
+        %138 = OpExtInst %uint %42 UMin %idx %uint_7
+        %139 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_0 %138 %uint_20
+ %mat2x4_f32 = OpLoad %mat2v4float %139 None
+        %143 = OpExtInst %uint %42 UMin %idx %uint_7
+        %144 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %143 %uint_21
+        %146 = OpLoad %v2float %144 None
+        %147 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %143 %uint_22
+        %149 = OpLoad %v2float %147 None
+        %150 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %143 %uint_23
+        %152 = OpLoad %v2float %150 None
+ %mat3x2_f32 = OpCompositeConstruct %mat3v2float %146 %149 %152
+        %155 = OpExtInst %uint %42 UMin %idx %uint_7
+        %156 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %155 %uint_24
+        %158 = OpLoad %v3float %156 None
+        %159 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %155 %uint_25
+        %161 = OpLoad %v3float %159 None
+        %162 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %155 %uint_26
+        %164 = OpLoad %v3float %162 None
+ %mat3x3_f32 = OpCompositeConstruct %mat3v3float %158 %161 %164
+        %167 = OpExtInst %uint %42 UMin %idx %uint_7
+        %168 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_0 %167 %uint_27
+ %mat3x4_f32 = OpLoad %mat3v4float %168 None
+        %172 = OpExtInst %uint %42 UMin %idx %uint_7
+        %173 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %172 %uint_28
+        %175 = OpLoad %v2float %173 None
+        %176 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %172 %uint_29
+        %178 = OpLoad %v2float %176 None
+        %179 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %172 %uint_30
+        %181 = OpLoad %v2float %179 None
+        %182 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %172 %uint_31
+        %184 = OpLoad %v2float %182 None
+ %mat4x2_f32 = OpCompositeConstruct %mat4v2float %175 %178 %181 %184
+        %187 = OpExtInst %uint %42 UMin %idx %uint_7
+        %188 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %187 %uint_32
+        %190 = OpLoad %v3float %188 None
+        %191 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %187 %uint_33
+        %193 = OpLoad %v3float %191 None
+        %194 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %187 %uint_34
+        %196 = OpLoad %v3float %194 None
+        %197 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %187 %uint_35
+        %199 = OpLoad %v3float %197 None
+ %mat4x3_f32 = OpCompositeConstruct %mat4v3float %190 %193 %196 %199
+        %202 = OpExtInst %uint %42 UMin %idx %uint_7
+        %203 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_0 %202 %uint_36
+ %mat4x4_f32 = OpLoad %mat4v4float %203 None
+        %207 = OpExtInst %uint %42 UMin %idx %uint_7
+        %208 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %207 %uint_37
         %210 = OpLoad %v2half %208 None
-        %211 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_45
+        %211 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %207 %uint_38
         %213 = OpLoad %v2half %211 None
- %mat3x2_f16 = OpCompositeConstruct %mat3v2half %207 %210 %213
-        %216 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_46
-        %218 = OpLoad %v3half %216 None
-        %219 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_47
-        %221 = OpLoad %v3half %219 None
-        %222 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_48
-        %224 = OpLoad %v3half %222 None
- %mat3x3_f16 = OpCompositeConstruct %mat3v3half %218 %221 %224
-        %227 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_49
-        %229 = OpLoad %v4half %227 None
-        %230 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_50
-        %232 = OpLoad %v4half %230 None
-        %233 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_51
-        %235 = OpLoad %v4half %233 None
- %mat3x4_f16 = OpCompositeConstruct %mat3v4half %229 %232 %235
-        %238 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_52
+ %mat2x2_f16 = OpCompositeConstruct %mat2v2half %210 %213
+        %216 = OpExtInst %uint %42 UMin %idx %uint_7
+        %217 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %216 %uint_39
+        %219 = OpLoad %v3half %217 None
+        %220 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %216 %uint_40
+        %222 = OpLoad %v3half %220 None
+ %mat2x3_f16 = OpCompositeConstruct %mat2v3half %219 %222
+        %225 = OpExtInst %uint %42 UMin %idx %uint_7
+        %226 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %225 %uint_41
+        %228 = OpLoad %v4half %226 None
+        %229 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %225 %uint_42
+        %231 = OpLoad %v4half %229 None
+ %mat2x4_f16 = OpCompositeConstruct %mat2v4half %228 %231
+        %234 = OpExtInst %uint %42 UMin %idx %uint_7
+        %235 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %234 %uint_43
+        %237 = OpLoad %v2half %235 None
+        %238 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %234 %uint_44
         %240 = OpLoad %v2half %238 None
-        %241 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_53
+        %241 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %234 %uint_45
         %243 = OpLoad %v2half %241 None
-        %244 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_54
-        %246 = OpLoad %v2half %244 None
-        %247 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %idx %uint_55
-        %249 = OpLoad %v2half %247 None
- %mat4x2_f16 = OpCompositeConstruct %mat4v2half %240 %243 %246 %249
-        %252 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_56
-        %254 = OpLoad %v3half %252 None
-        %255 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_57
-        %257 = OpLoad %v3half %255 None
-        %258 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_58
-        %260 = OpLoad %v3half %258 None
-        %261 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %idx %uint_59
-        %263 = OpLoad %v3half %261 None
- %mat4x3_f16 = OpCompositeConstruct %mat4v3half %254 %257 %260 %263
-        %266 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_60
-        %268 = OpLoad %v4half %266 None
-        %269 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_61
-        %271 = OpLoad %v4half %269 None
-        %272 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_62
-        %274 = OpLoad %v4half %272 None
-        %275 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %idx %uint_63
-        %277 = OpLoad %v4half %275 None
- %mat4x4_f16 = OpCompositeConstruct %mat4v4half %268 %271 %274 %277
-        %280 = OpAccessChain %_ptr_Uniform__arr_v3float_uint_2 %1 %uint_0 %uint_0 %idx %uint_64
-%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %280 None
-        %284 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f16_std140_uint_2 %1 %uint_0 %uint_0 %idx %uint_65
-        %287 = OpLoad %_arr_mat4x2_f16_std140_uint_2 %284 None
-               OpStore %288 %287
-               OpBranch %294
-        %294 = OpLabel
-               OpBranch %297
-        %297 = OpLabel
-        %299 = OpPhi %uint %uint_0 %294 %300 %296
-               OpLoopMerge %298 %296 None
-               OpBranch %295
-        %295 = OpLabel
-        %301 = OpUGreaterThanEqual %bool %299 %uint_2
-               OpSelectionMerge %303 None
-               OpBranchConditional %301 %304 %303
-        %304 = OpLabel
-               OpBranch %298
-        %303 = OpLabel
-        %305 = OpAccessChain %_ptr_Function_mat4v2half %290 %299
-        %307 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %288 %299
-        %309 = OpLoad %mat4x2_f16_std140 %307 None
-        %310 = OpCompositeExtract %v2half %309 0
-        %311 = OpCompositeExtract %v2half %309 1
-        %312 = OpCompositeExtract %v2half %309 2
-        %313 = OpCompositeExtract %v2half %309 3
-        %314 = OpCompositeConstruct %mat4v2half %310 %311 %312 %313
-               OpStore %305 %314 None
-               OpBranch %296
-        %296 = OpLabel
-        %300 = OpIAdd %uint %299 %uint_1
-               OpBranch %297
-        %298 = OpLabel
-%arr2_mat4x2_f16 = OpLoad %_arr_mat4v2half_uint_2 %290 None
-        %316 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
-        %318 = OpIAdd %int %316 %scalar_i32
-        %319 = OpBitcast %int %scalar_u32
-        %320 = OpIAdd %int %318 %319
-        %321 = OpFunctionCall %int %tint_f16_to_i32 %scalar_f16
-        %323 = OpIAdd %int %320 %321
-        %324 = OpCompositeExtract %float %vec2_f32 0
-        %325 = OpFunctionCall %int %tint_f32_to_i32 %324
-        %326 = OpIAdd %int %323 %325
-        %327 = OpCompositeExtract %int %vec2_i32 0
-        %328 = OpIAdd %int %326 %327
-        %329 = OpCompositeExtract %uint %vec2_u32 0
-        %330 = OpBitcast %int %329
-        %331 = OpIAdd %int %328 %330
-        %332 = OpCompositeExtract %half %vec2_f16 0
-        %333 = OpFunctionCall %int %tint_f16_to_i32 %332
-        %334 = OpIAdd %int %331 %333
-        %335 = OpCompositeExtract %float %vec3_f32 1
-        %336 = OpFunctionCall %int %tint_f32_to_i32 %335
-        %337 = OpIAdd %int %334 %336
-        %338 = OpCompositeExtract %int %vec3_i32 1
-        %339 = OpIAdd %int %337 %338
-        %340 = OpCompositeExtract %uint %vec3_u32 1
-        %341 = OpBitcast %int %340
-        %342 = OpIAdd %int %339 %341
-        %343 = OpCompositeExtract %half %vec3_f16 1
-        %344 = OpFunctionCall %int %tint_f16_to_i32 %343
-        %345 = OpIAdd %int %342 %344
-        %346 = OpCompositeExtract %float %vec4_f32 2
-        %347 = OpFunctionCall %int %tint_f32_to_i32 %346
-        %348 = OpIAdd %int %345 %347
-        %349 = OpCompositeExtract %int %vec4_i32 2
-        %350 = OpIAdd %int %348 %349
-        %351 = OpCompositeExtract %uint %vec4_u32 2
-        %352 = OpBitcast %int %351
-        %353 = OpIAdd %int %350 %352
-        %354 = OpCompositeExtract %half %vec4_f16 2
-        %355 = OpFunctionCall %int %tint_f16_to_i32 %354
-        %356 = OpIAdd %int %353 %355
-        %357 = OpCompositeExtract %float %mat2x2_f32 0 0
-        %358 = OpFunctionCall %int %tint_f32_to_i32 %357
-        %359 = OpIAdd %int %356 %358
-        %360 = OpCompositeExtract %float %mat2x3_f32 0 0
-        %361 = OpFunctionCall %int %tint_f32_to_i32 %360
-        %362 = OpIAdd %int %359 %361
-        %363 = OpCompositeExtract %float %mat2x4_f32 0 0
-        %364 = OpFunctionCall %int %tint_f32_to_i32 %363
-        %365 = OpIAdd %int %362 %364
-        %366 = OpCompositeExtract %float %mat3x2_f32 0 0
-        %367 = OpFunctionCall %int %tint_f32_to_i32 %366
+ %mat3x2_f16 = OpCompositeConstruct %mat3v2half %237 %240 %243
+        %246 = OpExtInst %uint %42 UMin %idx %uint_7
+        %247 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %246 %uint_46
+        %249 = OpLoad %v3half %247 None
+        %250 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %246 %uint_47
+        %252 = OpLoad %v3half %250 None
+        %253 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %246 %uint_48
+        %255 = OpLoad %v3half %253 None
+ %mat3x3_f16 = OpCompositeConstruct %mat3v3half %249 %252 %255
+        %258 = OpExtInst %uint %42 UMin %idx %uint_7
+        %259 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %258 %uint_49
+        %261 = OpLoad %v4half %259 None
+        %262 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %258 %uint_50
+        %264 = OpLoad %v4half %262 None
+        %265 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %258 %uint_51
+        %267 = OpLoad %v4half %265 None
+ %mat3x4_f16 = OpCompositeConstruct %mat3v4half %261 %264 %267
+        %270 = OpExtInst %uint %42 UMin %idx %uint_7
+        %271 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %270 %uint_52
+        %273 = OpLoad %v2half %271 None
+        %274 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %270 %uint_53
+        %276 = OpLoad %v2half %274 None
+        %277 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %270 %uint_54
+        %279 = OpLoad %v2half %277 None
+        %280 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %270 %uint_55
+        %282 = OpLoad %v2half %280 None
+ %mat4x2_f16 = OpCompositeConstruct %mat4v2half %273 %276 %279 %282
+        %285 = OpExtInst %uint %42 UMin %idx %uint_7
+        %286 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %285 %uint_56
+        %288 = OpLoad %v3half %286 None
+        %289 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %285 %uint_57
+        %291 = OpLoad %v3half %289 None
+        %292 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %285 %uint_58
+        %294 = OpLoad %v3half %292 None
+        %295 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %285 %uint_59
+        %297 = OpLoad %v3half %295 None
+ %mat4x3_f16 = OpCompositeConstruct %mat4v3half %288 %291 %294 %297
+        %300 = OpExtInst %uint %42 UMin %idx %uint_7
+        %301 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %300 %uint_60
+        %303 = OpLoad %v4half %301 None
+        %304 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %300 %uint_61
+        %306 = OpLoad %v4half %304 None
+        %307 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %300 %uint_62
+        %309 = OpLoad %v4half %307 None
+        %310 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %300 %uint_63
+        %312 = OpLoad %v4half %310 None
+ %mat4x4_f16 = OpCompositeConstruct %mat4v4half %303 %306 %309 %312
+        %315 = OpExtInst %uint %42 UMin %idx %uint_7
+        %316 = OpAccessChain %_ptr_Uniform__arr_v3float_uint_2 %1 %uint_0 %uint_0 %315 %uint_64
+%arr2_vec3_f32 = OpLoad %_arr_v3float_uint_2 %316 None
+        %320 = OpExtInst %uint %42 UMin %idx %uint_7
+        %321 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f16_std140_uint_2 %1 %uint_0 %uint_0 %320 %uint_65
+        %324 = OpLoad %_arr_mat4x2_f16_std140_uint_2 %321 None
+               OpStore %325 %324
+               OpBranch %331
+        %331 = OpLabel
+               OpBranch %334
+        %334 = OpLabel
+        %336 = OpPhi %uint %uint_0 %331 %337 %333
+               OpLoopMerge %335 %333 None
+               OpBranch %332
+        %332 = OpLabel
+        %338 = OpUGreaterThanEqual %bool %336 %uint_2
+               OpSelectionMerge %340 None
+               OpBranchConditional %338 %341 %340
+        %341 = OpLabel
+               OpBranch %335
+        %340 = OpLabel
+        %342 = OpAccessChain %_ptr_Function_mat4v2half %327 %336
+        %344 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %325 %336
+        %346 = OpLoad %mat4x2_f16_std140 %344 None
+        %347 = OpCompositeExtract %v2half %346 0
+        %348 = OpCompositeExtract %v2half %346 1
+        %349 = OpCompositeExtract %v2half %346 2
+        %350 = OpCompositeExtract %v2half %346 3
+        %351 = OpCompositeConstruct %mat4v2half %347 %348 %349 %350
+               OpStore %342 %351 None
+               OpBranch %333
+        %333 = OpLabel
+        %337 = OpIAdd %uint %336 %uint_1
+               OpBranch %334
+        %335 = OpLabel
+%arr2_mat4x2_f16 = OpLoad %_arr_mat4v2half_uint_2 %327 None
+        %353 = OpFunctionCall %int %tint_f32_to_i32 %scalar_f32
+        %355 = OpIAdd %int %353 %scalar_i32
+        %356 = OpBitcast %int %scalar_u32
+        %357 = OpIAdd %int %355 %356
+        %358 = OpFunctionCall %int %tint_f16_to_i32 %scalar_f16
+        %360 = OpIAdd %int %357 %358
+        %361 = OpCompositeExtract %float %vec2_f32 0
+        %362 = OpFunctionCall %int %tint_f32_to_i32 %361
+        %363 = OpIAdd %int %360 %362
+        %364 = OpCompositeExtract %int %vec2_i32 0
+        %365 = OpIAdd %int %363 %364
+        %366 = OpCompositeExtract %uint %vec2_u32 0
+        %367 = OpBitcast %int %366
         %368 = OpIAdd %int %365 %367
-        %369 = OpCompositeExtract %float %mat3x3_f32 0 0
-        %370 = OpFunctionCall %int %tint_f32_to_i32 %369
+        %369 = OpCompositeExtract %half %vec2_f16 0
+        %370 = OpFunctionCall %int %tint_f16_to_i32 %369
         %371 = OpIAdd %int %368 %370
-        %372 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %372 = OpCompositeExtract %float %vec3_f32 1
         %373 = OpFunctionCall %int %tint_f32_to_i32 %372
         %374 = OpIAdd %int %371 %373
-        %375 = OpCompositeExtract %float %mat4x2_f32 0 0
-        %376 = OpFunctionCall %int %tint_f32_to_i32 %375
-        %377 = OpIAdd %int %374 %376
-        %378 = OpCompositeExtract %float %mat4x3_f32 0 0
-        %379 = OpFunctionCall %int %tint_f32_to_i32 %378
-        %380 = OpIAdd %int %377 %379
-        %381 = OpCompositeExtract %float %mat4x4_f32 0 0
-        %382 = OpFunctionCall %int %tint_f32_to_i32 %381
-        %383 = OpIAdd %int %380 %382
-        %384 = OpCompositeExtract %half %mat2x2_f16 0 0
-        %385 = OpFunctionCall %int %tint_f16_to_i32 %384
-        %386 = OpIAdd %int %383 %385
-        %387 = OpCompositeExtract %half %mat2x3_f16 0 0
-        %388 = OpFunctionCall %int %tint_f16_to_i32 %387
-        %389 = OpIAdd %int %386 %388
-        %390 = OpCompositeExtract %half %mat2x4_f16 0 0
-        %391 = OpFunctionCall %int %tint_f16_to_i32 %390
-        %392 = OpIAdd %int %389 %391
-        %393 = OpCompositeExtract %half %mat3x2_f16 0 0
-        %394 = OpFunctionCall %int %tint_f16_to_i32 %393
-        %395 = OpIAdd %int %392 %394
-        %396 = OpCompositeExtract %half %mat3x3_f16 0 0
-        %397 = OpFunctionCall %int %tint_f16_to_i32 %396
-        %398 = OpIAdd %int %395 %397
-        %399 = OpCompositeExtract %half %mat3x4_f16 0 0
-        %400 = OpFunctionCall %int %tint_f16_to_i32 %399
-        %401 = OpIAdd %int %398 %400
-        %402 = OpCompositeExtract %half %mat4x2_f16 0 0
-        %403 = OpFunctionCall %int %tint_f16_to_i32 %402
-        %404 = OpIAdd %int %401 %403
-        %405 = OpCompositeExtract %half %mat4x3_f16 0 0
-        %406 = OpFunctionCall %int %tint_f16_to_i32 %405
-        %407 = OpIAdd %int %404 %406
-        %408 = OpCompositeExtract %half %mat4x4_f16 0 0
-        %409 = OpFunctionCall %int %tint_f16_to_i32 %408
-        %410 = OpIAdd %int %407 %409
-        %411 = OpCompositeExtract %float %arr2_vec3_f32 0 0
-        %412 = OpFunctionCall %int %tint_f32_to_i32 %411
-        %413 = OpIAdd %int %410 %412
-        %414 = OpCompositeExtract %half %arr2_mat4x2_f16 0 0 0
-        %415 = OpFunctionCall %int %tint_f16_to_i32 %414
-        %416 = OpIAdd %int %413 %415
-        %417 = OpAccessChain %_ptr_StorageBuffer_int %31 %uint_0
-               OpStore %417 %416 None
+        %375 = OpCompositeExtract %int %vec3_i32 1
+        %376 = OpIAdd %int %374 %375
+        %377 = OpCompositeExtract %uint %vec3_u32 1
+        %378 = OpBitcast %int %377
+        %379 = OpIAdd %int %376 %378
+        %380 = OpCompositeExtract %half %vec3_f16 1
+        %381 = OpFunctionCall %int %tint_f16_to_i32 %380
+        %382 = OpIAdd %int %379 %381
+        %383 = OpCompositeExtract %float %vec4_f32 2
+        %384 = OpFunctionCall %int %tint_f32_to_i32 %383
+        %385 = OpIAdd %int %382 %384
+        %386 = OpCompositeExtract %int %vec4_i32 2
+        %387 = OpIAdd %int %385 %386
+        %388 = OpCompositeExtract %uint %vec4_u32 2
+        %389 = OpBitcast %int %388
+        %390 = OpIAdd %int %387 %389
+        %391 = OpCompositeExtract %half %vec4_f16 2
+        %392 = OpFunctionCall %int %tint_f16_to_i32 %391
+        %393 = OpIAdd %int %390 %392
+        %394 = OpCompositeExtract %float %mat2x2_f32 0 0
+        %395 = OpFunctionCall %int %tint_f32_to_i32 %394
+        %396 = OpIAdd %int %393 %395
+        %397 = OpCompositeExtract %float %mat2x3_f32 0 0
+        %398 = OpFunctionCall %int %tint_f32_to_i32 %397
+        %399 = OpIAdd %int %396 %398
+        %400 = OpCompositeExtract %float %mat2x4_f32 0 0
+        %401 = OpFunctionCall %int %tint_f32_to_i32 %400
+        %402 = OpIAdd %int %399 %401
+        %403 = OpCompositeExtract %float %mat3x2_f32 0 0
+        %404 = OpFunctionCall %int %tint_f32_to_i32 %403
+        %405 = OpIAdd %int %402 %404
+        %406 = OpCompositeExtract %float %mat3x3_f32 0 0
+        %407 = OpFunctionCall %int %tint_f32_to_i32 %406
+        %408 = OpIAdd %int %405 %407
+        %409 = OpCompositeExtract %float %mat3x4_f32 0 0
+        %410 = OpFunctionCall %int %tint_f32_to_i32 %409
+        %411 = OpIAdd %int %408 %410
+        %412 = OpCompositeExtract %float %mat4x2_f32 0 0
+        %413 = OpFunctionCall %int %tint_f32_to_i32 %412
+        %414 = OpIAdd %int %411 %413
+        %415 = OpCompositeExtract %float %mat4x3_f32 0 0
+        %416 = OpFunctionCall %int %tint_f32_to_i32 %415
+        %417 = OpIAdd %int %414 %416
+        %418 = OpCompositeExtract %float %mat4x4_f32 0 0
+        %419 = OpFunctionCall %int %tint_f32_to_i32 %418
+        %420 = OpIAdd %int %417 %419
+        %421 = OpCompositeExtract %half %mat2x2_f16 0 0
+        %422 = OpFunctionCall %int %tint_f16_to_i32 %421
+        %423 = OpIAdd %int %420 %422
+        %424 = OpCompositeExtract %half %mat2x3_f16 0 0
+        %425 = OpFunctionCall %int %tint_f16_to_i32 %424
+        %426 = OpIAdd %int %423 %425
+        %427 = OpCompositeExtract %half %mat2x4_f16 0 0
+        %428 = OpFunctionCall %int %tint_f16_to_i32 %427
+        %429 = OpIAdd %int %426 %428
+        %430 = OpCompositeExtract %half %mat3x2_f16 0 0
+        %431 = OpFunctionCall %int %tint_f16_to_i32 %430
+        %432 = OpIAdd %int %429 %431
+        %433 = OpCompositeExtract %half %mat3x3_f16 0 0
+        %434 = OpFunctionCall %int %tint_f16_to_i32 %433
+        %435 = OpIAdd %int %432 %434
+        %436 = OpCompositeExtract %half %mat3x4_f16 0 0
+        %437 = OpFunctionCall %int %tint_f16_to_i32 %436
+        %438 = OpIAdd %int %435 %437
+        %439 = OpCompositeExtract %half %mat4x2_f16 0 0
+        %440 = OpFunctionCall %int %tint_f16_to_i32 %439
+        %441 = OpIAdd %int %438 %440
+        %442 = OpCompositeExtract %half %mat4x3_f16 0 0
+        %443 = OpFunctionCall %int %tint_f16_to_i32 %442
+        %444 = OpIAdd %int %441 %443
+        %445 = OpCompositeExtract %half %mat4x4_f16 0 0
+        %446 = OpFunctionCall %int %tint_f16_to_i32 %445
+        %447 = OpIAdd %int %444 %446
+        %448 = OpCompositeExtract %float %arr2_vec3_f32 0 0
+        %449 = OpFunctionCall %int %tint_f32_to_i32 %448
+        %450 = OpIAdd %int %447 %449
+        %451 = OpCompositeExtract %half %arr2_mat4x2_f16 0 0 0
+        %452 = OpFunctionCall %int %tint_f16_to_i32 %451
+        %453 = OpIAdd %int %450 %452
+        %454 = OpAccessChain %_ptr_StorageBuffer_int %31 %uint_0
+               OpStore %454 %453 None
                OpReturn
                OpFunctionEnd
-%tint_f32_to_i32 = OpFunction %int None %420
+%tint_f32_to_i32 = OpFunction %int None %457
       %value = OpFunctionParameter %float
-        %421 = OpLabel
-        %422 = OpConvertFToS %int %value
-        %423 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
-        %425 = OpSelect %int %423 %422 %int_n2147483648
-        %427 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
-        %429 = OpSelect %int %427 %425 %int_2147483647
-               OpReturnValue %429
+        %458 = OpLabel
+        %459 = OpConvertFToS %int %value
+        %460 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
+        %462 = OpSelect %int %460 %459 %int_n2147483648
+        %464 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
+        %466 = OpSelect %int %464 %462 %int_2147483647
+               OpReturnValue %466
                OpFunctionEnd
-%tint_f16_to_i32 = OpFunction %int None %432
+%tint_f16_to_i32 = OpFunction %int None %469
     %value_0 = OpFunctionParameter %half
-        %433 = OpLabel
-        %434 = OpConvertFToS %int %value_0
-        %435 = OpFOrdGreaterThanEqual %bool %value_0 %half_n0x1_ffcp_15
-        %437 = OpSelect %int %435 %434 %int_n2147483648
-        %438 = OpFOrdLessThanEqual %bool %value_0 %half_0x1_ffcp_15
-        %440 = OpSelect %int %438 %437 %int_2147483647
-               OpReturnValue %440
+        %470 = OpLabel
+        %471 = OpConvertFToS %int %value_0
+        %472 = OpFOrdGreaterThanEqual %bool %value_0 %half_n0x1_ffcp_15
+        %474 = OpSelect %int %472 %471 %int_n2147483648
+        %475 = OpFOrdLessThanEqual %bool %value_0 %half_0x1_ffcp_15
+        %477 = OpSelect %int %475 %474 %int_2147483647
+               OpReturnValue %477
                OpFunctionEnd
-       %main = OpFunction %void None %442
-        %443 = OpLabel
-        %444 = OpLoad %uint %main_local_invocation_index_Input None
-        %445 = OpFunctionCall %void %main_inner %444
+       %main = OpFunction %void None %479
+        %480 = OpLabel
+        %481 = OpLoad %uint %main_local_invocation_index_Input None
+        %482 = OpFunctionCall %void %main_inner %481
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/static_index/read.wgsl.expected.glsl b/test/tint/buffer/uniform/static_index/read.wgsl.expected.glsl
index eed92a4..49869c9 100644
--- a/test/tint/buffer/uniform/static_index/read.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/static_index/read.wgsl.expected.glsl
@@ -113,14 +113,14 @@
   int v_7 = (v_6 + int(vec3_u32[1u]));
   int v_8 = ((v_7 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_9 = (v_8 + int(vec4_u32[2u]));
-  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  v_1.inner = (((v_18 + tint_f32_to_i32(arr2_vec3_f32[0][0u])) + struct_inner.scalar_i32) + array_struct_inner[0].scalar_i32);
+  int v_10 = (v_9 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_11 = (v_10 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_12 = (v_11 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_13 = (v_12 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_14 = (v_13 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_15 = (v_14 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_16 = (v_15 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_17 = (v_16 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_18 = (v_17 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  v_1.inner = (((v_18 + tint_f32_to_i32(arr2_vec3_f32[0u][0u])) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32);
 }
diff --git a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.dxc.hlsl
index 5649640..6cb832b 100644
--- a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.dxc.hlsl
@@ -147,15 +147,15 @@
   int v_40 = (v_39 + int(vec3_u32.y));
   int v_41 = ((v_40 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_42 = (v_41 + int(vec4_u32.z));
-  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((((v_51 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((((v_51 + tint_f32_to_i32(arr2_vec3_f32[0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.fxc.hlsl
index 5649640..6cb832b 100644
--- a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.fxc.hlsl
@@ -147,15 +147,15 @@
   int v_40 = (v_39 + int(vec3_u32.y));
   int v_41 = ((v_40 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_42 = (v_41 + int(vec4_u32.z));
-  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  s.Store(0u, asuint((((v_51 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_43 = (v_42 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_44 = (v_43 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_45 = (v_44 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_46 = (v_45 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_47 = (v_46 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_48 = (v_47 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_49 = (v_48 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_50 = (v_49 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_51 = (v_50 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  s.Store(0u, asuint((((v_51 + tint_f32_to_i32(arr2_vec3_f32[0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.msl b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.msl
index a4eb1f7..fc5384a 100644
--- a/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/static_index/read.wgsl.expected.ir.msl
@@ -115,14 +115,14 @@
   int const v_15 = as_type<int>((as_type<uint>(v_14) + as_type<uint>(int(vec3_u32[1u]))));
   int const v_16 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_15) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_17 = as_type<int>((as_type<uint>(v_16) + as_type<uint>(int(vec4_u32[2u]))));
-  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0].scalar_i32)));
+  int const v_18 = as_type<int>((as_type<uint>(v_17) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_19 = as_type<int>((as_type<uint>(v_18) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_20 = as_type<int>((as_type<uint>(v_19) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_21 = as_type<int>((as_type<uint>(v_20) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_22 = as_type<int>((as_type<uint>(v_21) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_23 = as_type<int>((as_type<uint>(v_22) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_24 = as_type<int>((as_type<uint>(v_23) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_25 = as_type<int>((as_type<uint>(v_24) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_26 = as_type<int>((as_type<uint>(v_25) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_26) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0u].scalar_i32)));
 }
diff --git a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.glsl b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.glsl
index 365c199..0ab3970a 100644
--- a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.glsl
@@ -192,24 +192,24 @@
   int v_15 = ((v_14 + tint_f32_to_i32(vec4_f32[2u])) + vec4_i32[2u]);
   int v_16 = (v_15 + int(vec4_u32[2u]));
   int v_17 = (v_16 + tint_f16_to_i32(vec4_f16[2u]));
-  int v_18 = (v_17 + tint_f32_to_i32(mat2x2_f32[0][0u]));
-  int v_19 = (v_18 + tint_f32_to_i32(mat2x3_f32[0][0u]));
-  int v_20 = (v_19 + tint_f32_to_i32(mat2x4_f32[0][0u]));
-  int v_21 = (v_20 + tint_f32_to_i32(mat3x2_f32[0][0u]));
-  int v_22 = (v_21 + tint_f32_to_i32(mat3x3_f32[0][0u]));
-  int v_23 = (v_22 + tint_f32_to_i32(mat3x4_f32[0][0u]));
-  int v_24 = (v_23 + tint_f32_to_i32(mat4x2_f32[0][0u]));
-  int v_25 = (v_24 + tint_f32_to_i32(mat4x3_f32[0][0u]));
-  int v_26 = (v_25 + tint_f32_to_i32(mat4x4_f32[0][0u]));
-  int v_27 = (v_26 + tint_f16_to_i32(mat2x2_f16[0][0u]));
-  int v_28 = (v_27 + tint_f16_to_i32(mat2x3_f16[0][0u]));
-  int v_29 = (v_28 + tint_f16_to_i32(mat2x4_f16[0][0u]));
-  int v_30 = (v_29 + tint_f16_to_i32(mat3x2_f16[0][0u]));
-  int v_31 = (v_30 + tint_f16_to_i32(mat3x3_f16[0][0u]));
-  int v_32 = (v_31 + tint_f16_to_i32(mat3x4_f16[0][0u]));
-  int v_33 = (v_32 + tint_f16_to_i32(mat4x2_f16[0][0u]));
-  int v_34 = (v_33 + tint_f16_to_i32(mat4x3_f16[0][0u]));
-  int v_35 = (v_34 + tint_f16_to_i32(mat4x4_f16[0][0u]));
-  int v_36 = (v_35 + tint_f32_to_i32(arr2_vec3_f32[0][0u]));
-  v_1.inner = (((v_36 + tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u])) + struct_inner.scalar_i32) + array_struct_inner[0].scalar_i32);
+  int v_18 = (v_17 + tint_f32_to_i32(mat2x2_f32[0u][0u]));
+  int v_19 = (v_18 + tint_f32_to_i32(mat2x3_f32[0u][0u]));
+  int v_20 = (v_19 + tint_f32_to_i32(mat2x4_f32[0u][0u]));
+  int v_21 = (v_20 + tint_f32_to_i32(mat3x2_f32[0u][0u]));
+  int v_22 = (v_21 + tint_f32_to_i32(mat3x3_f32[0u][0u]));
+  int v_23 = (v_22 + tint_f32_to_i32(mat3x4_f32[0u][0u]));
+  int v_24 = (v_23 + tint_f32_to_i32(mat4x2_f32[0u][0u]));
+  int v_25 = (v_24 + tint_f32_to_i32(mat4x3_f32[0u][0u]));
+  int v_26 = (v_25 + tint_f32_to_i32(mat4x4_f32[0u][0u]));
+  int v_27 = (v_26 + tint_f16_to_i32(mat2x2_f16[0u][0u]));
+  int v_28 = (v_27 + tint_f16_to_i32(mat2x3_f16[0u][0u]));
+  int v_29 = (v_28 + tint_f16_to_i32(mat2x4_f16[0u][0u]));
+  int v_30 = (v_29 + tint_f16_to_i32(mat3x2_f16[0u][0u]));
+  int v_31 = (v_30 + tint_f16_to_i32(mat3x3_f16[0u][0u]));
+  int v_32 = (v_31 + tint_f16_to_i32(mat3x4_f16[0u][0u]));
+  int v_33 = (v_32 + tint_f16_to_i32(mat4x2_f16[0u][0u]));
+  int v_34 = (v_33 + tint_f16_to_i32(mat4x3_f16[0u][0u]));
+  int v_35 = (v_34 + tint_f16_to_i32(mat4x4_f16[0u][0u]));
+  int v_36 = (v_35 + tint_f32_to_i32(arr2_vec3_f32[0u][0u]));
+  v_1.inner = (((v_36 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u])) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32);
 }
diff --git a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
index 9f2e34e..9ef6eb6 100644
--- a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.dxc.hlsl
@@ -287,25 +287,25 @@
   int v_101 = ((v_100 + tint_f32_to_i32(vec4_f32.z)) + vec4_i32.z);
   int v_102 = (v_101 + int(vec4_u32.z));
   int v_103 = (v_102 + tint_f16_to_i32(vec4_f16.z));
-  int v_104 = (v_103 + tint_f32_to_i32(mat2x2_f32[int(0)].x));
-  int v_105 = (v_104 + tint_f32_to_i32(mat2x3_f32[int(0)].x));
-  int v_106 = (v_105 + tint_f32_to_i32(mat2x4_f32[int(0)].x));
-  int v_107 = (v_106 + tint_f32_to_i32(mat3x2_f32[int(0)].x));
-  int v_108 = (v_107 + tint_f32_to_i32(mat3x3_f32[int(0)].x));
-  int v_109 = (v_108 + tint_f32_to_i32(mat3x4_f32[int(0)].x));
-  int v_110 = (v_109 + tint_f32_to_i32(mat4x2_f32[int(0)].x));
-  int v_111 = (v_110 + tint_f32_to_i32(mat4x3_f32[int(0)].x));
-  int v_112 = (v_111 + tint_f32_to_i32(mat4x4_f32[int(0)].x));
-  int v_113 = (v_112 + tint_f16_to_i32(mat2x2_f16[int(0)].x));
-  int v_114 = (v_113 + tint_f16_to_i32(mat2x3_f16[int(0)].x));
-  int v_115 = (v_114 + tint_f16_to_i32(mat2x4_f16[int(0)].x));
-  int v_116 = (v_115 + tint_f16_to_i32(mat3x2_f16[int(0)].x));
-  int v_117 = (v_116 + tint_f16_to_i32(mat3x3_f16[int(0)].x));
-  int v_118 = (v_117 + tint_f16_to_i32(mat3x4_f16[int(0)].x));
-  int v_119 = (v_118 + tint_f16_to_i32(mat4x2_f16[int(0)].x));
-  int v_120 = (v_119 + tint_f16_to_i32(mat4x3_f16[int(0)].x));
-  int v_121 = (v_120 + tint_f16_to_i32(mat4x4_f16[int(0)].x));
-  int v_122 = (v_121 + tint_f32_to_i32(arr2_vec3_f32[int(0)].x));
-  s.Store(0u, asuint((((v_122 + tint_f16_to_i32(arr2_mat4x2_f16[int(0)][int(0)].x)) + struct_inner.scalar_i32) + array_struct_inner[int(0)].scalar_i32)));
+  int v_104 = (v_103 + tint_f32_to_i32(mat2x2_f32[0u].x));
+  int v_105 = (v_104 + tint_f32_to_i32(mat2x3_f32[0u].x));
+  int v_106 = (v_105 + tint_f32_to_i32(mat2x4_f32[0u].x));
+  int v_107 = (v_106 + tint_f32_to_i32(mat3x2_f32[0u].x));
+  int v_108 = (v_107 + tint_f32_to_i32(mat3x3_f32[0u].x));
+  int v_109 = (v_108 + tint_f32_to_i32(mat3x4_f32[0u].x));
+  int v_110 = (v_109 + tint_f32_to_i32(mat4x2_f32[0u].x));
+  int v_111 = (v_110 + tint_f32_to_i32(mat4x3_f32[0u].x));
+  int v_112 = (v_111 + tint_f32_to_i32(mat4x4_f32[0u].x));
+  int v_113 = (v_112 + tint_f16_to_i32(mat2x2_f16[0u].x));
+  int v_114 = (v_113 + tint_f16_to_i32(mat2x3_f16[0u].x));
+  int v_115 = (v_114 + tint_f16_to_i32(mat2x4_f16[0u].x));
+  int v_116 = (v_115 + tint_f16_to_i32(mat3x2_f16[0u].x));
+  int v_117 = (v_116 + tint_f16_to_i32(mat3x3_f16[0u].x));
+  int v_118 = (v_117 + tint_f16_to_i32(mat3x4_f16[0u].x));
+  int v_119 = (v_118 + tint_f16_to_i32(mat4x2_f16[0u].x));
+  int v_120 = (v_119 + tint_f16_to_i32(mat4x3_f16[0u].x));
+  int v_121 = (v_120 + tint_f16_to_i32(mat4x4_f16[0u].x));
+  int v_122 = (v_121 + tint_f32_to_i32(arr2_vec3_f32[0u].x));
+  s.Store(0u, asuint((((v_122 + tint_f16_to_i32(arr2_mat4x2_f16[0u][0u].x)) + struct_inner.scalar_i32) + array_struct_inner[0u].scalar_i32)));
 }
 
diff --git a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.msl b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.msl
index 739c2c6..c967a95 100644
--- a/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/static_index/read_f16.wgsl.expected.ir.msl
@@ -169,24 +169,24 @@
   int const v_28 = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_27) + as_type<uint>(tint_f32_to_i32(vec4_f32[2u]))))) + as_type<uint>(vec4_i32[2u])));
   int const v_29 = as_type<int>((as_type<uint>(v_28) + as_type<uint>(int(vec4_u32[2u]))));
   int const v_30 = as_type<int>((as_type<uint>(v_29) + as_type<uint>(tint_f16_to_i32(vec4_f16[2u]))));
-  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0][0u]))));
-  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0][0u]))));
-  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0][0u]))));
-  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0][0u]))));
-  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0][0u]))));
-  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0][0u]))));
-  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0][0u]))));
-  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0][0u]))));
-  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0][0u]))));
-  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0][0u]))));
-  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0][0u]))));
-  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0][0u]))));
-  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0][0u]))));
-  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0][0u]))));
-  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0][0u]))));
-  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0][0u]))));
-  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0][0u]))));
-  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0][0u]))));
-  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0][0u]))));
-  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0][0][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0].scalar_i32)));
+  int const v_31 = as_type<int>((as_type<uint>(v_30) + as_type<uint>(tint_f32_to_i32(mat2x2_f32[0u][0u]))));
+  int const v_32 = as_type<int>((as_type<uint>(v_31) + as_type<uint>(tint_f32_to_i32(mat2x3_f32[0u][0u]))));
+  int const v_33 = as_type<int>((as_type<uint>(v_32) + as_type<uint>(tint_f32_to_i32(mat2x4_f32[0u][0u]))));
+  int const v_34 = as_type<int>((as_type<uint>(v_33) + as_type<uint>(tint_f32_to_i32(mat3x2_f32[0u][0u]))));
+  int const v_35 = as_type<int>((as_type<uint>(v_34) + as_type<uint>(tint_f32_to_i32(mat3x3_f32[0u][0u]))));
+  int const v_36 = as_type<int>((as_type<uint>(v_35) + as_type<uint>(tint_f32_to_i32(mat3x4_f32[0u][0u]))));
+  int const v_37 = as_type<int>((as_type<uint>(v_36) + as_type<uint>(tint_f32_to_i32(mat4x2_f32[0u][0u]))));
+  int const v_38 = as_type<int>((as_type<uint>(v_37) + as_type<uint>(tint_f32_to_i32(mat4x3_f32[0u][0u]))));
+  int const v_39 = as_type<int>((as_type<uint>(v_38) + as_type<uint>(tint_f32_to_i32(mat4x4_f32[0u][0u]))));
+  int const v_40 = as_type<int>((as_type<uint>(v_39) + as_type<uint>(tint_f16_to_i32(mat2x2_f16[0u][0u]))));
+  int const v_41 = as_type<int>((as_type<uint>(v_40) + as_type<uint>(tint_f16_to_i32(mat2x3_f16[0u][0u]))));
+  int const v_42 = as_type<int>((as_type<uint>(v_41) + as_type<uint>(tint_f16_to_i32(mat2x4_f16[0u][0u]))));
+  int const v_43 = as_type<int>((as_type<uint>(v_42) + as_type<uint>(tint_f16_to_i32(mat3x2_f16[0u][0u]))));
+  int const v_44 = as_type<int>((as_type<uint>(v_43) + as_type<uint>(tint_f16_to_i32(mat3x3_f16[0u][0u]))));
+  int const v_45 = as_type<int>((as_type<uint>(v_44) + as_type<uint>(tint_f16_to_i32(mat3x4_f16[0u][0u]))));
+  int const v_46 = as_type<int>((as_type<uint>(v_45) + as_type<uint>(tint_f16_to_i32(mat4x2_f16[0u][0u]))));
+  int const v_47 = as_type<int>((as_type<uint>(v_46) + as_type<uint>(tint_f16_to_i32(mat4x3_f16[0u][0u]))));
+  int const v_48 = as_type<int>((as_type<uint>(v_47) + as_type<uint>(tint_f16_to_i32(mat4x4_f16[0u][0u]))));
+  int const v_49 = as_type<int>((as_type<uint>(v_48) + as_type<uint>(tint_f32_to_i32(arr2_vec3_f32[0u][0u]))));
+  (*tint_module_vars.s) = as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(v_49) + as_type<uint>(tint_f16_to_i32(arr2_mat4x2_f16[0u][0u][0u]))))) + as_type<uint>(struct_inner.scalar_i32)))) + as_type<uint>(array_struct_inner[0u].scalar_i32)));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 6282bcb..68b7678 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -33,11 +33,11 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x2 l_a[4] = a_load(0u);
-  float2x2 l_a_i = a_load_1((16u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  float2x2 l_a_i = a_load_1((16u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   uint4 ubo_load_2 = a[scalar_offset_2 / 4];
   float2 l_a_i_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
-  const uint scalar_offset_3 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 6282bcb..68b7678 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -33,11 +33,11 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x2 l_a[4] = a_load(0u);
-  float2x2 l_a_i = a_load_1((16u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  float2x2 l_a_i = a_load_1((16u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   uint4 ubo_load_2 = a[scalar_offset_2 / 4];
   float2 l_a_i_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
-  const uint scalar_offset_3 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index c8d026e..2383c0e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -21,9 +21,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   mat2 v_3 = mat2(v.inner[v_2].col0, v.inner[v_2].col1);
-  vec2 v_4 = v_3[i()];
+  vec2 v_4 = v_3[min(uint(i()), 1u)];
   mat2x2_f32_std140 v_5[4] = v.inner;
   mat2 v_6[4] = mat2[4](mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)));
   {
@@ -44,5 +44,5 @@
   mat2 l_a[4] = v_6;
   mat2 l_a_i = v_3;
   vec2 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 63559ed..c392245 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -40,12 +40,12 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (16u * uint(i()));
-  uint v_9 = (8u * uint(i()));
+  uint v_8 = (16u * uint(min(uint(i()), 3u)));
+  uint v_9 = (8u * uint(min(uint(i()), 1u)));
   float2x2 l_a[4] = v_4(0u);
   float2x2 l_a_i = v(v_8);
   uint4 v_10 = a[((v_8 + v_9) / 16u)];
   float2 l_a_i_i = asfloat(((((((v_8 + v_9) % 16u) / 4u) == 2u)) ? (v_10.zw) : (v_10.xy)));
-  s.Store(0u, asuint((((asfloat(a[((v_8 + v_9) / 16u)][(((v_8 + v_9) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_8 + v_9) / 16u)][(((v_8 + v_9) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 63559ed..c392245 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -40,12 +40,12 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (16u * uint(i()));
-  uint v_9 = (8u * uint(i()));
+  uint v_8 = (16u * uint(min(uint(i()), 3u)));
+  uint v_9 = (8u * uint(min(uint(i()), 1u)));
   float2x2 l_a[4] = v_4(0u);
   float2x2 l_a_i = v(v_8);
   uint4 v_10 = a[((v_8 + v_9) / 16u)];
   float2 l_a_i_i = asfloat(((((((v_8 + v_9) % 16u) / 4u) == 2u)) ? (v_10.zw) : (v_10.xy)));
-  s.Store(0u, asuint((((asfloat(a[((v_8 + v_9) / 16u)][(((v_8 + v_9) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_8 + v_9) / 16u)][(((v_8 + v_9) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index bac1d35a..6500865 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<float2x2, 4>* const p_a = tint_module_vars.a;
-  const constant float2x2* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant float2* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant float2x2* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant float2* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<float2x2, 4> const l_a = (*p_a);
   float2x2 const l_a_i = (*p_a_i);
   float2 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 43474ac..b53111d 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 1u);
   tint_array<float2x2, 4> const l_a = *(tint_symbol_2);
   float2x2 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   float2 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 8c3a8fa..19089c3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -56,6 +57,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat2x2_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x2_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
 %mat2v2float = OpTypeMatrix %v2float 2
@@ -64,7 +66,7 @@
 %_ptr_Function__arr_mat2x2_f32_std140_uint_4 = OpTypePointer Function %_arr_mat2x2_f32_std140_uint_4
 %_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4
 %_ptr_Function__arr_mat2v2float_uint_4 = OpTypePointer Function %_arr_mat2v2float_uint_4
-         %52 = OpConstantNull %_arr_mat2v2float_uint_4
+         %58 = OpConstantNull %_arr_mat2v2float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2x2_f32_std140 = OpTypePointer Function %mat2x2_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -78,57 +80,61 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %40 = OpVariable %_ptr_Function_mat2v2float Function
-         %47 = OpVariable %_ptr_Function__arr_mat2x2_f32_std140_uint_4 Function
-         %49 = OpVariable %_ptr_Function__arr_mat2v2float_uint_4 Function %52
+         %44 = OpVariable %_ptr_Function_mat2v2float Function
+         %53 = OpVariable %_ptr_Function__arr_mat2x2_f32_std140_uint_4 Function
+         %55 = OpVariable %_ptr_Function__arr_mat2v2float_uint_4 Function %58
          %28 = OpAccessChain %_ptr_Uniform__arr_mat2x2_f32_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_0
-         %34 = OpLoad %v2float %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_1
-         %37 = OpLoad %v2float %35 None
-      %l_a_i = OpCompositeConstruct %mat2v2float %34 %37
-               OpStore %40 %l_a_i
-         %42 = OpFunctionCall %int %i
-         %43 = OpAccessChain %_ptr_Function_v2float %40 %42
-    %l_a_i_i = OpLoad %v2float %43 None
-         %46 = OpLoad %_arr_mat2x2_f32_std140_uint_4 %28 None
-               OpStore %47 %46
-               OpBranch %53
-         %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
-               OpBranch %54
-         %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_0
+         %38 = OpLoad %v2float %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_1
+         %41 = OpLoad %v2float %39 None
+      %l_a_i = OpCompositeConstruct %mat2v2float %38 %41
+               OpStore %44 %l_a_i
+         %46 = OpFunctionCall %int %i
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %34 UMin %47 %uint_1
+         %49 = OpAccessChain %_ptr_Function_v2float %44 %48
+    %l_a_i_i = OpLoad %v2float %49 None
+         %52 = OpLoad %_arr_mat2x2_f32_std140_uint_4 %28 None
+               OpStore %53 %52
+               OpBranch %59
+         %59 = OpLabel
+               OpBranch %62
          %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_mat2v2float %49 %58
-         %65 = OpAccessChain %_ptr_Function_mat2x2_f32_std140 %47 %58
-         %67 = OpLoad %mat2x2_f32_std140 %65 None
-         %68 = OpCompositeExtract %v2float %67 0
-         %69 = OpCompositeExtract %v2float %67 1
-         %70 = OpCompositeConstruct %mat2v2float %68 %69
-               OpStore %64 %70 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_mat2v2float_uint_4 %49 None
-         %72 = OpCompositeExtract %float %l_a_i_i 0
-         %73 = OpCompositeExtract %float %l_a 0 0 0
-         %74 = OpFAdd %float %72 %73
-         %75 = OpCompositeExtract %float %l_a_i 0 0
-         %76 = OpFAdd %float %74 %75
-         %77 = OpCompositeExtract %float %l_a_i_i 0
-         %78 = OpFAdd %float %76 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %79 %78 None
+         %64 = OpPhi %uint %uint_0 %59 %65 %61
+               OpLoopMerge %63 %61 None
+               OpBranch %60
+         %60 = OpLabel
+         %66 = OpUGreaterThanEqual %bool %64 %uint_4
+               OpSelectionMerge %68 None
+               OpBranchConditional %66 %69 %68
+         %69 = OpLabel
+               OpBranch %63
+         %68 = OpLabel
+         %70 = OpAccessChain %_ptr_Function_mat2v2float %55 %64
+         %71 = OpAccessChain %_ptr_Function_mat2x2_f32_std140 %53 %64
+         %73 = OpLoad %mat2x2_f32_std140 %71 None
+         %74 = OpCompositeExtract %v2float %73 0
+         %75 = OpCompositeExtract %v2float %73 1
+         %76 = OpCompositeConstruct %mat2v2float %74 %75
+               OpStore %70 %76 None
+               OpBranch %61
+         %61 = OpLabel
+         %65 = OpIAdd %uint %64 %uint_1
+               OpBranch %62
+         %63 = OpLabel
+        %l_a = OpLoad %_arr_mat2v2float_uint_4 %55 None
+         %78 = OpCompositeExtract %float %l_a_i_i 0
+         %79 = OpCompositeExtract %float %l_a 0 0 0
+         %80 = OpFAdd %float %78 %79
+         %81 = OpCompositeExtract %float %l_a_i 0 0
+         %82 = OpFAdd %float %80 %81
+         %83 = OpCompositeExtract %float %l_a_i_i 0
+         %84 = OpFAdd %float %82 %83
+         %85 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %85 %84 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
index ebff0e4..63547cd 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -16,7 +16,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2 v_2 = mat2(v.inner[2].col0, v.inner[2].col1);
+  mat2 v_2 = mat2(v.inner[2u].col0, v.inner[2u].col1);
   mat2x2_f32_std140 v_3[4] = v.inner;
   mat2 v_4[4] = mat2[4](mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)), mat2(vec2(0.0f), vec2(0.0f)));
   {
@@ -36,6 +36,6 @@
   }
   mat2 l_a[4] = v_4;
   mat2 l_a_i = v_2;
-  vec2 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  vec2 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 8ba2a03..5f399ac 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,6 +37,6 @@
   float2x2 l_a[4] = v_4(0u);
   float2x2 l_a_i = v(32u);
   float2 l_a_i_i = asfloat(a[2u].zw);
-  s.Store(0u, asuint((((asfloat(a[2u].z) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[2u].z) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 8ba2a03..5f399ac 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,6 +37,6 @@
   float2x2 l_a[4] = v_4(0u);
   float2x2 l_a_i = v(32u);
   float2 l_a_i_i = asfloat(a[2u].zw);
-  s.Store(0u, asuint((((asfloat(a[2u].z) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[2u].z) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 70dc50d..4559635 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<float2x2, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<float2x2, 4>* const p_a = tint_module_vars.a;
-  const constant float2x2* const p_a_2 = (&(*p_a)[2]);
-  const constant float2* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant float2x2* const p_a_2 = (&(*p_a)[2u]);
+  const constant float2* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<float2x2, 4> const l_a = (*p_a);
   float2x2 const l_a_i = (*p_a_2);
   float2 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
index cd8f016..67fd110 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -49,66 +49,65 @@
 %_ptr_Uniform__arr_mat2x2_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x2_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %mat2v2float = OpTypeMatrix %v2float 2
 %_ptr_Function__arr_mat2x2_f32_std140_uint_4 = OpTypePointer Function %_arr_mat2x2_f32_std140_uint_4
 %_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4
 %_ptr_Function__arr_mat2v2float_uint_4 = OpTypePointer Function %_arr_mat2v2float_uint_4
-         %37 = OpConstantNull %_arr_mat2v2float_uint_4
+         %36 = OpConstantNull %_arr_mat2v2float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
 %_ptr_Function_mat2x2_f32_std140 = OpTypePointer Function %mat2x2_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %32 = OpVariable %_ptr_Function__arr_mat2x2_f32_std140_uint_4 Function
-         %34 = OpVariable %_ptr_Function__arr_mat2v2float_uint_4 Function %37
+         %31 = OpVariable %_ptr_Function__arr_mat2x2_f32_std140_uint_4 Function
+         %33 = OpVariable %_ptr_Function__arr_mat2v2float_uint_4 Function %36
          %17 = OpAccessChain %_ptr_Uniform__arr_mat2x2_f32_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_0
-         %24 = OpLoad %v2float %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_1
-         %27 = OpLoad %v2float %25 None
-      %l_a_i = OpCompositeConstruct %mat2v2float %24 %27
+         %20 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_0
+         %23 = OpLoad %v2float %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_1
+         %26 = OpLoad %v2float %24 None
+      %l_a_i = OpCompositeConstruct %mat2v2float %23 %26
     %l_a_i_i = OpCompositeExtract %v2float %l_a_i 1
-         %31 = OpLoad %_arr_mat2x2_f32_std140_uint_4 %17 None
-               OpStore %32 %31
-               OpBranch %38
-         %38 = OpLabel
-               OpBranch %41
-         %41 = OpLabel
-         %43 = OpPhi %uint %uint_0 %38 %44 %40
-               OpLoopMerge %42 %40 None
-               OpBranch %39
-         %39 = OpLabel
-         %45 = OpUGreaterThanEqual %bool %43 %uint_4
-               OpSelectionMerge %47 None
-               OpBranchConditional %45 %48 %47
-         %48 = OpLabel
-               OpBranch %42
-         %47 = OpLabel
-         %49 = OpAccessChain %_ptr_Function_mat2v2float %34 %43
-         %51 = OpAccessChain %_ptr_Function_mat2x2_f32_std140 %32 %43
-         %53 = OpLoad %mat2x2_f32_std140 %51 None
-         %54 = OpCompositeExtract %v2float %53 0
-         %55 = OpCompositeExtract %v2float %53 1
-         %56 = OpCompositeConstruct %mat2v2float %54 %55
-               OpStore %49 %56 None
+         %30 = OpLoad %_arr_mat2x2_f32_std140_uint_4 %17 None
+               OpStore %31 %30
+               OpBranch %37
+         %37 = OpLabel
                OpBranch %40
          %40 = OpLabel
-         %44 = OpIAdd %uint %43 %uint_1
+         %42 = OpPhi %uint %uint_0 %37 %43 %39
+               OpLoopMerge %41 %39 None
+               OpBranch %38
+         %38 = OpLabel
+         %44 = OpUGreaterThanEqual %bool %42 %uint_4
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %47 %46
+         %47 = OpLabel
                OpBranch %41
-         %42 = OpLabel
-        %l_a = OpLoad %_arr_mat2v2float_uint_4 %34 None
-         %58 = OpCompositeExtract %float %l_a_i_i 0
-         %59 = OpCompositeExtract %float %l_a 0 0 0
-         %60 = OpFAdd %float %58 %59
-         %61 = OpCompositeExtract %float %l_a_i 0 0
-         %62 = OpFAdd %float %60 %61
-         %63 = OpCompositeExtract %float %l_a_i_i 0
-         %64 = OpFAdd %float %62 %63
-         %65 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %65 %64 None
+         %46 = OpLabel
+         %48 = OpAccessChain %_ptr_Function_mat2v2float %33 %42
+         %50 = OpAccessChain %_ptr_Function_mat2x2_f32_std140 %31 %42
+         %52 = OpLoad %mat2x2_f32_std140 %50 None
+         %53 = OpCompositeExtract %v2float %52 0
+         %54 = OpCompositeExtract %v2float %52 1
+         %55 = OpCompositeConstruct %mat2v2float %53 %54
+               OpStore %48 %55 None
+               OpBranch %39
+         %39 = OpLabel
+         %43 = OpIAdd %uint %42 %uint_1
+               OpBranch %40
+         %41 = OpLabel
+        %l_a = OpLoad %_arr_mat2v2float_uint_4 %33 None
+         %57 = OpCompositeExtract %float %l_a_i_i 0
+         %58 = OpCompositeExtract %float %l_a 0 0 0
+         %59 = OpFAdd %float %57 %58
+         %60 = OpCompositeExtract %float %l_a_i 0 0
+         %61 = OpFAdd %float %59 %60
+         %62 = OpCompositeExtract %float %l_a_i_i 0
+         %63 = OpFAdd %float %61 %62
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.glsl
index 65679e4..1477fec 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.glsl
@@ -16,9 +16,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2 t = transpose(mat2(v.inner[2].col0, v.inner[2].col1));
-  float l = length(v.inner[0].col1.yx);
-  float a = abs(v.inner[0].col1.yx[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat2 t = transpose(mat2(v.inner[2u].col0, v.inner[2u].col1));
+  float l = length(v.inner[0u].col1.yx);
+  float a = abs(v.inner[0u].col1.yx[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 10b0966..fd99489 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -15,7 +15,7 @@
   float2x2 t = transpose(v(32u));
   float l = length(asfloat(u[0u].zw).yx);
   float a = abs(asfloat(u[0u].zw).yx.x);
-  float v_4 = (t[int(0)].x + float(l));
+  float v_4 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_4 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 10b0966..fd99489 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -15,7 +15,7 @@
   float2x2 t = transpose(v(32u));
   float l = length(asfloat(u[0u].zw).yx);
   float a = abs(asfloat(u[0u].zw).yx.x);
-  float v_4 = (t[int(0)].x + float(l));
+  float v_4 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_4 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
index e979dd3..0904308 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<float2x2, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  float2x2 const t = transpose((*tint_module_vars.u)[2]);
-  float const l = length((*tint_module_vars.u)[0][1].yx);
-  float const a = abs((*tint_module_vars.u)[0][1].yx[0u]);
-  float const v = (t[0][0u] + float(l));
+  float2x2 const t = transpose((*tint_module_vars.u)[2u]);
+  float const l = length((*tint_module_vars.u)[0u][1u].yx);
+  float const a = abs((*tint_module_vars.u)[0u][1u].yx[0u]);
+  float const v = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.spvasm
index b8f1aa4..c0987a0 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
-         %34 = OpExtInstImport "GLSL.std.450"
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -48,33 +48,31 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %mat2v2float = OpTypeMatrix %v2float 2
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v2float %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v2float %23 None
-         %27 = OpCompositeConstruct %mat2v2float %22 %25
-          %t = OpTranspose %mat2v2float %27
-         %29 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %31 = OpLoad %v2float %29 None
-         %32 = OpVectorShuffle %v2float %31 %31 1 0
-          %l = OpExtInst %float %34 Length %32
-         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %36 = OpLoad %v2float %35 None
-         %37 = OpVectorShuffle %v2float %36 %36 1 0
-         %38 = OpCompositeExtract %float %37 0
-          %a = OpExtInst %float %34 FAbs %38
-         %40 = OpCompositeExtract %float %t 0 0
-         %41 = OpFAdd %float %40 %l
-         %42 = OpFAdd %float %41 %a
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %43 %42 None
+         %17 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v2float %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v2float %22 None
+         %26 = OpCompositeConstruct %mat2v2float %21 %24
+          %t = OpTranspose %mat2v2float %26
+         %28 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %29 = OpLoad %v2float %28 None
+         %30 = OpVectorShuffle %v2float %29 %29 1 0
+          %l = OpExtInst %float %32 Length %30
+         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %34 = OpLoad %v2float %33 None
+         %35 = OpVectorShuffle %v2float %34 %34 1 0
+         %36 = OpCompositeExtract %float %35 0
+          %a = OpExtInst %float %32 FAbs %36
+         %38 = OpCompositeExtract %float %t 0 0
+         %39 = OpFAdd %float %38 %l
+         %40 = OpFAdd %float %39 %a
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.glsl
index 1754ce8..751dad1 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.glsl
@@ -15,10 +15,10 @@
   float inner;
 } v_2;
 float a(mat2 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec2 v) {
   return v[0u];
@@ -46,7 +46,7 @@
     }
   }
   float v_7 = a(v_4);
-  float v_8 = (v_7 + b(mat2(v_1.inner[1].col0, v_1.inner[1].col1)));
-  float v_9 = (v_8 + c(v_1.inner[1].col0.yx));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.yx[0u]));
+  float v_8 = (v_7 + b(mat2(v_1.inner[1u].col0, v_1.inner[1u].col1)));
+  float v_9 = (v_8 + c(v_1.inner[1u].col0.yx));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index 57fc09f..ca23fde 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x2 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x2 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float2 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index 57fc09f..ca23fde 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x2 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x2 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float2 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.msl
index 1fb5ecc..68eccde 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 float a(tint_array<float2x2, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float2x2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float2 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<float2x2, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_1 = a((*tint_module_vars.u));
-  float const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  float const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].yx));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].yx[0u]));
+  float const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  float const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].yx));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.spvasm
index cd6ecd7..e265ba7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 92
+; Bound: 90
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -67,8 +67,6 @@
 %_ptr_Function_mat2x2_f32_std140 = OpTypePointer Function %mat2x2_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %17
         %a_0 = OpFunctionParameter %_arr_mat2v2float_uint_4
@@ -128,25 +126,25 @@
          %51 = OpLabel
          %67 = OpLoad %_arr_mat2v2float_uint_4 %44 None
          %68 = OpFunctionCall %float %a %67
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %73 = OpLoad %v2float %69 None
-         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_1
-         %75 = OpLoad %v2float %74 None
-         %76 = OpCompositeConstruct %mat2v2float %73 %75
-         %77 = OpFunctionCall %float %b %76
-         %78 = OpFAdd %float %68 %77
-         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %80 = OpLoad %v2float %79 None
-         %81 = OpVectorShuffle %v2float %80 %80 1 0
-         %82 = OpFunctionCall %float %c %81
-         %83 = OpFAdd %float %78 %82
-         %84 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %85 = OpLoad %v2float %84 None
-         %86 = OpVectorShuffle %v2float %85 %85 1 0
-         %87 = OpCompositeExtract %float %86 0
-         %88 = OpFunctionCall %float %d %87
-         %89 = OpFAdd %float %83 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %90 %89 None
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %71 = OpLoad %v2float %69 None
+         %72 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_1
+         %73 = OpLoad %v2float %72 None
+         %74 = OpCompositeConstruct %mat2v2float %71 %73
+         %75 = OpFunctionCall %float %b %74
+         %76 = OpFAdd %float %68 %75
+         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %78 = OpLoad %v2float %77 None
+         %79 = OpVectorShuffle %v2float %78 %78 1 0
+         %80 = OpFunctionCall %float %c %79
+         %81 = OpFAdd %float %76 %80
+         %82 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %83 = OpLoad %v2float %82 None
+         %84 = OpVectorShuffle %v2float %83 %83 1 0
+         %85 = OpCompositeExtract %float %84 0
+         %86 = OpFunctionCall %float %d %85
+         %87 = OpFAdd %float %81 %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %88 %87 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.glsl
index 0079997..608d7eb 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.glsl
@@ -35,8 +35,8 @@
     }
   }
   p = v_3;
-  p[1] = mat2(v.inner[2].col0, v.inner[2].col1);
-  p[1][0] = v.inner[0].col1.yx;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = mat2(v.inner[2u].col0, v.inner[2u].col1);
+  p[1u][0u] = v.inner[0u].col1.yx;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 64c99c3..4078f44 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -37,9 +37,9 @@
 void f() {
   float2x2 v_8[4] = v_4(0u);
   p = v_8;
-  p[int(1)] = v(32u);
-  p[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  p[int(1)][int(0)].x = asfloat(u[0u].z);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(32u);
+  p[1u][0u] = asfloat(u[0u].zw).yx;
+  p[1u][0u].x = asfloat(u[0u].z);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 64c99c3..4078f44 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -37,9 +37,9 @@
 void f() {
   float2x2 v_8[4] = v_4(0u);
   p = v_8;
-  p[int(1)] = v(32u);
-  p[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  p[int(1)][int(0)].x = asfloat(u[0u].z);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(32u);
+  p[1u][0u] = asfloat(u[0u].zw).yx;
+  p[1u][0u].x = asfloat(u[0u].z);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.msl
index 859f064..28ac270 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<float2x2, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.spvasm
index 3f6b11d..2b2bdc1 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 80
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -58,12 +58,9 @@
 %_ptr_Function_mat2x2_f32_std140 = OpTypePointer Function %mat2x2_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat2v2float = OpTypePointer Private %mat2v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -102,28 +99,28 @@
          %34 = OpLabel
          %50 = OpLoad %_arr_mat2v2float_uint_4 %28 None
                OpStore %p %50 None
-         %51 = OpAccessChain %_ptr_Private_mat2v2float %p %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v2float %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v2float %59 None
-         %61 = OpCompositeConstruct %mat2v2float %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v2float %65 None
-         %67 = OpVectorShuffle %v2float %66 %66 1 0
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_float %69 %uint_0
-         %72 = OpLoad %float %70 None
-         %73 = OpAccessChain %_ptr_Private_float %68 %uint_0
-               OpStore %73 %72 None
-         %75 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Private_float %75 %uint_0
-         %77 = OpLoad %float %76 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %78 %77 None
+         %51 = OpAccessChain %_ptr_Private_mat2v2float %p %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v2float %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v2float %57 None
+         %59 = OpCompositeConstruct %mat2v2float %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v2float %62 None
+         %64 = OpVectorShuffle %v2float %63 %63 1 0
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_float %66 %uint_0
+         %69 = OpLoad %float %67 None
+         %70 = OpAccessChain %_ptr_Private_float %65 %uint_0
+               OpStore %70 %69 None
+         %72 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Private_float %72 %uint_0
+         %74 = OpLoad %float %73 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %75 %74 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.glsl
index 0453da1..c4dff7e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.glsl
@@ -34,7 +34,7 @@
     }
   }
   v_1.inner = v_3;
-  v_1.inner[1] = mat2(v.inner[2].col0, v.inner[2].col1);
-  v_1.inner[1][0] = v.inner[0].col1.yx;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  v_1.inner[1u] = mat2(v.inner[2u].col0, v.inner[2u].col1);
+  v_1.inner[1u][0u] = v.inner[0u].col1.yx;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.ir.msl
index a814951..e97a60a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<float2x2, 4>* u [[buffer(0)]], device tint_array<float2x2, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.spvasm
index df66c4b..06ef36a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -58,12 +58,9 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer__arr_mat2v2float_uint_4 = OpTypePointer StorageBuffer %_arr_mat2v2float_uint_4
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %17
@@ -102,23 +99,23 @@
          %48 = OpLoad %_arr_mat2v2float_uint_4 %25 None
          %49 = OpAccessChain %_ptr_StorageBuffer__arr_mat2v2float_uint_4 %10 %uint_0
                OpStore %49 %48 None
-         %51 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %10 %uint_0 %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v2float %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v2float %59 None
-         %61 = OpCompositeConstruct %mat2v2float %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v2float %65 None
-         %67 = OpVectorShuffle %v2float %66 %66 1 0
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_float %69 %uint_0
-         %72 = OpLoad %float %70 None
-         %73 = OpAccessChain %_ptr_StorageBuffer_float %68 %uint_0
-               OpStore %73 %72 None
+         %51 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %10 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v2float %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v2float %57 None
+         %59 = OpCompositeConstruct %mat2v2float %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v2float %62 None
+         %64 = OpVectorShuffle %v2float %63 %63 1 0
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_float %66 %uint_0
+         %69 = OpLoad %float %67 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_float %65 %uint_0
+               OpStore %70 %69 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.glsl
index b02f66b..1d37771 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.glsl
@@ -46,9 +46,9 @@
     }
   }
   w = v_4;
-  w[1] = mat2(v.inner[2].col0, v.inner[2].col1);
-  w[1][0] = v.inner[0].col1.yx;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = mat2(v.inner[2u].col0, v.inner[2u].col1);
+  w[1u][0u] = v.inner[0u].col1.yx;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 983c1ec..9d8c887 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -55,9 +55,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x2 v_10[4] = v_4(0u);
   w = v_10;
-  w[int(1)] = v(32u);
-  w[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  w[int(1)][int(0)].x = asfloat(u[0u].z);
+  w[1u] = v(32u);
+  w[1u][0u] = asfloat(u[0u].zw).yx;
+  w[1u][0u].x = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 983c1ec..9d8c887 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -55,9 +55,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x2 v_10[4] = v_4(0u);
   w = v_10;
-  w[int(1)] = v(32u);
-  w[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  w[int(1)][int(0)].x = asfloat(u[0u].z);
+  w[1u] = v(32u);
+  w[1u][0u] = asfloat(u[0u].zw).yx;
+  w[1u][0u].x = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
index ba5453b..326a767 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<float2x2, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<float2x2, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<float2x2, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.msl
index b55cc08..972347e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<float2x2, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<float2x2, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = float2x2(float2(0.0f), float2(0.0f));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
index 44ed288..d8dce72 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 95
+; Bound: 91
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -57,15 +57,11 @@
          %47 = OpConstantNull %_arr_mat2v2float_uint_4
 %_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
 %_ptr_Function_mat2x2_f32_std140 = OpTypePointer Function %mat2x2_f32_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %91 = OpTypeFunction %void
+         %87 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -124,29 +120,29 @@
          %52 = OpLabel
          %66 = OpLoad %_arr_mat2v2float_uint_4 %45 None
                OpStore %w %66 None
-         %67 = OpAccessChain %_ptr_Workgroup_mat2v2float %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %73 = OpLoad %v2float %70 None
-         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %75 = OpLoad %v2float %74 None
-         %76 = OpCompositeConstruct %mat2v2float %73 %75
-               OpStore %67 %76 None
-         %77 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %81 = OpLoad %v2float %80 None
-         %82 = OpVectorShuffle %v2float %81 %81 1 0
-               OpStore %77 %82 None
-         %83 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %85 = OpAccessChain %_ptr_Uniform_float %84 %uint_0
-         %87 = OpLoad %float %85 None
-         %88 = OpAccessChain %_ptr_Workgroup_float %83 %uint_0
-               OpStore %88 %87 None
+         %67 = OpAccessChain %_ptr_Workgroup_mat2v2float %w %uint_1
+         %68 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %70 = OpLoad %v2float %68 None
+         %71 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %72 = OpLoad %v2float %71 None
+         %73 = OpCompositeConstruct %mat2v2float %70 %72
+               OpStore %67 %73 None
+         %74 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %77 = OpLoad %v2float %76 None
+         %78 = OpVectorShuffle %v2float %77 %77 1 0
+               OpStore %74 %78 None
+         %79 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %81 = OpAccessChain %_ptr_Uniform_float %80 %uint_0
+         %83 = OpLoad %float %81 None
+         %84 = OpAccessChain %_ptr_Workgroup_float %79 %uint_0
+               OpStore %84 %83 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %87
+         %88 = OpLabel
+         %89 = OpLoad %uint %f_local_invocation_index_Input None
+         %90 = OpFunctionCall %void %f_inner %89
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 7dbffa1..b999a35 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -39,14 +39,14 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   matrix<float16_t, 2, 3> l_a[4] = a_load(0u);
-  matrix<float16_t, 2, 3> l_a_i = a_load_1((16u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  matrix<float16_t, 2, 3> l_a_i = a_load_1((16u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   uint4 ubo_load_5 = a[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
   float16_t ubo_load_4_y = f16tof32(ubo_load_4[0] >> 16);
   vector<float16_t, 3> l_a_i_i = vector<float16_t, 3>(ubo_load_4_xz[0], ubo_load_4_y, ubo_load_4_xz[1]);
-  const uint scalar_offset_bytes = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save))));
+  const uint scalar_offset_bytes = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   s.Store<float16_t>(0u, (((float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF))) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x));
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index b94dfcb..7015063 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -22,9 +22,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   f16mat2x3 v_3 = f16mat2x3(v.inner[v_2].col0, v.inner[v_2].col1);
-  f16vec3 v_4 = v_3[i()];
+  f16vec3 v_4 = v_3[min(uint(i()), 1u)];
   mat2x3_f16_std140 v_5[4] = v.inner;
   f16mat2x3 v_6[4] = f16mat2x3[4](f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
   {
@@ -45,5 +45,5 @@
   f16mat2x3 l_a[4] = v_6;
   f16mat2x3 l_a_i = v_3;
   f16vec3 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 719a1b8..94abac0 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -52,13 +52,13 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (16u * uint(i()));
-  uint v_13 = (8u * uint(i()));
+  uint v_12 = (16u * uint(min(uint(i()), 3u)));
+  uint v_13 = (8u * uint(min(uint(i()), 1u)));
   matrix<float16_t, 2, 3> l_a[4] = v_8(0u);
   matrix<float16_t, 2, 3> l_a_i = v_4(v_12);
   uint4 v_14 = a[((v_12 + v_13) / 16u)];
   vector<float16_t, 3> l_a_i_i = tint_bitcast_to_f16(((((((v_12 + v_13) % 16u) / 4u) == 2u)) ? (v_14.zw) : (v_14.xy))).xyz;
   uint v_15 = a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)];
-  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_15 >> (((((v_12 + v_13) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_15 >> (((((v_12 + v_13) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 4995b32..de99dd3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -48,12 +48,12 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant packed_half3* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)].packed);
+  const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant packed_half3* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<half2x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f16_array_element, 2> const v_11 = (*p_a_i);
   half3 const v_12 = half3(v_11[0u].packed);
   half2x3 const l_a_i = half2x3(v_12, half3(v_11[1u].packed));
   half3 const l_a_i_i = half3((*p_a_i_i));
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 9d29cc2..e84070a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -42,9 +42,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 1u);
   tint_array<half2x3, 4> const l_a = tint_unpack_vec3_in_composite_1(*(tint_symbol_2));
   half2x3 const l_a_i = tint_unpack_vec3_in_composite((*(tint_symbol_2))[p_a_i_save]);
   half3 const l_a_i_i = half3((*(tint_symbol_2))[p_a_i_save][p_a_i_i_save].elements);
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 7e8e652..2c7d701 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -59,6 +60,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat2x3_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
  %mat2v3half = OpTypeMatrix %v3half 2
@@ -67,7 +69,7 @@
 %_ptr_Function__arr_mat2x3_f16_std140_uint_4 = OpTypePointer Function %_arr_mat2x3_f16_std140_uint_4
 %_arr_mat2v3half_uint_4 = OpTypeArray %mat2v3half %uint_4
 %_ptr_Function__arr_mat2v3half_uint_4 = OpTypePointer Function %_arr_mat2v3half_uint_4
-         %52 = OpConstantNull %_arr_mat2v3half_uint_4
+         %58 = OpConstantNull %_arr_mat2v3half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -81,57 +83,61 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %40 = OpVariable %_ptr_Function_mat2v3half Function
-         %47 = OpVariable %_ptr_Function__arr_mat2x3_f16_std140_uint_4 Function
-         %49 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %52
+         %44 = OpVariable %_ptr_Function_mat2v3half Function
+         %53 = OpVariable %_ptr_Function__arr_mat2x3_f16_std140_uint_4 Function
+         %55 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %58
          %28 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f16_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_0
-         %34 = OpLoad %v3half %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_1
-         %37 = OpLoad %v3half %35 None
-      %l_a_i = OpCompositeConstruct %mat2v3half %34 %37
-               OpStore %40 %l_a_i
-         %42 = OpFunctionCall %int %i
-         %43 = OpAccessChain %_ptr_Function_v3half %40 %42
-    %l_a_i_i = OpLoad %v3half %43 None
-         %46 = OpLoad %_arr_mat2x3_f16_std140_uint_4 %28 None
-               OpStore %47 %46
-               OpBranch %53
-         %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
-               OpBranch %54
-         %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_0
+         %38 = OpLoad %v3half %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_1
+         %41 = OpLoad %v3half %39 None
+      %l_a_i = OpCompositeConstruct %mat2v3half %38 %41
+               OpStore %44 %l_a_i
+         %46 = OpFunctionCall %int %i
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %34 UMin %47 %uint_1
+         %49 = OpAccessChain %_ptr_Function_v3half %44 %48
+    %l_a_i_i = OpLoad %v3half %49 None
+         %52 = OpLoad %_arr_mat2x3_f16_std140_uint_4 %28 None
+               OpStore %53 %52
+               OpBranch %59
+         %59 = OpLabel
+               OpBranch %62
          %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_mat2v3half %49 %58
-         %65 = OpAccessChain %_ptr_Function_mat2x3_f16_std140 %47 %58
-         %67 = OpLoad %mat2x3_f16_std140 %65 None
-         %68 = OpCompositeExtract %v3half %67 0
-         %69 = OpCompositeExtract %v3half %67 1
-         %70 = OpCompositeConstruct %mat2v3half %68 %69
-               OpStore %64 %70 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_mat2v3half_uint_4 %49 None
-         %72 = OpCompositeExtract %half %l_a_i_i 0
-         %73 = OpCompositeExtract %half %l_a 0 0 0
-         %74 = OpFAdd %half %72 %73
-         %75 = OpCompositeExtract %half %l_a_i 0 0
-         %76 = OpFAdd %half %74 %75
-         %77 = OpCompositeExtract %half %l_a_i_i 0
-         %78 = OpFAdd %half %76 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %79 %78 None
+         %64 = OpPhi %uint %uint_0 %59 %65 %61
+               OpLoopMerge %63 %61 None
+               OpBranch %60
+         %60 = OpLabel
+         %66 = OpUGreaterThanEqual %bool %64 %uint_4
+               OpSelectionMerge %68 None
+               OpBranchConditional %66 %69 %68
+         %69 = OpLabel
+               OpBranch %63
+         %68 = OpLabel
+         %70 = OpAccessChain %_ptr_Function_mat2v3half %55 %64
+         %71 = OpAccessChain %_ptr_Function_mat2x3_f16_std140 %53 %64
+         %73 = OpLoad %mat2x3_f16_std140 %71 None
+         %74 = OpCompositeExtract %v3half %73 0
+         %75 = OpCompositeExtract %v3half %73 1
+         %76 = OpCompositeConstruct %mat2v3half %74 %75
+               OpStore %70 %76 None
+               OpBranch %61
+         %61 = OpLabel
+         %65 = OpIAdd %uint %64 %uint_1
+               OpBranch %62
+         %63 = OpLabel
+        %l_a = OpLoad %_arr_mat2v3half_uint_4 %55 None
+         %78 = OpCompositeExtract %half %l_a_i_i 0
+         %79 = OpCompositeExtract %half %l_a 0 0 0
+         %80 = OpFAdd %half %78 %79
+         %81 = OpCompositeExtract %half %l_a_i 0 0
+         %82 = OpFAdd %half %80 %81
+         %83 = OpCompositeExtract %half %l_a_i_i 0
+         %84 = OpFAdd %half %82 %83
+         %85 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %85 %84 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
index a68ab73..5c5227c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -17,7 +17,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x3 v_2 = f16mat2x3(v.inner[2].col0, v.inner[2].col1);
+  f16mat2x3 v_2 = f16mat2x3(v.inner[2u].col0, v.inner[2u].col1);
   mat2x3_f16_std140 v_3[4] = v.inner;
   f16mat2x3 v_4[4] = f16mat2x3[4](f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)), f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf)));
   {
@@ -37,6 +37,6 @@
   }
   f16mat2x3 l_a[4] = v_4;
   f16mat2x3 l_a_i = v_2;
-  f16vec3 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  f16vec3 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index c2b4175..b7ce9e0 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -49,6 +49,6 @@
   matrix<float16_t, 2, 3> l_a[4] = v_8(0u);
   matrix<float16_t, 2, 3> l_a_i = v_4(32u);
   vector<float16_t, 3> l_a_i_i = tint_bitcast_to_f16(a[2u].zw).xyz;
-  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].z)) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].z)) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 6b1f1eb..011125a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -41,12 +41,12 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* a [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_2 = (&(*p_a)[2]);
-  const constant packed_half3* const p_a_2_1 = (&(*p_a_2)[1].packed);
+  const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_2 = (&(*p_a)[2u]);
+  const constant packed_half3* const p_a_2_1 = (&(*p_a_2)[1u].packed);
   tint_array<half2x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f16_array_element, 2> const v_11 = (*p_a_2);
   half3 const v_12 = half3(v_11[0u].packed);
   half2x3 const l_a_i = half2x3(v_12, half3(v_11[1u].packed));
   half3 const l_a_i_i = half3((*p_a_2_1));
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
index 8b77c7f..9def70c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -52,66 +52,65 @@
 %_ptr_Uniform__arr_mat2x3_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
  %mat2v3half = OpTypeMatrix %v3half 2
 %_ptr_Function__arr_mat2x3_f16_std140_uint_4 = OpTypePointer Function %_arr_mat2x3_f16_std140_uint_4
 %_arr_mat2v3half_uint_4 = OpTypeArray %mat2v3half %uint_4
 %_ptr_Function__arr_mat2v3half_uint_4 = OpTypePointer Function %_arr_mat2v3half_uint_4
-         %37 = OpConstantNull %_arr_mat2v3half_uint_4
+         %36 = OpConstantNull %_arr_mat2v3half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2v3half = OpTypePointer Function %mat2v3half
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %32 = OpVariable %_ptr_Function__arr_mat2x3_f16_std140_uint_4 Function
-         %34 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %37
+         %31 = OpVariable %_ptr_Function__arr_mat2x3_f16_std140_uint_4 Function
+         %33 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function %36
          %17 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f16_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_0
-         %24 = OpLoad %v3half %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_1
-         %27 = OpLoad %v3half %25 None
-      %l_a_i = OpCompositeConstruct %mat2v3half %24 %27
+         %20 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_0
+         %23 = OpLoad %v3half %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_1
+         %26 = OpLoad %v3half %24 None
+      %l_a_i = OpCompositeConstruct %mat2v3half %23 %26
     %l_a_i_i = OpCompositeExtract %v3half %l_a_i 1
-         %31 = OpLoad %_arr_mat2x3_f16_std140_uint_4 %17 None
-               OpStore %32 %31
-               OpBranch %38
-         %38 = OpLabel
-               OpBranch %41
-         %41 = OpLabel
-         %43 = OpPhi %uint %uint_0 %38 %44 %40
-               OpLoopMerge %42 %40 None
-               OpBranch %39
-         %39 = OpLabel
-         %45 = OpUGreaterThanEqual %bool %43 %uint_4
-               OpSelectionMerge %47 None
-               OpBranchConditional %45 %48 %47
-         %48 = OpLabel
-               OpBranch %42
-         %47 = OpLabel
-         %49 = OpAccessChain %_ptr_Function_mat2v3half %34 %43
-         %51 = OpAccessChain %_ptr_Function_mat2x3_f16_std140 %32 %43
-         %53 = OpLoad %mat2x3_f16_std140 %51 None
-         %54 = OpCompositeExtract %v3half %53 0
-         %55 = OpCompositeExtract %v3half %53 1
-         %56 = OpCompositeConstruct %mat2v3half %54 %55
-               OpStore %49 %56 None
+         %30 = OpLoad %_arr_mat2x3_f16_std140_uint_4 %17 None
+               OpStore %31 %30
+               OpBranch %37
+         %37 = OpLabel
                OpBranch %40
          %40 = OpLabel
-         %44 = OpIAdd %uint %43 %uint_1
+         %42 = OpPhi %uint %uint_0 %37 %43 %39
+               OpLoopMerge %41 %39 None
+               OpBranch %38
+         %38 = OpLabel
+         %44 = OpUGreaterThanEqual %bool %42 %uint_4
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %47 %46
+         %47 = OpLabel
                OpBranch %41
-         %42 = OpLabel
-        %l_a = OpLoad %_arr_mat2v3half_uint_4 %34 None
-         %58 = OpCompositeExtract %half %l_a_i_i 0
-         %59 = OpCompositeExtract %half %l_a 0 0 0
-         %60 = OpFAdd %half %58 %59
-         %61 = OpCompositeExtract %half %l_a_i 0 0
-         %62 = OpFAdd %half %60 %61
-         %63 = OpCompositeExtract %half %l_a_i_i 0
-         %64 = OpFAdd %half %62 %63
-         %65 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %65 %64 None
+         %46 = OpLabel
+         %48 = OpAccessChain %_ptr_Function_mat2v3half %33 %42
+         %50 = OpAccessChain %_ptr_Function_mat2x3_f16_std140 %31 %42
+         %52 = OpLoad %mat2x3_f16_std140 %50 None
+         %53 = OpCompositeExtract %v3half %52 0
+         %54 = OpCompositeExtract %v3half %52 1
+         %55 = OpCompositeConstruct %mat2v3half %53 %54
+               OpStore %48 %55 None
+               OpBranch %39
+         %39 = OpLabel
+         %43 = OpIAdd %uint %42 %uint_1
+               OpBranch %40
+         %41 = OpLabel
+        %l_a = OpLoad %_arr_mat2v3half_uint_4 %33 None
+         %57 = OpCompositeExtract %half %l_a_i_i 0
+         %58 = OpCompositeExtract %half %l_a 0 0 0
+         %59 = OpFAdd %half %57 %58
+         %60 = OpCompositeExtract %half %l_a_i 0 0
+         %61 = OpFAdd %half %59 %60
+         %62 = OpCompositeExtract %half %l_a_i_i 0
+         %63 = OpFAdd %half %61 %62
+         %64 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.glsl
index 6486f53..0acabdc 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.glsl
@@ -17,9 +17,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x2 t = transpose(f16mat2x3(v.inner[2].col0, v.inner[2].col1));
-  float16_t l = length(v.inner[0].col1.zxy);
-  float16_t a = abs(v.inner[0].col1.zxy[0u]);
+  f16mat3x2 t = transpose(f16mat2x3(v.inner[2u].col0, v.inner[2u].col1));
+  float16_t l = length(v.inner[0u].col1.zxy);
+  float16_t a = abs(v.inner[0u].col1.zxy[0u]);
   float16_t v_2 = float16_t(a);
-  v_1.inner = ((v_2 + float16_t(l)) + t[0][0u]);
+  v_1.inner = ((v_2 + float16_t(l)) + t[0u][0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
index 0d2875b..c2de00b 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -28,6 +28,6 @@
   float16_t l = length(tint_bitcast_to_f16(u[0u].zw).xyz.zxy);
   float16_t a = abs(tint_bitcast_to_f16(u[0u].zw).xyz.zxy.x);
   float16_t v_8 = float16_t(a);
-  s.Store<float16_t>(0u, ((v_8 + float16_t(l)) + t[int(0)].x));
+  s.Store<float16_t>(0u, ((v_8 + float16_t(l)) + t[0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
index 312ecec..a84c16d 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -25,11 +25,11 @@
 
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u)[2u];
   half3 const v_1 = half3(v[0u].packed);
   half3x2 const t = transpose(half2x3(v_1, half3(v[1u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  half const a = abs(half3((*tint_module_vars.u)[0][1].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  half const a = abs(half3((*tint_module_vars.u)[0u][1u].packed).zxy[0u]);
   half const v_2 = half(a);
-  (*tint_module_vars.s) = ((v_2 + half(l)) + t[0][0u]);
+  (*tint_module_vars.s) = ((v_2 + half(l)) + t[0u][0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.spvasm
index 6d152ad..0a8a685 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %36 = OpExtInstImport "GLSL.std.450"
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -51,35 +51,33 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
  %mat2v3half = OpTypeMatrix %v3half 2
      %v2half = OpTypeVector %half 2
  %mat3v2half = OpTypeMatrix %v2half 3
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v3half %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v3half %23 None
-         %27 = OpCompositeConstruct %mat2v3half %22 %25
-          %t = OpTranspose %mat3v2half %27
-         %31 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %33 = OpLoad %v3half %31 None
-         %34 = OpVectorShuffle %v3half %33 %33 2 0 1
-          %l = OpExtInst %half %36 Length %34
-         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %38 = OpLoad %v3half %37 None
-         %39 = OpVectorShuffle %v3half %38 %38 2 0 1
-         %40 = OpCompositeExtract %half %39 0
-          %a = OpExtInst %half %36 FAbs %40
-         %42 = OpFAdd %half %a %l
-         %43 = OpCompositeExtract %half %t 0 0
-         %44 = OpFAdd %half %42 %43
-         %45 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %45 %44 None
+         %17 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v3half %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v3half %22 None
+         %26 = OpCompositeConstruct %mat2v3half %21 %24
+          %t = OpTranspose %mat3v2half %26
+         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %31 = OpLoad %v3half %30 None
+         %32 = OpVectorShuffle %v3half %31 %31 2 0 1
+          %l = OpExtInst %half %34 Length %32
+         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v3half %35 None
+         %37 = OpVectorShuffle %v3half %36 %36 2 0 1
+         %38 = OpCompositeExtract %half %37 0
+          %a = OpExtInst %half %34 FAbs %38
+         %40 = OpFAdd %half %a %l
+         %41 = OpCompositeExtract %half %t 0 0
+         %42 = OpFAdd %half %40 %41
+         %43 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.glsl
index f105a48..05cd490 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.glsl
@@ -16,10 +16,10 @@
   float16_t inner;
 } v_2;
 float16_t a(f16mat2x3 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float16_t b(f16mat2x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float16_t c(f16vec3 v) {
   return v[0u];
@@ -47,7 +47,7 @@
     }
   }
   float16_t v_7 = a(v_4);
-  float16_t v_8 = (v_7 + b(f16mat2x3(v_1.inner[1].col0, v_1.inner[1].col1)));
-  float16_t v_9 = (v_8 + c(v_1.inner[1].col0.zxy));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.zxy[0u]));
+  float16_t v_8 = (v_7 + b(f16mat2x3(v_1.inner[1u].col0, v_1.inner[1u].col1)));
+  float16_t v_9 = (v_8 + c(v_1.inner[1u].col0.zxy));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
index 0b42010..e524a73 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float16_t a(matrix<float16_t, 2, 3> a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float16_t b(matrix<float16_t, 2, 3> m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float16_t c(vector<float16_t, 3> v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.msl
index b20bcdf..de98f09 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.ir.msl
@@ -24,11 +24,11 @@
 };
 
 half a(tint_array<half2x3, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 half b(half2x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 half c(half3 v) {
@@ -57,9 +57,9 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   half const v_12 = a(tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[1];
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[1u];
   half3 const v_14 = half3(v_13[0u].packed);
   half const v_15 = (v_12 + b(half2x3(v_14, half3(v_13[1u].packed))));
-  half const v_16 = (v_15 + c(half3((*tint_module_vars.u)[1][0].packed).zxy));
-  (*tint_module_vars.s) = (v_16 + d(half3((*tint_module_vars.u)[1][0].packed).zxy[0u]));
+  half const v_16 = (v_15 + c(half3((*tint_module_vars.u)[1u][0u].packed).zxy));
+  (*tint_module_vars.s) = (v_16 + d(half3((*tint_module_vars.u)[1u][0u].packed).zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.spvasm
index 78707f1..d1b3c5b 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 92
+; Bound: 90
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,8 +70,6 @@
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %a = OpFunction %half None %17
         %a_0 = OpFunctionParameter %_arr_mat2v3half_uint_4
@@ -131,25 +129,25 @@
          %51 = OpLabel
          %67 = OpLoad %_arr_mat2v3half_uint_4 %44 None
          %68 = OpFunctionCall %half %a %67
-         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %73 = OpLoad %v3half %69 None
-         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_1
-         %75 = OpLoad %v3half %74 None
-         %76 = OpCompositeConstruct %mat2v3half %73 %75
-         %77 = OpFunctionCall %half %b %76
-         %78 = OpFAdd %half %68 %77
-         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %80 = OpLoad %v3half %79 None
-         %81 = OpVectorShuffle %v3half %80 %80 2 0 1
-         %82 = OpFunctionCall %half %c %81
-         %83 = OpFAdd %half %78 %82
-         %84 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %85 = OpLoad %v3half %84 None
-         %86 = OpVectorShuffle %v3half %85 %85 2 0 1
-         %87 = OpCompositeExtract %half %86 0
-         %88 = OpFunctionCall %half %d %87
-         %89 = OpFAdd %half %83 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %90 %89 None
+         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %71 = OpLoad %v3half %69 None
+         %72 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_1
+         %73 = OpLoad %v3half %72 None
+         %74 = OpCompositeConstruct %mat2v3half %71 %73
+         %75 = OpFunctionCall %half %b %74
+         %76 = OpFAdd %half %68 %75
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %78 = OpLoad %v3half %77 None
+         %79 = OpVectorShuffle %v3half %78 %78 2 0 1
+         %80 = OpFunctionCall %half %c %79
+         %81 = OpFAdd %half %76 %80
+         %82 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %83 = OpLoad %v3half %82 None
+         %84 = OpVectorShuffle %v3half %83 %83 2 0 1
+         %85 = OpCompositeExtract %half %84 0
+         %86 = OpFunctionCall %half %d %85
+         %87 = OpFAdd %half %81 %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %88 %87 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.glsl
index c825a93..db9ca9e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.glsl
@@ -36,8 +36,8 @@
     }
   }
   p = v_3;
-  p[1] = f16mat2x3(v.inner[2].col0, v.inner[2].col1);
-  p[1][0] = v.inner[0].col1.zxy;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = f16mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  p[1u][0u] = v.inner[0u].col1.zxy;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 0e898e0..74247b3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -49,9 +49,9 @@
 void f() {
   matrix<float16_t, 2, 3> v_12[4] = v_8(0u);
   p = v_12;
-  p[int(1)] = v_4(32u);
-  p[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
-  p[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
-  s.Store<float16_t>(0u, p[int(1)][int(0)].x);
+  p[1u] = v_4(32u);
+  p[1u][0u] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
+  p[1u][0u].x = float16_t(f16tof32(u[0u].z));
+  s.Store<float16_t>(0u, p[1u][0u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.msl
index fc79c1f..b8c9db4 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.ir.msl
@@ -43,10 +43,10 @@
   thread tint_array<half2x3, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_11 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_11 = (*tint_module_vars.u)[2u];
   half3 const v_12 = half3(v_11[0u].packed);
-  (*tint_module_vars.p)[1] = half2x3(v_12, half3(v_11[1u].packed));
-  (*tint_module_vars.p)[1][0] = half3((*tint_module_vars.u)[0][1].packed).zxy;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = half2x3(v_12, half3(v_11[1u].packed));
+  (*tint_module_vars.p)[1u][0u] = half3((*tint_module_vars.u)[0u][1u].packed).zxy;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.spvasm
index 709bdde..fac5347 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 80
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -61,12 +61,9 @@
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat2v3half = OpTypePointer Private %mat2v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -105,28 +102,28 @@
          %34 = OpLabel
          %50 = OpLoad %_arr_mat2v3half_uint_4 %28 None
                OpStore %p %50 None
-         %51 = OpAccessChain %_ptr_Private_mat2v3half %p %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v3half %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v3half %59 None
-         %61 = OpCompositeConstruct %mat2v3half %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v3half %65 None
-         %67 = OpVectorShuffle %v3half %66 %66 2 0 1
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_half %69 %uint_0
-         %72 = OpLoad %half %70 None
-         %73 = OpAccessChain %_ptr_Private_half %68 %uint_0
-               OpStore %73 %72 None
-         %75 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Private_half %75 %uint_0
-         %77 = OpLoad %half %76 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %78 %77 None
+         %51 = OpAccessChain %_ptr_Private_mat2v3half %p %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v3half %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v3half %57 None
+         %59 = OpCompositeConstruct %mat2v3half %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v3half %62 None
+         %64 = OpVectorShuffle %v3half %63 %63 2 0 1
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_half %66 %uint_0
+         %69 = OpLoad %half %67 None
+         %70 = OpAccessChain %_ptr_Private_half %65 %uint_0
+               OpStore %70 %69 None
+         %72 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Private_half %72 %uint_0
+         %74 = OpLoad %half %73 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %75 %74 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
index 8f8aa0e..24777e9 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -56,8 +56,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  f16mat2x3 v_8 = f16mat2x3(v.inner[2].col0, v.inner[2].col1);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[1][0] = v.inner[0].col1.zxy;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  f16mat2x3 v_8 = f16mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[1u][0u] = v.inner[0u].col1.zxy;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.ir.msl
index f94c189..8409b50 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* u;
   device tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* s;
@@ -33,6 +36,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -64,9 +68,9 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* u [[buffer(0)]], device tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[2u];
   half3 const v_14 = half3(v_13[0u].packed);
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), half2x3(v_14, half3(v_13[1u].packed)));
-  (*tint_module_vars.s)[1][0].packed = packed_half3(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.s)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), half2x3(v_14, half3(v_13[1u].packed)));
+  (*tint_module_vars.s)[1u][0u].packed = packed_half3(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.s)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
index 5fa3424..3c91ed3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -36,7 +39,8 @@
 
 void assign_and_preserve_padding(device tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* const dest, tint_array<half2x3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
index 4f593b7..005cd6e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -66,16 +66,13 @@
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %79 = OpTypeFunction %void %_arr_mat2v3half_uint_4
-         %98 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
+         %75 = OpTypeFunction %void %_arr_mat2v3half_uint_4
+         %94 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
           %f = OpFunction %void None %17
          %18 = OpLabel
          %23 = OpVariable %_ptr_Function__arr_mat2x3_f16_std140_uint_4 Function
@@ -111,67 +108,66 @@
          %32 = OpLabel
          %48 = OpLoad %_arr_mat2v3half_uint_4 %25 None
          %49 = OpFunctionCall %void %tint_store_and_preserve_padding %48
-         %51 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %55 = OpLoad %v3half %51 None
-         %56 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %57 = OpLoad %v3half %56 None
-         %58 = OpCompositeConstruct %mat2v3half %55 %57
-         %59 = OpBitcast %uint %int_1
-         %62 = OpCompositeConstruct %_arr_uint_uint_1 %59
-         %63 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %62 %58
-         %65 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %int_1 %int_0
-         %68 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %69 = OpLoad %v3half %68 None
-         %70 = OpVectorShuffle %v3half %69 %69 2 0 1
-               OpStore %65 %70 None
-         %71 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %int_1 %int_0
-         %72 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %73 = OpAccessChain %_ptr_Uniform_half %72 %uint_0
-         %75 = OpLoad %half %73 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_half %71 %uint_0
-               OpStore %76 %75 None
+         %51 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %54 = OpLoad %v3half %51 None
+         %55 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %56 = OpLoad %v3half %55 None
+         %57 = OpCompositeConstruct %mat2v3half %54 %56
+         %59 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %60 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %59 %57
+         %62 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %uint_1 %uint_0
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %65 = OpLoad %v3half %64 None
+         %66 = OpVectorShuffle %v3half %65 %65 2 0 1
+               OpStore %62 %66 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %uint_1 %uint_0
+         %68 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_half %68 %uint_0
+         %71 = OpLoad %half %69 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_half %67 %uint_0
+               OpStore %72 %71 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %79
+%tint_store_and_preserve_padding = OpFunction %void None %75
 %value_param = OpFunctionParameter %_arr_mat2v3half_uint_4
-         %80 = OpLabel
-         %81 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function
-               OpStore %81 %value_param
+         %76 = OpLabel
+         %77 = OpVariable %_ptr_Function__arr_mat2v3half_uint_4 Function
+               OpStore %77 %value_param
+               OpBranch %78
+         %78 = OpLabel
+               OpBranch %81
+         %81 = OpLabel
+         %83 = OpPhi %uint %uint_0 %78 %84 %80
+               OpLoopMerge %82 %80 None
+               OpBranch %79
+         %79 = OpLabel
+         %85 = OpUGreaterThanEqual %bool %83 %uint_4
+               OpSelectionMerge %86 None
+               OpBranchConditional %85 %87 %86
+         %87 = OpLabel
                OpBranch %82
-         %82 = OpLabel
-               OpBranch %85
-         %85 = OpLabel
-         %87 = OpPhi %uint %uint_0 %82 %88 %84
-               OpLoopMerge %86 %84 None
-               OpBranch %83
-         %83 = OpLabel
-         %89 = OpUGreaterThanEqual %bool %87 %uint_4
-               OpSelectionMerge %90 None
-               OpBranchConditional %89 %91 %90
-         %91 = OpLabel
-               OpBranch %86
-         %90 = OpLabel
-         %92 = OpAccessChain %_ptr_Function_mat2v3half %81 %87
-         %93 = OpLoad %mat2v3half %92 None
-         %94 = OpCompositeConstruct %_arr_uint_uint_1 %87
-         %95 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %94 %93
-               OpBranch %84
-         %84 = OpLabel
-         %88 = OpIAdd %uint %87 %uint_1
-               OpBranch %85
          %86 = OpLabel
+         %88 = OpAccessChain %_ptr_Function_mat2v3half %77 %83
+         %89 = OpLoad %mat2v3half %88 None
+         %90 = OpCompositeConstruct %_arr_uint_uint_1 %83
+         %91 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %90 %89
+               OpBranch %80
+         %80 = OpLabel
+         %84 = OpIAdd %uint %83 %uint_1
+               OpBranch %81
+         %82 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %98
+%tint_store_and_preserve_padding_0 = OpFunction %void None %94
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat2v3half
-         %99 = OpLabel
-        %100 = OpCompositeExtract %uint %target_indices 0
-        %101 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %100 %uint_0
-        %102 = OpCompositeExtract %v3half %value_param_0 0
-               OpStore %101 %102 None
-        %103 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %100 %uint_1
-        %104 = OpCompositeExtract %v3half %value_param_0 1
-               OpStore %103 %104 None
+         %95 = OpLabel
+         %96 = OpCompositeExtract %uint %target_indices 0
+         %97 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %96 %uint_0
+         %98 = OpCompositeExtract %v3half %value_param_0 0
+               OpStore %97 %98 None
+         %99 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %96 %uint_1
+        %100 = OpCompositeExtract %v3half %value_param_0 1
+               OpStore %99 %100 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.glsl
index f96baa2..ee9aac7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.glsl
@@ -51,10 +51,10 @@
     }
   }
   w = v_5;
-  w[1] = f16mat2x3(v.inner[2].col0, v.inner[2].col1);
-  w[1][0] = v.inner[0].col1.zxy;
-  w[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = w[1][0].x;
+  w[1u] = f16mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  w[1u][0u] = v.inner[0u].col1.zxy;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = w[1u][0u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 5fc291e..5359bd7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,10 +68,10 @@
   GroupMemoryBarrierWithGroupSync();
   matrix<float16_t, 2, 3> v_14[4] = v_8(0u);
   w = v_14;
-  w[int(1)] = v_4(32u);
-  w[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
-  w[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
-  s.Store<float16_t>(0u, w[int(1)][int(0)].x);
+  w[1u] = v_4(32u);
+  w[1u][0u] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
+  w[1u][0u].x = float16_t(f16tof32(u[0u].z));
+  s.Store<float16_t>(0u, w[1u][0u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
index a244cc9..7298cb0 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -24,6 +24,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4> tint_symbol;
 };
@@ -59,6 +62,7 @@
     uint v_11 = 0u;
     v_11 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_12 = v_11;
       if ((v_12 >= 4u)) {
         break;
@@ -73,14 +77,14 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_13 = (*tint_module_vars.u)[2u];
   half3 const v_14 = half3(v_13[0u].packed);
   half2x3 const v_15 = half2x3(v_14, half3(v_13[1u].packed));
-  (*tint_module_vars.w)[1][0u].packed = packed_half3(v_15[0u]);
-  (*tint_module_vars.w)[1][1u].packed = packed_half3(v_15[1u]);
-  (*tint_module_vars.w)[1][0].packed = packed_half3(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.w)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.w)[1][0].packed[0u];
+  (*tint_module_vars.w)[1u][0u].packed = packed_half3(v_15[0u]);
+  (*tint_module_vars.w)[1u][1u].packed = packed_half3(v_15[1u]);
+  (*tint_module_vars.w)[1u][0u].packed = packed_half3(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.w)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.w)[1u][0u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* u [[buffer(0)]], device half* s [[buffer(1)]], threadgroup tint_symbol_1* v_16 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.msl
index 1067651..139b064 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f16_array_element, 2>, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = tint_pack_vec3_in_composite(half2x3(half3(0.0h), half3(0.0h)));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
index 253c861..ab399ea 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 103
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,16 +70,12 @@
          %50 = OpConstantNull %_arr_mat2v3half_uint_4
 %_ptr_Function_mat2v3half = OpTypePointer Function %mat2v3half
 %_ptr_Function_mat2x3_f16_std140 = OpTypePointer Function %mat2x3_f16_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %99 = OpTypeFunction %void
+         %95 = OpTypeFunction %void
     %f_inner = OpFunction %void None %22
 %tint_local_index = OpFunctionParameter %uint
          %23 = OpLabel
@@ -138,34 +134,34 @@
          %55 = OpLabel
          %69 = OpLoad %_arr_mat2v3half_uint_4 %48 None
                OpStore %w %69 None
-         %70 = OpAccessChain %_ptr_Workgroup_mat2v3half %w %int_1
-         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %76 = OpLoad %v3half %73 None
-         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %78 = OpLoad %v3half %77 None
-         %79 = OpCompositeConstruct %mat2v3half %76 %78
-               OpStore %70 %79 None
-         %80 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %int_0
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %84 = OpLoad %v3half %83 None
-         %85 = OpVectorShuffle %v3half %84 %84 2 0 1
-               OpStore %80 %85 None
-         %86 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %88 = OpAccessChain %_ptr_Uniform_half %87 %uint_0
-         %90 = OpLoad %half %88 None
-         %91 = OpAccessChain %_ptr_Workgroup_half %86 %uint_0
-               OpStore %91 %90 None
-         %93 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %int_0
-         %94 = OpAccessChain %_ptr_Workgroup_half %93 %uint_0
-         %95 = OpLoad %half %94 None
-         %96 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %96 %95 None
+         %70 = OpAccessChain %_ptr_Workgroup_mat2v3half %w %uint_1
+         %71 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %73 = OpLoad %v3half %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %75 = OpLoad %v3half %74 None
+         %76 = OpCompositeConstruct %mat2v3half %73 %75
+               OpStore %70 %76 None
+         %77 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_0
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %80 = OpLoad %v3half %79 None
+         %81 = OpVectorShuffle %v3half %80 %80 2 0 1
+               OpStore %77 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %84 = OpAccessChain %_ptr_Uniform_half %83 %uint_0
+         %86 = OpLoad %half %84 None
+         %87 = OpAccessChain %_ptr_Workgroup_half %82 %uint_0
+               OpStore %87 %86 None
+         %89 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_0
+         %90 = OpAccessChain %_ptr_Workgroup_half %89 %uint_0
+         %91 = OpLoad %half %90 None
+         %92 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %99
-        %100 = OpLabel
-        %101 = OpLoad %uint %f_local_invocation_index_Input None
-        %102 = OpFunctionCall %void %f_inner %101
+          %f = OpFunction %void None %95
+         %96 = OpLabel
+         %97 = OpLoad %uint %f_local_invocation_index_Input None
+         %98 = OpFunctionCall %void %f_inner %97
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 62bcef4..86e6413 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -31,10 +31,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x3 l_a[4] = a_load(0u);
-  float2x3 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float2x3 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_2 / 4].xyz);
-  const uint scalar_offset_3 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 62bcef4..86e6413 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -31,10 +31,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x3 l_a[4] = a_load(0u);
-  float2x3 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float2x3 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_2 / 4].xyz);
-  const uint scalar_offset_3 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index f8ed93f..af5113d 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -23,9 +23,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   mat2x3 v_3 = mat2x3(v.inner[v_2].col0, v.inner[v_2].col1);
-  vec3 v_4 = v_3[i()];
+  vec3 v_4 = v_3[min(uint(i()), 1u)];
   mat2x3_f32_std140 v_5[4] = v.inner;
   mat2x3 v_6[4] = mat2x3[4](mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)));
   {
@@ -46,5 +46,5 @@
   mat2x3 l_a[4] = v_6;
   mat2x3 l_a_i = v_3;
   vec3 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 325b27c..92828e7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (32u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (32u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 1u)));
   float2x3 l_a[4] = v_1(0u);
   float2x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 325b27c..92828e7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (32u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (32u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 1u)));
   float2x3 l_a[4] = v_1(0u);
   float2x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index ff6c9b7..7f543e3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -48,12 +48,12 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<float2x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 2> const v_11 = (*p_a_i);
   float3 const v_12 = float3(v_11[0u].packed);
   float2x3 const l_a_i = float2x3(v_12, float3(v_11[1u].packed));
   float3 const l_a_i_i = float3((*p_a_i_i));
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 93df986..2627ca7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -42,9 +42,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 1u);
   tint_array<float2x3, 4> const l_a = tint_unpack_vec3_in_composite_1(*(tint_symbol_2));
   float2x3 const l_a_i = tint_unpack_vec3_in_composite((*(tint_symbol_2))[p_a_i_save]);
   float3 const l_a_i_i = float3((*(tint_symbol_2))[p_a_i_save][p_a_i_i_save].elements);
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 23cb998..95f2d6e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -56,6 +57,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat2x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
 %mat2v3float = OpTypeMatrix %v3float 2
@@ -64,7 +66,7 @@
 %_ptr_Function__arr_mat2x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat2x3_f32_std140_uint_4
 %_arr_mat2v3float_uint_4 = OpTypeArray %mat2v3float %uint_4
 %_ptr_Function__arr_mat2v3float_uint_4 = OpTypePointer Function %_arr_mat2v3float_uint_4
-         %52 = OpConstantNull %_arr_mat2v3float_uint_4
+         %58 = OpConstantNull %_arr_mat2v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -78,57 +80,61 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %40 = OpVariable %_ptr_Function_mat2v3float Function
-         %47 = OpVariable %_ptr_Function__arr_mat2x3_f32_std140_uint_4 Function
-         %49 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function %52
+         %44 = OpVariable %_ptr_Function_mat2v3float Function
+         %53 = OpVariable %_ptr_Function__arr_mat2x3_f32_std140_uint_4 Function
+         %55 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function %58
          %28 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f32_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_0
-         %34 = OpLoad %v3float %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_1
-         %37 = OpLoad %v3float %35 None
-      %l_a_i = OpCompositeConstruct %mat2v3float %34 %37
-               OpStore %40 %l_a_i
-         %42 = OpFunctionCall %int %i
-         %43 = OpAccessChain %_ptr_Function_v3float %40 %42
-    %l_a_i_i = OpLoad %v3float %43 None
-         %46 = OpLoad %_arr_mat2x3_f32_std140_uint_4 %28 None
-               OpStore %47 %46
-               OpBranch %53
-         %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
-               OpBranch %54
-         %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_0
+         %38 = OpLoad %v3float %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_1
+         %41 = OpLoad %v3float %39 None
+      %l_a_i = OpCompositeConstruct %mat2v3float %38 %41
+               OpStore %44 %l_a_i
+         %46 = OpFunctionCall %int %i
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %34 UMin %47 %uint_1
+         %49 = OpAccessChain %_ptr_Function_v3float %44 %48
+    %l_a_i_i = OpLoad %v3float %49 None
+         %52 = OpLoad %_arr_mat2x3_f32_std140_uint_4 %28 None
+               OpStore %53 %52
+               OpBranch %59
+         %59 = OpLabel
+               OpBranch %62
          %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_mat2v3float %49 %58
-         %65 = OpAccessChain %_ptr_Function_mat2x3_f32_std140 %47 %58
-         %67 = OpLoad %mat2x3_f32_std140 %65 None
-         %68 = OpCompositeExtract %v3float %67 0
-         %69 = OpCompositeExtract %v3float %67 1
-         %70 = OpCompositeConstruct %mat2v3float %68 %69
-               OpStore %64 %70 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_mat2v3float_uint_4 %49 None
-         %72 = OpCompositeExtract %float %l_a_i_i 0
-         %73 = OpCompositeExtract %float %l_a 0 0 0
-         %74 = OpFAdd %float %72 %73
-         %75 = OpCompositeExtract %float %l_a_i 0 0
-         %76 = OpFAdd %float %74 %75
-         %77 = OpCompositeExtract %float %l_a_i_i 0
-         %78 = OpFAdd %float %76 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %79 %78 None
+         %64 = OpPhi %uint %uint_0 %59 %65 %61
+               OpLoopMerge %63 %61 None
+               OpBranch %60
+         %60 = OpLabel
+         %66 = OpUGreaterThanEqual %bool %64 %uint_4
+               OpSelectionMerge %68 None
+               OpBranchConditional %66 %69 %68
+         %69 = OpLabel
+               OpBranch %63
+         %68 = OpLabel
+         %70 = OpAccessChain %_ptr_Function_mat2v3float %55 %64
+         %71 = OpAccessChain %_ptr_Function_mat2x3_f32_std140 %53 %64
+         %73 = OpLoad %mat2x3_f32_std140 %71 None
+         %74 = OpCompositeExtract %v3float %73 0
+         %75 = OpCompositeExtract %v3float %73 1
+         %76 = OpCompositeConstruct %mat2v3float %74 %75
+               OpStore %70 %76 None
+               OpBranch %61
+         %61 = OpLabel
+         %65 = OpIAdd %uint %64 %uint_1
+               OpBranch %62
+         %63 = OpLabel
+        %l_a = OpLoad %_arr_mat2v3float_uint_4 %55 None
+         %78 = OpCompositeExtract %float %l_a_i_i 0
+         %79 = OpCompositeExtract %float %l_a 0 0 0
+         %80 = OpFAdd %float %78 %79
+         %81 = OpCompositeExtract %float %l_a_i 0 0
+         %82 = OpFAdd %float %80 %81
+         %83 = OpCompositeExtract %float %l_a_i_i 0
+         %84 = OpFAdd %float %82 %83
+         %85 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %85 %84 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 24543f1..987cd4c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -18,7 +18,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2x3 v_2 = mat2x3(v.inner[2].col0, v.inner[2].col1);
+  mat2x3 v_2 = mat2x3(v.inner[2u].col0, v.inner[2u].col1);
   mat2x3_f32_std140 v_3[4] = v.inner;
   mat2x3 v_4[4] = mat2x3[4](mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)), mat2x3(vec3(0.0f), vec3(0.0f)));
   {
@@ -38,6 +38,6 @@
   }
   mat2x3 l_a[4] = v_4;
   mat2x3 l_a_i = v_2;
-  vec3 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  vec3 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index a11fbdd..b3d8a3f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float2x3 l_a[4] = v_1(0u);
   float2x3 l_a_i = v(64u);
   float3 l_a_i_i = asfloat(a[5u].xyz);
-  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index a11fbdd..b3d8a3f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float2x3 l_a[4] = v_1(0u);
   float2x3 l_a_i = v(64u);
   float3 l_a_i_i = asfloat(a[5u].xyz);
-  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index f46300f..d107964 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -41,12 +41,12 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_2 = (&(*p_a)[2]);
-  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_2 = (&(*p_a)[2u]);
+  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1u].packed);
   tint_array<float2x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 2> const v_11 = (*p_a_2);
   float3 const v_12 = float3(v_11[0u].packed);
   float2x3 const l_a_i = float2x3(v_12, float3(v_11[1u].packed));
   float3 const l_a_i_i = float3((*p_a_2_1));
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index d6f2984..fdf163a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -49,66 +49,65 @@
 %_ptr_Uniform__arr_mat2x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %mat2v3float = OpTypeMatrix %v3float 2
 %_ptr_Function__arr_mat2x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat2x3_f32_std140_uint_4
 %_arr_mat2v3float_uint_4 = OpTypeArray %mat2v3float %uint_4
 %_ptr_Function__arr_mat2v3float_uint_4 = OpTypePointer Function %_arr_mat2v3float_uint_4
-         %37 = OpConstantNull %_arr_mat2v3float_uint_4
+         %36 = OpConstantNull %_arr_mat2v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %32 = OpVariable %_ptr_Function__arr_mat2x3_f32_std140_uint_4 Function
-         %34 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function %37
+         %31 = OpVariable %_ptr_Function__arr_mat2x3_f32_std140_uint_4 Function
+         %33 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function %36
          %17 = OpAccessChain %_ptr_Uniform__arr_mat2x3_f32_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_0
-         %24 = OpLoad %v3float %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_1
-         %27 = OpLoad %v3float %25 None
-      %l_a_i = OpCompositeConstruct %mat2v3float %24 %27
+         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_0
+         %23 = OpLoad %v3float %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_1
+         %26 = OpLoad %v3float %24 None
+      %l_a_i = OpCompositeConstruct %mat2v3float %23 %26
     %l_a_i_i = OpCompositeExtract %v3float %l_a_i 1
-         %31 = OpLoad %_arr_mat2x3_f32_std140_uint_4 %17 None
-               OpStore %32 %31
-               OpBranch %38
-         %38 = OpLabel
-               OpBranch %41
-         %41 = OpLabel
-         %43 = OpPhi %uint %uint_0 %38 %44 %40
-               OpLoopMerge %42 %40 None
-               OpBranch %39
-         %39 = OpLabel
-         %45 = OpUGreaterThanEqual %bool %43 %uint_4
-               OpSelectionMerge %47 None
-               OpBranchConditional %45 %48 %47
-         %48 = OpLabel
-               OpBranch %42
-         %47 = OpLabel
-         %49 = OpAccessChain %_ptr_Function_mat2v3float %34 %43
-         %51 = OpAccessChain %_ptr_Function_mat2x3_f32_std140 %32 %43
-         %53 = OpLoad %mat2x3_f32_std140 %51 None
-         %54 = OpCompositeExtract %v3float %53 0
-         %55 = OpCompositeExtract %v3float %53 1
-         %56 = OpCompositeConstruct %mat2v3float %54 %55
-               OpStore %49 %56 None
+         %30 = OpLoad %_arr_mat2x3_f32_std140_uint_4 %17 None
+               OpStore %31 %30
+               OpBranch %37
+         %37 = OpLabel
                OpBranch %40
          %40 = OpLabel
-         %44 = OpIAdd %uint %43 %uint_1
+         %42 = OpPhi %uint %uint_0 %37 %43 %39
+               OpLoopMerge %41 %39 None
+               OpBranch %38
+         %38 = OpLabel
+         %44 = OpUGreaterThanEqual %bool %42 %uint_4
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %47 %46
+         %47 = OpLabel
                OpBranch %41
-         %42 = OpLabel
-        %l_a = OpLoad %_arr_mat2v3float_uint_4 %34 None
-         %58 = OpCompositeExtract %float %l_a_i_i 0
-         %59 = OpCompositeExtract %float %l_a 0 0 0
-         %60 = OpFAdd %float %58 %59
-         %61 = OpCompositeExtract %float %l_a_i 0 0
-         %62 = OpFAdd %float %60 %61
-         %63 = OpCompositeExtract %float %l_a_i_i 0
-         %64 = OpFAdd %float %62 %63
-         %65 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %65 %64 None
+         %46 = OpLabel
+         %48 = OpAccessChain %_ptr_Function_mat2v3float %33 %42
+         %50 = OpAccessChain %_ptr_Function_mat2x3_f32_std140 %31 %42
+         %52 = OpLoad %mat2x3_f32_std140 %50 None
+         %53 = OpCompositeExtract %v3float %52 0
+         %54 = OpCompositeExtract %v3float %52 1
+         %55 = OpCompositeConstruct %mat2v3float %53 %54
+               OpStore %48 %55 None
+               OpBranch %39
+         %39 = OpLabel
+         %43 = OpIAdd %uint %42 %uint_1
+               OpBranch %40
+         %41 = OpLabel
+        %l_a = OpLoad %_arr_mat2v3float_uint_4 %33 None
+         %57 = OpCompositeExtract %float %l_a_i_i 0
+         %58 = OpCompositeExtract %float %l_a 0 0 0
+         %59 = OpFAdd %float %57 %58
+         %60 = OpCompositeExtract %float %l_a_i 0 0
+         %61 = OpFAdd %float %59 %60
+         %62 = OpCompositeExtract %float %l_a_i_i 0
+         %63 = OpFAdd %float %61 %62
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.glsl
index 8ccd54f..1124753 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.glsl
@@ -18,9 +18,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3x2 t = transpose(mat2x3(v.inner[2].col0, v.inner[2].col1));
-  float l = length(v.inner[0].col1.zxy);
-  float a = abs(v.inner[0].col1.zxy[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat3x2 t = transpose(mat2x3(v.inner[2u].col0, v.inner[2u].col1));
+  float l = length(v.inner[0u].col1.zxy);
+  float a = abs(v.inner[0u].col1.zxy[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 01302e0..8a67aff 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float3x2 t = transpose(v(64u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 01302e0..8a67aff 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float3x2 t = transpose(v(64u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
index f0a670c..dbd9545 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -25,11 +25,11 @@
 
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u)[2u];
   float3 const v_1 = float3(v[0u].packed);
   float3x2 const t = transpose(float2x3(v_1, float3(v[1u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0][1].packed).zxy[0u]);
-  float const v_2 = (t[0][0u] + float(l));
+  float const l = length(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u][1u].packed).zxy[0u]);
+  float const v_2 = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.spvasm
index 640dc2a..46eac3d 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
-         %36 = OpExtInstImport "GLSL.std.450"
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -48,35 +48,33 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %mat2v3float = OpTypeMatrix %v3float 2
     %v2float = OpTypeVector %float 2
 %mat3v2float = OpTypeMatrix %v2float 3
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v3float %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v3float %23 None
-         %27 = OpCompositeConstruct %mat2v3float %22 %25
-          %t = OpTranspose %mat3v2float %27
-         %31 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %33 = OpLoad %v3float %31 None
-         %34 = OpVectorShuffle %v3float %33 %33 2 0 1
-          %l = OpExtInst %float %36 Length %34
-         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %38 = OpLoad %v3float %37 None
-         %39 = OpVectorShuffle %v3float %38 %38 2 0 1
-         %40 = OpCompositeExtract %float %39 0
-          %a = OpExtInst %float %36 FAbs %40
-         %42 = OpCompositeExtract %float %t 0 0
-         %43 = OpFAdd %float %42 %l
-         %44 = OpFAdd %float %43 %a
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %45 %44 None
+         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v3float %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v3float %22 None
+         %26 = OpCompositeConstruct %mat2v3float %21 %24
+          %t = OpTranspose %mat3v2float %26
+         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %31 = OpLoad %v3float %30 None
+         %32 = OpVectorShuffle %v3float %31 %31 2 0 1
+          %l = OpExtInst %float %34 Length %32
+         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v3float %35 None
+         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
+         %38 = OpCompositeExtract %float %37 0
+          %a = OpExtInst %float %34 FAbs %38
+         %40 = OpCompositeExtract %float %t 0 0
+         %41 = OpFAdd %float %40 %l
+         %42 = OpFAdd %float %41 %a
+         %43 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.glsl
index 6a5df66..676eba8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.glsl
@@ -17,10 +17,10 @@
   float inner;
 } v_2;
 float a(mat2x3 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat2x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec3 v) {
   return v[0u];
@@ -48,7 +48,7 @@
     }
   }
   float v_7 = a(v_4);
-  float v_8 = (v_7 + b(mat2x3(v_1.inner[1].col0, v_1.inner[1].col1)));
-  float v_9 = (v_8 + c(v_1.inner[1].col0.zxy));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.zxy[0u]));
+  float v_8 = (v_7 + b(mat2x3(v_1.inner[1u].col0, v_1.inner[1u].col1)));
+  float v_9 = (v_8 + c(v_1.inner[1u].col0.zxy));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index 872ee57..8c0847e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index 872ee57..8c0847e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.msl
index 0dacc11..a76cfd8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.ir.msl
@@ -24,11 +24,11 @@
 };
 
 float a(tint_array<float2x3, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float2x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float3 v) {
@@ -57,9 +57,9 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_12 = a(tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[1];
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[1u];
   float3 const v_14 = float3(v_13[0u].packed);
   float const v_15 = (v_12 + b(float2x3(v_14, float3(v_13[1u].packed))));
-  float const v_16 = (v_15 + c(float3((*tint_module_vars.u)[1][0].packed).zxy));
-  (*tint_module_vars.s) = (v_16 + d(float3((*tint_module_vars.u)[1][0].packed).zxy[0u]));
+  float const v_16 = (v_15 + c(float3((*tint_module_vars.u)[1u][0u].packed).zxy));
+  (*tint_module_vars.s) = (v_16 + d(float3((*tint_module_vars.u)[1u][0u].packed).zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.spvasm
index 04127df..8f5f0b8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 92
+; Bound: 90
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -67,8 +67,6 @@
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %17
         %a_0 = OpFunctionParameter %_arr_mat2v3float_uint_4
@@ -128,25 +126,25 @@
          %51 = OpLabel
          %67 = OpLoad %_arr_mat2v3float_uint_4 %44 None
          %68 = OpFunctionCall %float %a %67
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %73 = OpLoad %v3float %69 None
-         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_1
-         %75 = OpLoad %v3float %74 None
-         %76 = OpCompositeConstruct %mat2v3float %73 %75
-         %77 = OpFunctionCall %float %b %76
-         %78 = OpFAdd %float %68 %77
-         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %80 = OpLoad %v3float %79 None
-         %81 = OpVectorShuffle %v3float %80 %80 2 0 1
-         %82 = OpFunctionCall %float %c %81
-         %83 = OpFAdd %float %78 %82
-         %84 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %85 = OpLoad %v3float %84 None
-         %86 = OpVectorShuffle %v3float %85 %85 2 0 1
-         %87 = OpCompositeExtract %float %86 0
-         %88 = OpFunctionCall %float %d %87
-         %89 = OpFAdd %float %83 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %90 %89 None
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %71 = OpLoad %v3float %69 None
+         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_1
+         %73 = OpLoad %v3float %72 None
+         %74 = OpCompositeConstruct %mat2v3float %71 %73
+         %75 = OpFunctionCall %float %b %74
+         %76 = OpFAdd %float %68 %75
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %78 = OpLoad %v3float %77 None
+         %79 = OpVectorShuffle %v3float %78 %78 2 0 1
+         %80 = OpFunctionCall %float %c %79
+         %81 = OpFAdd %float %76 %80
+         %82 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %83 = OpLoad %v3float %82 None
+         %84 = OpVectorShuffle %v3float %83 %83 2 0 1
+         %85 = OpCompositeExtract %float %84 0
+         %86 = OpFunctionCall %float %d %85
+         %87 = OpFAdd %float %81 %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %88 %87 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.glsl
index 45b8eac..952ea77 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.glsl
@@ -37,8 +37,8 @@
     }
   }
   p = v_3;
-  p[1] = mat2x3(v.inner[2].col0, v.inner[2].col1);
-  p[1][0] = v.inner[0].col1.zxy;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  p[1u][0u] = v.inner[0u].col1.zxy;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 318e079..b94b087 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float2x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 318e079..b94b087 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float2x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.msl
index 6916b0f..df78852 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.ir.msl
@@ -43,10 +43,10 @@
   thread tint_array<float2x3, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_11 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_11 = (*tint_module_vars.u)[2u];
   float3 const v_12 = float3(v_11[0u].packed);
-  (*tint_module_vars.p)[1] = float2x3(v_12, float3(v_11[1u].packed));
-  (*tint_module_vars.p)[1][0] = float3((*tint_module_vars.u)[0][1].packed).zxy;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = float2x3(v_12, float3(v_11[1u].packed));
+  (*tint_module_vars.p)[1u][0u] = float3((*tint_module_vars.u)[0u][1u].packed).zxy;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.spvasm
index f7b894f..c552ba3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 80
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -58,12 +58,9 @@
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat2v3float = OpTypePointer Private %mat2v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -102,28 +99,28 @@
          %34 = OpLabel
          %50 = OpLoad %_arr_mat2v3float_uint_4 %28 None
                OpStore %p %50 None
-         %51 = OpAccessChain %_ptr_Private_mat2v3float %p %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v3float %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v3float %59 None
-         %61 = OpCompositeConstruct %mat2v3float %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v3float %65 None
-         %67 = OpVectorShuffle %v3float %66 %66 2 0 1
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_float %69 %uint_0
-         %72 = OpLoad %float %70 None
-         %73 = OpAccessChain %_ptr_Private_float %68 %uint_0
-               OpStore %73 %72 None
-         %75 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Private_float %75 %uint_0
-         %77 = OpLoad %float %76 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %78 %77 None
+         %51 = OpAccessChain %_ptr_Private_mat2v3float %p %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v3float %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v3float %57 None
+         %59 = OpCompositeConstruct %mat2v3float %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v3float %62 None
+         %64 = OpVectorShuffle %v3float %63 %63 2 0 1
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_float %66 %uint_0
+         %69 = OpLoad %float %67 None
+         %70 = OpAccessChain %_ptr_Private_float %65 %uint_0
+               OpStore %70 %69 None
+         %72 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Private_float %72 %uint_0
+         %74 = OpLoad %float %73 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %75 %74 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
index 201ddb1..d739ed8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -57,8 +57,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  mat2x3 v_8 = mat2x3(v.inner[2].col0, v.inner[2].col1);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[1][0] = v.inner[0].col1.zxy;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  mat2x3 v_8 = mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[1u][0u] = v.inner[0u].col1.zxy;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.ir.msl
index 9576b4b..a0ff344 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* u;
   device tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* s;
@@ -33,6 +36,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -64,9 +68,9 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* u [[buffer(0)]], device tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[2u];
   float3 const v_14 = float3(v_13[0u].packed);
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), float2x3(v_14, float3(v_13[1u].packed)));
-  (*tint_module_vars.s)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.s)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), float2x3(v_14, float3(v_13[1u].packed)));
+  (*tint_module_vars.s)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.s)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
index 48872f5..a88747e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -36,7 +39,8 @@
 
 void assign_and_preserve_padding(device tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* const dest, tint_array<float2x3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
index 2bbc761..b071e7e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -63,16 +63,13 @@
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %79 = OpTypeFunction %void %_arr_mat2v3float_uint_4
-         %98 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+         %75 = OpTypeFunction %void %_arr_mat2v3float_uint_4
+         %94 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %23 = OpVariable %_ptr_Function__arr_mat2x3_f32_std140_uint_4 Function
@@ -108,67 +105,66 @@
          %32 = OpLabel
          %48 = OpLoad %_arr_mat2v3float_uint_4 %25 None
          %49 = OpFunctionCall %void %tint_store_and_preserve_padding %48
-         %51 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %55 = OpLoad %v3float %51 None
-         %56 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %57 = OpLoad %v3float %56 None
-         %58 = OpCompositeConstruct %mat2v3float %55 %57
-         %59 = OpBitcast %uint %int_1
-         %62 = OpCompositeConstruct %_arr_uint_uint_1 %59
-         %63 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %62 %58
-         %65 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %68 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %69 = OpLoad %v3float %68 None
-         %70 = OpVectorShuffle %v3float %69 %69 2 0 1
-               OpStore %65 %70 None
-         %71 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %73 = OpAccessChain %_ptr_Uniform_float %72 %uint_0
-         %75 = OpLoad %float %73 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_float %71 %uint_0
-               OpStore %76 %75 None
+         %51 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %54 = OpLoad %v3float %51 None
+         %55 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %56 = OpLoad %v3float %55 None
+         %57 = OpCompositeConstruct %mat2v3float %54 %56
+         %59 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %60 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %59 %57
+         %62 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %65 = OpLoad %v3float %64 None
+         %66 = OpVectorShuffle %v3float %65 %65 2 0 1
+               OpStore %62 %66 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %68 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_float %68 %uint_0
+         %71 = OpLoad %float %69 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_float %67 %uint_0
+               OpStore %72 %71 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %79
+%tint_store_and_preserve_padding = OpFunction %void None %75
 %value_param = OpFunctionParameter %_arr_mat2v3float_uint_4
-         %80 = OpLabel
-         %81 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function
-               OpStore %81 %value_param
+         %76 = OpLabel
+         %77 = OpVariable %_ptr_Function__arr_mat2v3float_uint_4 Function
+               OpStore %77 %value_param
+               OpBranch %78
+         %78 = OpLabel
+               OpBranch %81
+         %81 = OpLabel
+         %83 = OpPhi %uint %uint_0 %78 %84 %80
+               OpLoopMerge %82 %80 None
+               OpBranch %79
+         %79 = OpLabel
+         %85 = OpUGreaterThanEqual %bool %83 %uint_4
+               OpSelectionMerge %86 None
+               OpBranchConditional %85 %87 %86
+         %87 = OpLabel
                OpBranch %82
-         %82 = OpLabel
-               OpBranch %85
-         %85 = OpLabel
-         %87 = OpPhi %uint %uint_0 %82 %88 %84
-               OpLoopMerge %86 %84 None
-               OpBranch %83
-         %83 = OpLabel
-         %89 = OpUGreaterThanEqual %bool %87 %uint_4
-               OpSelectionMerge %90 None
-               OpBranchConditional %89 %91 %90
-         %91 = OpLabel
-               OpBranch %86
-         %90 = OpLabel
-         %92 = OpAccessChain %_ptr_Function_mat2v3float %81 %87
-         %93 = OpLoad %mat2v3float %92 None
-         %94 = OpCompositeConstruct %_arr_uint_uint_1 %87
-         %95 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %94 %93
-               OpBranch %84
-         %84 = OpLabel
-         %88 = OpIAdd %uint %87 %uint_1
-               OpBranch %85
          %86 = OpLabel
+         %88 = OpAccessChain %_ptr_Function_mat2v3float %77 %83
+         %89 = OpLoad %mat2v3float %88 None
+         %90 = OpCompositeConstruct %_arr_uint_uint_1 %83
+         %91 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %90 %89
+               OpBranch %80
+         %80 = OpLabel
+         %84 = OpIAdd %uint %83 %uint_1
+               OpBranch %81
+         %82 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %98
+%tint_store_and_preserve_padding_0 = OpFunction %void None %94
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat2v3float
-         %99 = OpLabel
-        %100 = OpCompositeExtract %uint %target_indices 0
-        %101 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %100 %uint_0
-        %102 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %101 %102 None
-        %103 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %100 %uint_1
-        %104 = OpCompositeExtract %v3float %value_param_0 1
-               OpStore %103 %104 None
+         %95 = OpLabel
+         %96 = OpCompositeExtract %uint %target_indices 0
+         %97 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %96 %uint_0
+         %98 = OpCompositeExtract %v3float %value_param_0 0
+               OpStore %97 %98 None
+         %99 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %96 %uint_1
+        %100 = OpCompositeExtract %v3float %value_param_0 1
+               OpStore %99 %100 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.glsl
index e68630d..dabd8b0 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.glsl
@@ -48,9 +48,9 @@
     }
   }
   w = v_4;
-  w[1] = mat2x3(v.inner[2].col0, v.inner[2].col1);
-  w[1][0] = v.inner[0].col1.zxy;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = mat2x3(v.inner[2u].col0, v.inner[2u].col1);
+  w[1u][0u] = v.inner[0u].col1.zxy;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 4292b8b..8a4eb85 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 4292b8b..8a4eb85 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
index d75e356..8b081481 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -23,6 +23,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4> tint_symbol;
 };
@@ -58,6 +61,7 @@
     uint v_11 = 0u;
     v_11 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_12 = v_11;
       if ((v_12 >= 4u)) {
         break;
@@ -72,13 +76,13 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_13 = (*tint_module_vars.u)[2u];
   float3 const v_14 = float3(v_13[0u].packed);
   float2x3 const v_15 = float2x3(v_14, float3(v_13[1u].packed));
-  (*tint_module_vars.w)[1][0u].packed = packed_float3(v_15[0u]);
-  (*tint_module_vars.w)[1][1u].packed = packed_float3(v_15[1u]);
-  (*tint_module_vars.w)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.w)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(v_15[0u]);
+  (*tint_module_vars.w)[1u][1u].packed = packed_float3(v_15[1u]);
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.w)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_16 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.msl
index 3895ef9..1da30d9 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 2>, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = tint_pack_vec3_in_composite(float2x3(float3(0.0f), float3(0.0f)));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
index 8232879..86a591d 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 95
+; Bound: 91
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -57,15 +57,11 @@
          %47 = OpConstantNull %_arr_mat2v3float_uint_4
 %_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
 %_ptr_Function_mat2x3_f32_std140 = OpTypePointer Function %mat2x3_f32_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %91 = OpTypeFunction %void
+         %87 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -124,29 +120,29 @@
          %52 = OpLabel
          %66 = OpLoad %_arr_mat2v3float_uint_4 %45 None
                OpStore %w %66 None
-         %67 = OpAccessChain %_ptr_Workgroup_mat2v3float %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %73 = OpLoad %v3float %70 None
-         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %75 = OpLoad %v3float %74 None
-         %76 = OpCompositeConstruct %mat2v3float %73 %75
-               OpStore %67 %76 None
-         %77 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %81 = OpLoad %v3float %80 None
-         %82 = OpVectorShuffle %v3float %81 %81 2 0 1
-               OpStore %77 %82 None
-         %83 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %85 = OpAccessChain %_ptr_Uniform_float %84 %uint_0
-         %87 = OpLoad %float %85 None
-         %88 = OpAccessChain %_ptr_Workgroup_float %83 %uint_0
-               OpStore %88 %87 None
+         %67 = OpAccessChain %_ptr_Workgroup_mat2v3float %w %uint_1
+         %68 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %70 = OpLoad %v3float %68 None
+         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %72 = OpLoad %v3float %71 None
+         %73 = OpCompositeConstruct %mat2v3float %70 %72
+               OpStore %67 %73 None
+         %74 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %77 = OpLoad %v3float %76 None
+         %78 = OpVectorShuffle %v3float %77 %77 2 0 1
+               OpStore %74 %78 None
+         %79 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %81 = OpAccessChain %_ptr_Uniform_float %80 %uint_0
+         %83 = OpLoad %float %81 None
+         %84 = OpAccessChain %_ptr_Workgroup_float %79 %uint_0
+               OpStore %84 %83 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %87
+         %88 = OpLabel
+         %89 = OpLoad %uint %f_local_invocation_index_Input None
+         %90 = OpFunctionCall %void %f_inner %89
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 0e3d604..fe0b6f5 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -39,14 +39,14 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   matrix<float16_t, 2, 4> l_a[4] = a_load(0u);
-  matrix<float16_t, 2, 4> l_a_i = a_load_1((16u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  matrix<float16_t, 2, 4> l_a_i = a_load_1((16u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u)))) / 4;
   uint4 ubo_load_5 = a[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
   vector<float16_t, 2> ubo_load_4_yw = vector<float16_t, 2>(f16tof32(ubo_load_4 >> 16));
   vector<float16_t, 4> l_a_i_i = vector<float16_t, 4>(ubo_load_4_xz[0], ubo_load_4_yw[0], ubo_load_4_xz[1], ubo_load_4_yw[1]);
-  const uint scalar_offset_bytes = (((16u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save))));
+  const uint scalar_offset_bytes = (((16u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 1u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   s.Store<float16_t>(0u, (((float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF))) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x));
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 2eae516..6efa1da 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -22,9 +22,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   f16mat2x4 v_3 = f16mat2x4(v.inner[v_2].col0, v.inner[v_2].col1);
-  f16vec4 v_4 = v_3[i()];
+  f16vec4 v_4 = v_3[min(uint(i()), 1u)];
   mat2x4_f16_std140 v_5[4] = v.inner;
   f16mat2x4 v_6[4] = f16mat2x4[4](f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)));
   {
@@ -45,5 +45,5 @@
   f16mat2x4 l_a[4] = v_6;
   f16mat2x4 l_a_i = v_3;
   f16vec4 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index eef9514..7e0aa19 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -52,13 +52,13 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (16u * uint(i()));
-  uint v_13 = (8u * uint(i()));
+  uint v_12 = (16u * uint(min(uint(i()), 3u)));
+  uint v_13 = (8u * uint(min(uint(i()), 1u)));
   matrix<float16_t, 2, 4> l_a[4] = v_8(0u);
   matrix<float16_t, 2, 4> l_a_i = v_4(v_12);
   uint4 v_14 = a[((v_12 + v_13) / 16u)];
   vector<float16_t, 4> l_a_i_i = tint_bitcast_to_f16(((((((v_12 + v_13) % 16u) / 4u) == 2u)) ? (v_14.zw) : (v_14.xy)));
   uint v_15 = a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)];
-  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_15 >> (((((v_12 + v_13) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_15 >> (((((v_12 + v_13) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 1bf7983..8b489a4 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<half2x4, 4>* const p_a = tint_module_vars.a;
-  const constant half2x4* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant half4* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant half2x4* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant half4* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<half2x4, 4> const l_a = (*p_a);
   half2x4 const l_a_i = (*p_a_i);
   half4 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index dce6b75..c3f505e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 1u);
   tint_array<half2x4, 4> const l_a = *(tint_symbol_2);
   half2x4 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   half4 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index d88a11d..804dcc9 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -59,6 +60,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat2x4_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x4_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
  %mat2v4half = OpTypeMatrix %v4half 2
@@ -67,7 +69,7 @@
 %_ptr_Function__arr_mat2x4_f16_std140_uint_4 = OpTypePointer Function %_arr_mat2x4_f16_std140_uint_4
 %_arr_mat2v4half_uint_4 = OpTypeArray %mat2v4half %uint_4
 %_ptr_Function__arr_mat2v4half_uint_4 = OpTypePointer Function %_arr_mat2v4half_uint_4
-         %52 = OpConstantNull %_arr_mat2v4half_uint_4
+         %58 = OpConstantNull %_arr_mat2v4half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2x4_f16_std140 = OpTypePointer Function %mat2x4_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -81,57 +83,61 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %40 = OpVariable %_ptr_Function_mat2v4half Function
-         %47 = OpVariable %_ptr_Function__arr_mat2x4_f16_std140_uint_4 Function
-         %49 = OpVariable %_ptr_Function__arr_mat2v4half_uint_4 Function %52
+         %44 = OpVariable %_ptr_Function_mat2v4half Function
+         %53 = OpVariable %_ptr_Function__arr_mat2x4_f16_std140_uint_4 Function
+         %55 = OpVariable %_ptr_Function__arr_mat2v4half_uint_4 Function %58
          %28 = OpAccessChain %_ptr_Uniform__arr_mat2x4_f16_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_0
-         %34 = OpLoad %v4half %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_1
-         %37 = OpLoad %v4half %35 None
-      %l_a_i = OpCompositeConstruct %mat2v4half %34 %37
-               OpStore %40 %l_a_i
-         %42 = OpFunctionCall %int %i
-         %43 = OpAccessChain %_ptr_Function_v4half %40 %42
-    %l_a_i_i = OpLoad %v4half %43 None
-         %46 = OpLoad %_arr_mat2x4_f16_std140_uint_4 %28 None
-               OpStore %47 %46
-               OpBranch %53
-         %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
-               OpBranch %54
-         %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_0
+         %38 = OpLoad %v4half %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_1
+         %41 = OpLoad %v4half %39 None
+      %l_a_i = OpCompositeConstruct %mat2v4half %38 %41
+               OpStore %44 %l_a_i
+         %46 = OpFunctionCall %int %i
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %34 UMin %47 %uint_1
+         %49 = OpAccessChain %_ptr_Function_v4half %44 %48
+    %l_a_i_i = OpLoad %v4half %49 None
+         %52 = OpLoad %_arr_mat2x4_f16_std140_uint_4 %28 None
+               OpStore %53 %52
+               OpBranch %59
+         %59 = OpLabel
+               OpBranch %62
          %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_mat2v4half %49 %58
-         %65 = OpAccessChain %_ptr_Function_mat2x4_f16_std140 %47 %58
-         %67 = OpLoad %mat2x4_f16_std140 %65 None
-         %68 = OpCompositeExtract %v4half %67 0
-         %69 = OpCompositeExtract %v4half %67 1
-         %70 = OpCompositeConstruct %mat2v4half %68 %69
-               OpStore %64 %70 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_mat2v4half_uint_4 %49 None
-         %72 = OpCompositeExtract %half %l_a_i_i 0
-         %73 = OpCompositeExtract %half %l_a 0 0 0
-         %74 = OpFAdd %half %72 %73
-         %75 = OpCompositeExtract %half %l_a_i 0 0
-         %76 = OpFAdd %half %74 %75
-         %77 = OpCompositeExtract %half %l_a_i_i 0
-         %78 = OpFAdd %half %76 %77
-         %79 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %79 %78 None
+         %64 = OpPhi %uint %uint_0 %59 %65 %61
+               OpLoopMerge %63 %61 None
+               OpBranch %60
+         %60 = OpLabel
+         %66 = OpUGreaterThanEqual %bool %64 %uint_4
+               OpSelectionMerge %68 None
+               OpBranchConditional %66 %69 %68
+         %69 = OpLabel
+               OpBranch %63
+         %68 = OpLabel
+         %70 = OpAccessChain %_ptr_Function_mat2v4half %55 %64
+         %71 = OpAccessChain %_ptr_Function_mat2x4_f16_std140 %53 %64
+         %73 = OpLoad %mat2x4_f16_std140 %71 None
+         %74 = OpCompositeExtract %v4half %73 0
+         %75 = OpCompositeExtract %v4half %73 1
+         %76 = OpCompositeConstruct %mat2v4half %74 %75
+               OpStore %70 %76 None
+               OpBranch %61
+         %61 = OpLabel
+         %65 = OpIAdd %uint %64 %uint_1
+               OpBranch %62
+         %63 = OpLabel
+        %l_a = OpLoad %_arr_mat2v4half_uint_4 %55 None
+         %78 = OpCompositeExtract %half %l_a_i_i 0
+         %79 = OpCompositeExtract %half %l_a 0 0 0
+         %80 = OpFAdd %half %78 %79
+         %81 = OpCompositeExtract %half %l_a_i 0 0
+         %82 = OpFAdd %half %80 %81
+         %83 = OpCompositeExtract %half %l_a_i_i 0
+         %84 = OpFAdd %half %82 %83
+         %85 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %85 %84 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
index 40df881..47afb3c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -17,7 +17,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x4 v_2 = f16mat2x4(v.inner[2].col0, v.inner[2].col1);
+  f16mat2x4 v_2 = f16mat2x4(v.inner[2u].col0, v.inner[2u].col1);
   mat2x4_f16_std140 v_3[4] = v.inner;
   f16mat2x4 v_4[4] = f16mat2x4[4](f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)), f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf)));
   {
@@ -37,6 +37,6 @@
   }
   f16mat2x4 l_a[4] = v_4;
   f16mat2x4 l_a_i = v_2;
-  f16vec4 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  f16vec4 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 1d491c4..958cdb8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -49,6 +49,6 @@
   matrix<float16_t, 2, 4> l_a[4] = v_8(0u);
   matrix<float16_t, 2, 4> l_a_i = v_4(32u);
   vector<float16_t, 4> l_a_i_i = tint_bitcast_to_f16(a[2u].zw);
-  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].z)) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].z)) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 2aeea57..a8e5cb6 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<half2x4, 4>* a [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<half2x4, 4>* const p_a = tint_module_vars.a;
-  const constant half2x4* const p_a_2 = (&(*p_a)[2]);
-  const constant half4* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant half2x4* const p_a_2 = (&(*p_a)[2u]);
+  const constant half4* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<half2x4, 4> const l_a = (*p_a);
   half2x4 const l_a_i = (*p_a_2);
   half4 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
index 7784457..3c14282 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -52,66 +52,65 @@
 %_ptr_Uniform__arr_mat2x4_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat2x4_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
  %mat2v4half = OpTypeMatrix %v4half 2
 %_ptr_Function__arr_mat2x4_f16_std140_uint_4 = OpTypePointer Function %_arr_mat2x4_f16_std140_uint_4
 %_arr_mat2v4half_uint_4 = OpTypeArray %mat2v4half %uint_4
 %_ptr_Function__arr_mat2v4half_uint_4 = OpTypePointer Function %_arr_mat2v4half_uint_4
-         %37 = OpConstantNull %_arr_mat2v4half_uint_4
+         %36 = OpConstantNull %_arr_mat2v4half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat2v4half = OpTypePointer Function %mat2v4half
 %_ptr_Function_mat2x4_f16_std140 = OpTypePointer Function %mat2x4_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %32 = OpVariable %_ptr_Function__arr_mat2x4_f16_std140_uint_4 Function
-         %34 = OpVariable %_ptr_Function__arr_mat2v4half_uint_4 Function %37
+         %31 = OpVariable %_ptr_Function__arr_mat2x4_f16_std140_uint_4 Function
+         %33 = OpVariable %_ptr_Function__arr_mat2v4half_uint_4 Function %36
          %17 = OpAccessChain %_ptr_Uniform__arr_mat2x4_f16_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_0
-         %24 = OpLoad %v4half %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_1
-         %27 = OpLoad %v4half %25 None
-      %l_a_i = OpCompositeConstruct %mat2v4half %24 %27
+         %20 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_0
+         %23 = OpLoad %v4half %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_1
+         %26 = OpLoad %v4half %24 None
+      %l_a_i = OpCompositeConstruct %mat2v4half %23 %26
     %l_a_i_i = OpCompositeExtract %v4half %l_a_i 1
-         %31 = OpLoad %_arr_mat2x4_f16_std140_uint_4 %17 None
-               OpStore %32 %31
-               OpBranch %38
-         %38 = OpLabel
-               OpBranch %41
-         %41 = OpLabel
-         %43 = OpPhi %uint %uint_0 %38 %44 %40
-               OpLoopMerge %42 %40 None
-               OpBranch %39
-         %39 = OpLabel
-         %45 = OpUGreaterThanEqual %bool %43 %uint_4
-               OpSelectionMerge %47 None
-               OpBranchConditional %45 %48 %47
-         %48 = OpLabel
-               OpBranch %42
-         %47 = OpLabel
-         %49 = OpAccessChain %_ptr_Function_mat2v4half %34 %43
-         %51 = OpAccessChain %_ptr_Function_mat2x4_f16_std140 %32 %43
-         %53 = OpLoad %mat2x4_f16_std140 %51 None
-         %54 = OpCompositeExtract %v4half %53 0
-         %55 = OpCompositeExtract %v4half %53 1
-         %56 = OpCompositeConstruct %mat2v4half %54 %55
-               OpStore %49 %56 None
+         %30 = OpLoad %_arr_mat2x4_f16_std140_uint_4 %17 None
+               OpStore %31 %30
+               OpBranch %37
+         %37 = OpLabel
                OpBranch %40
          %40 = OpLabel
-         %44 = OpIAdd %uint %43 %uint_1
+         %42 = OpPhi %uint %uint_0 %37 %43 %39
+               OpLoopMerge %41 %39 None
+               OpBranch %38
+         %38 = OpLabel
+         %44 = OpUGreaterThanEqual %bool %42 %uint_4
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %47 %46
+         %47 = OpLabel
                OpBranch %41
-         %42 = OpLabel
-        %l_a = OpLoad %_arr_mat2v4half_uint_4 %34 None
-         %58 = OpCompositeExtract %half %l_a_i_i 0
-         %59 = OpCompositeExtract %half %l_a 0 0 0
-         %60 = OpFAdd %half %58 %59
-         %61 = OpCompositeExtract %half %l_a_i 0 0
-         %62 = OpFAdd %half %60 %61
-         %63 = OpCompositeExtract %half %l_a_i_i 0
-         %64 = OpFAdd %half %62 %63
-         %65 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %65 %64 None
+         %46 = OpLabel
+         %48 = OpAccessChain %_ptr_Function_mat2v4half %33 %42
+         %50 = OpAccessChain %_ptr_Function_mat2x4_f16_std140 %31 %42
+         %52 = OpLoad %mat2x4_f16_std140 %50 None
+         %53 = OpCompositeExtract %v4half %52 0
+         %54 = OpCompositeExtract %v4half %52 1
+         %55 = OpCompositeConstruct %mat2v4half %53 %54
+               OpStore %48 %55 None
+               OpBranch %39
+         %39 = OpLabel
+         %43 = OpIAdd %uint %42 %uint_1
+               OpBranch %40
+         %41 = OpLabel
+        %l_a = OpLoad %_arr_mat2v4half_uint_4 %33 None
+         %57 = OpCompositeExtract %half %l_a_i_i 0
+         %58 = OpCompositeExtract %half %l_a 0 0 0
+         %59 = OpFAdd %half %57 %58
+         %60 = OpCompositeExtract %half %l_a_i 0 0
+         %61 = OpFAdd %half %59 %60
+         %62 = OpCompositeExtract %half %l_a_i_i 0
+         %63 = OpFAdd %half %61 %62
+         %64 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.glsl
index 41b85e0..122510c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.glsl
@@ -17,9 +17,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x2 t = transpose(f16mat2x4(v.inner[2].col0, v.inner[2].col1));
-  float16_t l = length(v.inner[0].col1.ywxz);
-  float16_t a = abs(v.inner[0].col1.ywxz[0u]);
-  float16_t v_2 = (t[0][0u] + float16_t(l));
+  f16mat4x2 t = transpose(f16mat2x4(v.inner[2u].col0, v.inner[2u].col1));
+  float16_t l = length(v.inner[0u].col1.ywxz);
+  float16_t a = abs(v.inner[0u].col1.ywxz[0u]);
+  float16_t v_2 = (t[0u][0u] + float16_t(l));
   v_1.inner = (v_2 + float16_t(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
index dd0fd8d..6096d6b 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -27,7 +27,7 @@
   matrix<float16_t, 4, 2> t = transpose(v_4(32u));
   float16_t l = length(tint_bitcast_to_f16(u[0u].zw).ywxz);
   float16_t a = abs(tint_bitcast_to_f16(u[0u].zw).ywxz.x);
-  float16_t v_8 = (t[int(0)].x + float16_t(l));
+  float16_t v_8 = (t[0u].x + float16_t(l));
   s.Store<float16_t>(0u, (v_8 + float16_t(a)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
index 5ddb677..55c59e7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<half2x4, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  half4x2 const t = transpose((*tint_module_vars.u)[2]);
-  half const l = length((*tint_module_vars.u)[0][1].ywxz);
-  half const a = abs((*tint_module_vars.u)[0][1].ywxz[0u]);
-  half const v = (t[0][0u] + half(l));
+  half4x2 const t = transpose((*tint_module_vars.u)[2u]);
+  half const l = length((*tint_module_vars.u)[0u][1u].ywxz);
+  half const a = abs((*tint_module_vars.u)[0u][1u].ywxz[0u]);
+  half const v = (t[0u][0u] + half(l));
   (*tint_module_vars.s) = (v + half(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.spvasm
index b062bac..39d6950 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %36 = OpExtInstImport "GLSL.std.450"
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -51,35 +51,33 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
  %mat2v4half = OpTypeMatrix %v4half 2
      %v2half = OpTypeVector %half 2
  %mat4v2half = OpTypeMatrix %v2half 4
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v4half %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v4half %23 None
-         %27 = OpCompositeConstruct %mat2v4half %22 %25
-          %t = OpTranspose %mat4v2half %27
-         %31 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %33 = OpLoad %v4half %31 None
-         %34 = OpVectorShuffle %v4half %33 %33 1 3 0 2
-          %l = OpExtInst %half %36 Length %34
-         %37 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %38 = OpLoad %v4half %37 None
-         %39 = OpVectorShuffle %v4half %38 %38 1 3 0 2
-         %40 = OpCompositeExtract %half %39 0
-          %a = OpExtInst %half %36 FAbs %40
-         %42 = OpCompositeExtract %half %t 0 0
-         %43 = OpFAdd %half %42 %l
-         %44 = OpFAdd %half %43 %a
-         %45 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %45 %44 None
+         %17 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v4half %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v4half %22 None
+         %26 = OpCompositeConstruct %mat2v4half %21 %24
+          %t = OpTranspose %mat4v2half %26
+         %30 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %31 = OpLoad %v4half %30 None
+         %32 = OpVectorShuffle %v4half %31 %31 1 3 0 2
+          %l = OpExtInst %half %34 Length %32
+         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v4half %35 None
+         %37 = OpVectorShuffle %v4half %36 %36 1 3 0 2
+         %38 = OpCompositeExtract %half %37 0
+          %a = OpExtInst %half %34 FAbs %38
+         %40 = OpCompositeExtract %half %t 0 0
+         %41 = OpFAdd %half %40 %l
+         %42 = OpFAdd %half %41 %a
+         %43 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.glsl
index 52cbc91..a3ea5ea 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.glsl
@@ -16,10 +16,10 @@
   float16_t inner;
 } v_2;
 float16_t a(f16mat2x4 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float16_t b(f16mat2x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float16_t c(f16vec4 v) {
   return v[0u];
@@ -47,7 +47,7 @@
     }
   }
   float16_t v_7 = a(v_4);
-  float16_t v_8 = (v_7 + b(f16mat2x4(v_1.inner[1].col0, v_1.inner[1].col1)));
-  float16_t v_9 = (v_8 + c(v_1.inner[1].col0.ywxz));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.ywxz[0u]));
+  float16_t v_8 = (v_7 + b(f16mat2x4(v_1.inner[1u].col0, v_1.inner[1u].col1)));
+  float16_t v_9 = (v_8 + c(v_1.inner[1u].col0.ywxz));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
index 59b5f6c..8fa8a1a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float16_t a(matrix<float16_t, 2, 4> a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float16_t b(matrix<float16_t, 2, 4> m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float16_t c(vector<float16_t, 4> v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.msl
index 8647cd7..7171329 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 half a(tint_array<half2x4, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 half b(half2x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 half c(half4 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<half2x4, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   half const v_1 = a((*tint_module_vars.u));
-  half const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  half const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].ywxz));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].ywxz[0u]));
+  half const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  half const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].ywxz));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.spvasm
index 55629ff..092d72b 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 92
+; Bound: 90
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,8 +70,6 @@
 %_ptr_Function_mat2x4_f16_std140 = OpTypePointer Function %mat2x4_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %a = OpFunction %half None %17
         %a_0 = OpFunctionParameter %_arr_mat2v4half_uint_4
@@ -131,25 +129,25 @@
          %51 = OpLabel
          %67 = OpLoad %_arr_mat2v4half_uint_4 %44 None
          %68 = OpFunctionCall %half %a %67
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %73 = OpLoad %v4half %69 None
-         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_1
-         %75 = OpLoad %v4half %74 None
-         %76 = OpCompositeConstruct %mat2v4half %73 %75
-         %77 = OpFunctionCall %half %b %76
-         %78 = OpFAdd %half %68 %77
-         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %80 = OpLoad %v4half %79 None
-         %81 = OpVectorShuffle %v4half %80 %80 1 3 0 2
-         %82 = OpFunctionCall %half %c %81
-         %83 = OpFAdd %half %78 %82
-         %84 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %85 = OpLoad %v4half %84 None
-         %86 = OpVectorShuffle %v4half %85 %85 1 3 0 2
-         %87 = OpCompositeExtract %half %86 0
-         %88 = OpFunctionCall %half %d %87
-         %89 = OpFAdd %half %83 %88
-         %90 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %90 %89 None
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %71 = OpLoad %v4half %69 None
+         %72 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_1
+         %73 = OpLoad %v4half %72 None
+         %74 = OpCompositeConstruct %mat2v4half %71 %73
+         %75 = OpFunctionCall %half %b %74
+         %76 = OpFAdd %half %68 %75
+         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %78 = OpLoad %v4half %77 None
+         %79 = OpVectorShuffle %v4half %78 %78 1 3 0 2
+         %80 = OpFunctionCall %half %c %79
+         %81 = OpFAdd %half %76 %80
+         %82 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %83 = OpLoad %v4half %82 None
+         %84 = OpVectorShuffle %v4half %83 %83 1 3 0 2
+         %85 = OpCompositeExtract %half %84 0
+         %86 = OpFunctionCall %half %d %85
+         %87 = OpFAdd %half %81 %86
+         %88 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %88 %87 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.glsl
index 7a39a02..1f58d49 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.glsl
@@ -36,8 +36,8 @@
     }
   }
   p = v_3;
-  p[1] = f16mat2x4(v.inner[2].col0, v.inner[2].col1);
-  p[1][0] = v.inner[0].col1.ywxz;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = f16mat2x4(v.inner[2u].col0, v.inner[2u].col1);
+  p[1u][0u] = v.inner[0u].col1.ywxz;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 6df806a..b693c59 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -49,9 +49,9 @@
 void f() {
   matrix<float16_t, 2, 4> v_12[4] = v_8(0u);
   p = v_12;
-  p[int(1)] = v_4(32u);
-  p[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).ywxz;
-  p[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
-  s.Store<float16_t>(0u, p[int(1)][int(0)].x);
+  p[1u] = v_4(32u);
+  p[1u][0u] = tint_bitcast_to_f16(u[0u].zw).ywxz;
+  p[1u][0u].x = float16_t(f16tof32(u[0u].z));
+  s.Store<float16_t>(0u, p[1u][0u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.msl
index fa9fa49..2b8340b 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<half2x4, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.spvasm
index c4c373e..a81f542 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 80
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -61,12 +61,9 @@
 %_ptr_Function_mat2x4_f16_std140 = OpTypePointer Function %mat2x4_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat2v4half = OpTypePointer Private %mat2v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -105,28 +102,28 @@
          %34 = OpLabel
          %50 = OpLoad %_arr_mat2v4half_uint_4 %28 None
                OpStore %p %50 None
-         %51 = OpAccessChain %_ptr_Private_mat2v4half %p %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v4half %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v4half %59 None
-         %61 = OpCompositeConstruct %mat2v4half %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v4half %65 None
-         %67 = OpVectorShuffle %v4half %66 %66 1 3 0 2
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_half %69 %uint_0
-         %72 = OpLoad %half %70 None
-         %73 = OpAccessChain %_ptr_Private_half %68 %uint_0
-               OpStore %73 %72 None
-         %75 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Private_half %75 %uint_0
-         %77 = OpLoad %half %76 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %78 %77 None
+         %51 = OpAccessChain %_ptr_Private_mat2v4half %p %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v4half %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v4half %57 None
+         %59 = OpCompositeConstruct %mat2v4half %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v4half %62 None
+         %64 = OpVectorShuffle %v4half %63 %63 1 3 0 2
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_half %66 %uint_0
+         %69 = OpLoad %half %67 None
+         %70 = OpAccessChain %_ptr_Private_half %65 %uint_0
+               OpStore %70 %69 None
+         %72 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Private_half %72 %uint_0
+         %74 = OpLoad %half %73 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %75 %74 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.glsl
index 0b78b11..021a49a 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.glsl
@@ -35,7 +35,7 @@
     }
   }
   v_1.inner = v_3;
-  v_1.inner[1] = f16mat2x4(v.inner[2].col0, v.inner[2].col1);
-  v_1.inner[1][0] = v.inner[0].col1.ywxz;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  v_1.inner[1u] = f16mat2x4(v.inner[2u].col0, v.inner[2u].col1);
+  v_1.inner[1u][0u] = v.inner[0u].col1.ywxz;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.ir.msl
index 3ff3303..cb62f04 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<half2x4, 4>* u [[buffer(0)]], device tint_array<half2x4, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.spvasm
index 97b1d69..36f067e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -61,12 +61,9 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer__arr_mat2v4half_uint_4 = OpTypePointer StorageBuffer %_arr_mat2v4half_uint_4
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %17
@@ -105,23 +102,23 @@
          %48 = OpLoad %_arr_mat2v4half_uint_4 %25 None
          %49 = OpAccessChain %_ptr_StorageBuffer__arr_mat2v4half_uint_4 %10 %uint_0
                OpStore %49 %48 None
-         %51 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %10 %uint_0 %int_1
-         %55 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %58 = OpLoad %v4half %55 None
-         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %60 = OpLoad %v4half %59 None
-         %61 = OpCompositeConstruct %mat2v4half %58 %60
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %int_1 %int_0
-         %65 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %66 = OpLoad %v4half %65 None
-         %67 = OpVectorShuffle %v4half %66 %66 1 3 0 2
-               OpStore %62 %67 None
-         %68 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %70 = OpAccessChain %_ptr_Uniform_half %69 %uint_0
-         %72 = OpLoad %half %70 None
-         %73 = OpAccessChain %_ptr_StorageBuffer_half %68 %uint_0
-               OpStore %73 %72 None
+         %51 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %10 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v4half %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v4half %57 None
+         %59 = OpCompositeConstruct %mat2v4half %56 %58
+               OpStore %51 %59 None
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %uint_1 %uint_0
+         %62 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %63 = OpLoad %v4half %62 None
+         %64 = OpVectorShuffle %v4half %63 %63 1 3 0 2
+               OpStore %60 %64 None
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %uint_1 %uint_0
+         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %67 = OpAccessChain %_ptr_Uniform_half %66 %uint_0
+         %69 = OpLoad %half %67 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_half %65 %uint_0
+               OpStore %70 %69 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.glsl
index 1a657c0..1b2ea14 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.glsl
@@ -47,9 +47,9 @@
     }
   }
   w = v_4;
-  w[1] = f16mat2x4(v.inner[2].col0, v.inner[2].col1);
-  w[1][0] = v.inner[0].col1.ywxz;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = f16mat2x4(v.inner[2u].col0, v.inner[2u].col1);
+  w[1u][0u] = v.inner[0u].col1.ywxz;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index b79883d..4e84988 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -67,9 +67,9 @@
   GroupMemoryBarrierWithGroupSync();
   matrix<float16_t, 2, 4> v_14[4] = v_8(0u);
   w = v_14;
-  w[int(1)] = v_4(32u);
-  w[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).ywxz;
-  w[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
+  w[1u] = v_4(32u);
+  w[1u][0u] = tint_bitcast_to_f16(u[0u].zw).ywxz;
+  w[1u][0u].x = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
index 0c46632..e41da6f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<half2x4, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<half2x4, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<half2x4, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.msl
index b54d2c1..ea42e796 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<half2x4, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<half2x4, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = half2x4(half4(0.0h), half4(0.0h));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
index 9349813..073c7c2 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 95
+; Bound: 91
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -60,15 +60,11 @@
          %47 = OpConstantNull %_arr_mat2v4half_uint_4
 %_ptr_Function_mat2v4half = OpTypePointer Function %mat2v4half
 %_ptr_Function_mat2x4_f16_std140 = OpTypePointer Function %mat2x4_f16_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %91 = OpTypeFunction %void
+         %87 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -127,29 +123,29 @@
          %52 = OpLabel
          %66 = OpLoad %_arr_mat2v4half_uint_4 %45 None
                OpStore %w %66 None
-         %67 = OpAccessChain %_ptr_Workgroup_mat2v4half %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %73 = OpLoad %v4half %70 None
-         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %75 = OpLoad %v4half %74 None
-         %76 = OpCompositeConstruct %mat2v4half %73 %75
-               OpStore %67 %76 None
-         %77 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %81 = OpLoad %v4half %80 None
-         %82 = OpVectorShuffle %v4half %81 %81 1 3 0 2
-               OpStore %77 %82 None
-         %83 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %85 = OpAccessChain %_ptr_Uniform_half %84 %uint_0
-         %87 = OpLoad %half %85 None
-         %88 = OpAccessChain %_ptr_Workgroup_half %83 %uint_0
-               OpStore %88 %87 None
+         %67 = OpAccessChain %_ptr_Workgroup_mat2v4half %w %uint_1
+         %68 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %70 = OpLoad %v4half %68 None
+         %71 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %72 = OpLoad %v4half %71 None
+         %73 = OpCompositeConstruct %mat2v4half %70 %72
+               OpStore %67 %73 None
+         %74 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %77 = OpLoad %v4half %76 None
+         %78 = OpVectorShuffle %v4half %77 %77 1 3 0 2
+               OpStore %74 %78 None
+         %79 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %81 = OpAccessChain %_ptr_Uniform_half %80 %uint_0
+         %83 = OpLoad %half %81 None
+         %84 = OpAccessChain %_ptr_Workgroup_half %79 %uint_0
+               OpStore %84 %83 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %87
+         %88 = OpLabel
+         %89 = OpLoad %uint %f_local_invocation_index_Input None
+         %90 = OpFunctionCall %void %f_inner %89
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 81b5fa5..1a2bf1e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -31,10 +31,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x4 l_a[4] = a_load(0u);
-  float2x4 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float2x4 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_2 / 4]);
-  const uint scalar_offset_3 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 81b5fa5..1a2bf1e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -31,10 +31,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float2x4 l_a[4] = a_load(0u);
-  float2x4 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_2 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float2x4 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_2 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_2 / 4]);
-  const uint scalar_offset_3 = (((32u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_3 = (((32u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 1u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 27186c9..567e3dc 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,10 +15,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
-  int v_3 = i();
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 1u);
   mat2x4 l_a[4] = v.inner;
   mat2x4 l_a_i = v.inner[v_2];
   vec4 l_a_i_i = v.inner[v_2][v_3];
-  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index ce9262d..baf849c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (32u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (32u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 1u)));
   float2x4 l_a[4] = v_1(0u);
   float2x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index ce9262d..baf849c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (32u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (32u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 1u)));
   float2x4 l_a[4] = v_1(0u);
   float2x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index d5b7298..26dcbc6 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<float2x4, 4>* const p_a = tint_module_vars.a;
-  const constant float2x4* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant float4* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant float2x4* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant float4* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<float2x4, 4> const l_a = (*p_a);
   float2x4 const l_a_i = (*p_a_i);
   float4 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index cf0d49c..fc1819e 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 1u);
   tint_array<float2x4, 4> const l_a = *(tint_symbol_2);
   float2x4 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   float4 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index f5ad67e..57f558c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,7 +56,9 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat2v4float_uint_4 = OpTypePointer Uniform %_arr_mat2v4float_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -71,21 +74,25 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat2v4float_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_mat2v4float %p_a %31
-         %34 = OpFunctionCall %int %i
-    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %34
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_mat2v4float %p_a %33
+         %38 = OpFunctionCall %int %i
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %34 UMin %39 %uint_1
+    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %40
         %l_a = OpLoad %_arr_mat2v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat2v4float %p_a_i None
     %l_a_i_i = OpLoad %v4float %p_a_i_i None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpCompositeExtract %float %l_a 0 0 0
-         %44 = OpFAdd %float %42 %43
-         %45 = OpCompositeExtract %float %l_a_i 0 0
-         %46 = OpFAdd %float %44 %45
-         %47 = OpCompositeExtract %float %l_a_i_i 0
-         %48 = OpFAdd %float %46 %47
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %47 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
+         %49 = OpLoad %float %47 None
+         %50 = OpCompositeExtract %float %l_a 0 0 0
+         %51 = OpFAdd %float %49 %50
+         %52 = OpCompositeExtract %float %l_a_i 0 0
+         %53 = OpFAdd %float %51 %52
+         %54 = OpCompositeExtract %float %l_a_i_i 0
+         %55 = OpFAdd %float %53 %54
+         %56 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
index 58e9c30..65d09cc 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 l_a[4] = v.inner;
-  mat2x4 l_a_i = v.inner[2];
-  vec4 l_a_i_i = v.inner[2][1];
-  v_1.inner = (((v.inner[2][1].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  mat2x4 l_a_i = v.inner[2u];
+  vec4 l_a_i_i = v.inner[2u][1u];
+  v_1.inner = (((v.inner[2u][1u].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index a8803db..cf84df7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float2x4 l_a[4] = v_1(0u);
   float2x4 l_a_i = v(64u);
   float4 l_a_i_i = asfloat(a[5u]);
-  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index a8803db..cf84df7 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float2x4 l_a[4] = v_1(0u);
   float2x4 l_a_i = v(64u);
   float4 l_a_i_i = asfloat(a[5u]);
-  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[5u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index f338175..f743e8c 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<float2x4, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<float2x4, 4>* const p_a = tint_module_vars.a;
-  const constant float2x4* const p_a_2 = (&(*p_a)[2]);
-  const constant float4* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant float2x4* const p_a_2 = (&(*p_a)[2u]);
+  const constant float4* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<float2x4, 4> const l_a = (*p_a);
   float2x4 const l_a_i = (*p_a_2);
   float4 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index 83f0140..90583f1 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -48,29 +48,28 @@
 %_ptr_Uniform__arr_mat2v4float_uint_4 = OpTypePointer Uniform %_arr_mat2v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat2v4float_uint_4 %1 %uint_0
-      %p_a_2 = OpAccessChain %_ptr_Uniform_mat2v4float %p_a %int_2
-    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %int_1
+      %p_a_2 = OpAccessChain %_ptr_Uniform_mat2v4float %p_a %uint_2
+    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %uint_1
         %l_a = OpLoad %_arr_mat2v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat2v4float %p_a_2 None
     %l_a_i_i = OpLoad %v4float %p_a_2_1 None
-         %30 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
-         %32 = OpLoad %float %30 None
-         %33 = OpCompositeExtract %float %l_a 0 0 0
-         %34 = OpFAdd %float %32 %33
-         %35 = OpCompositeExtract %float %l_a_i 0 0
-         %36 = OpFAdd %float %34 %35
-         %37 = OpCompositeExtract %float %l_a_i_i 0
-         %38 = OpFAdd %float %36 %37
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %39 %38 None
+         %29 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
+         %31 = OpLoad %float %29 None
+         %32 = OpCompositeExtract %float %l_a 0 0 0
+         %33 = OpFAdd %float %31 %32
+         %34 = OpCompositeExtract %float %l_a_i 0 0
+         %35 = OpFAdd %float %33 %34
+         %36 = OpCompositeExtract %float %l_a_i_i 0
+         %37 = OpFAdd %float %35 %36
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.glsl
index d2b9311..d53f686 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.glsl
@@ -10,9 +10,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x2 t = transpose(v.inner[2]);
-  float l = length(v.inner[0][1].ywxz);
-  float a = abs(v.inner[0][1].ywxz[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat4x2 t = transpose(v.inner[2u]);
+  float l = length(v.inner[0u][1u].ywxz);
+  float a = abs(v.inner[0u][1u].ywxz[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 6d46199..d595e84 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float4x2 t = transpose(v(64u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 6d46199..d595e84 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float4x2 t = transpose(v(64u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
index be4086e..a778a39 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<float2x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  float4x2 const t = transpose((*tint_module_vars.u)[2]);
-  float const l = length((*tint_module_vars.u)[0][1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0][1].ywxz[0u]);
-  float const v = (t[0][0u] + float(l));
+  float4x2 const t = transpose((*tint_module_vars.u)[2u]);
+  float const l = length((*tint_module_vars.u)[0u][1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u][1u].ywxz[0u]);
+  float const v = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.spvasm
index 3e2a33a..ee02427 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
-         %33 = OpExtInstImport "GLSL.std.450"
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -45,32 +45,30 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
     %v2float = OpTypeVector %float 2
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2
-         %22 = OpLoad %mat2v4float %17 None
-          %t = OpTranspose %mat4v2float %22
-         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %30 = OpLoad %v4float %26 None
-         %31 = OpVectorShuffle %v4float %30 %30 1 3 0 2
-          %l = OpExtInst %float %33 Length %31
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %35 = OpLoad %v4float %34 None
-         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
-         %37 = OpCompositeExtract %float %36 0
-          %a = OpExtInst %float %33 FAbs %37
-         %39 = OpCompositeExtract %float %t 0 0
-         %40 = OpFAdd %float %39 %l
-         %41 = OpFAdd %float %40 %a
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %42 %41 None
+         %17 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2
+         %21 = OpLoad %mat2v4float %17 None
+          %t = OpTranspose %mat4v2float %21
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %28 = OpLoad %v4float %25 None
+         %29 = OpVectorShuffle %v4float %28 %28 1 3 0 2
+          %l = OpExtInst %float %31 Length %29
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %33 = OpLoad %v4float %32 None
+         %34 = OpVectorShuffle %v4float %33 %33 1 3 0 2
+         %35 = OpCompositeExtract %float %34 0
+          %a = OpExtInst %float %31 FAbs %35
+         %37 = OpCompositeExtract %float %t 0 0
+         %38 = OpFAdd %float %37 %l
+         %39 = OpFAdd %float %38 %a
+         %40 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.glsl
index 208c738..a6796a8 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.glsl
@@ -9,10 +9,10 @@
   float inner;
 } v_2;
 float a(mat2x4 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat2x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec4 v) {
   return v[0u];
@@ -23,7 +23,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   float v_3 = a(v_1.inner);
-  float v_4 = (v_3 + b(v_1.inner[1]));
-  float v_5 = (v_4 + c(v_1.inner[1][0].ywxz));
-  v_2.inner = (v_5 + d(v_1.inner[1][0].ywxz[0u]));
+  float v_4 = (v_3 + b(v_1.inner[1u]));
+  float v_5 = (v_4 + c(v_1.inner[1u][0u].ywxz));
+  v_2.inner = (v_5 + d(v_1.inner[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index a33ecae..d44bcae 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index a33ecae..d44bcae 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float2x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float2x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.msl
index 4ca8572..5bc9969 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 float a(tint_array<float2x4, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float2x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float4 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<float2x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_1 = a((*tint_module_vars.u));
-  float const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  float const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].ywxz));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].ywxz[0u]));
+  float const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  float const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].ywxz));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.spvasm
index bd1dc15..4239757 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -54,10 +54,8 @@
 %_ptr_Uniform__arr_mat2v4float_uint_4 = OpTypePointer Uniform %_arr_mat2v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %15
         %a_0 = OpFunctionParameter %_arr_mat2v4float_uint_4
@@ -87,22 +85,22 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_mat2v4float_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_mat2v4float_uint_4 %36 None
          %40 = OpFunctionCall %float %a %39
-         %41 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_1
-         %45 = OpLoad %mat2v4float %41 None
-         %46 = OpFunctionCall %float %b %45
-         %47 = OpFAdd %float %40 %46
-         %48 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %51 = OpLoad %v4float %48 None
-         %52 = OpVectorShuffle %v4float %51 %51 1 3 0 2
-         %53 = OpFunctionCall %float %c %52
-         %54 = OpFAdd %float %47 %53
-         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %56 = OpLoad %v4float %55 None
-         %57 = OpVectorShuffle %v4float %56 %56 1 3 0 2
-         %58 = OpCompositeExtract %float %57 0
-         %59 = OpFunctionCall %float %d %58
-         %60 = OpFAdd %float %54 %59
-         %61 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %61 %60 None
+         %41 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %mat2v4float %41 None
+         %45 = OpFunctionCall %float %b %44
+         %46 = OpFAdd %float %40 %45
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+         %51 = OpFunctionCall %float %c %50
+         %52 = OpFAdd %float %46 %51
+         %53 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %54 = OpLoad %v4float %53 None
+         %55 = OpVectorShuffle %v4float %54 %54 1 3 0 2
+         %56 = OpCompositeExtract %float %55 0
+         %57 = OpFunctionCall %float %d %56
+         %58 = OpFAdd %float %52 %57
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.glsl
index e999995..d482909 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.glsl
@@ -12,8 +12,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[1][0] = v.inner[0][1].ywxz;
-  p[1][0][0u] = v.inner[0][1].x;
-  v_1.inner = p[1][0].x;
+  p[1u] = v.inner[2u];
+  p[1u][0u] = v.inner[0u][1u].ywxz;
+  p[1u][0u][0u] = v.inner[0u][1u].x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 38f12e0..581413f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float2x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 38f12e0..581413f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float2x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.msl
index 51ddc96..ae56973 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<float2x4, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.spvasm
index dcf45f6..8979722 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,12 +46,10 @@
 %_ptr_Uniform__arr_mat2v4float_uint_4 = OpTypePointer Uniform %_arr_mat2v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_mat2v4float = OpTypePointer Private %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
@@ -61,25 +59,25 @@
          %20 = OpAccessChain %_ptr_Uniform__arr_mat2v4float_uint_4 %1 %uint_0
          %23 = OpLoad %_arr_mat2v4float_uint_4 %20 None
                OpStore %p %23 None
-         %24 = OpAccessChain %_ptr_Private_mat2v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2
-         %31 = OpLoad %mat2v4float %28 None
-               OpStore %24 %31 None
-         %32 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %37 = OpLoad %v4float %35 None
-         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
-               OpStore %32 %38 None
-         %39 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
-         %43 = OpLoad %float %41 None
-         %44 = OpAccessChain %_ptr_Private_float %39 %uint_0
-               OpStore %44 %43 None
-         %46 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %47 = OpAccessChain %_ptr_Private_float %46 %uint_0
-         %48 = OpLoad %float %47 None
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %24 = OpAccessChain %_ptr_Private_mat2v4float %p %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2
+         %30 = OpLoad %mat2v4float %27 None
+               OpStore %24 %30 None
+         %31 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %33 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %35 = OpLoad %v4float %33 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+               OpStore %31 %36 None
+         %37 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpAccessChain %_ptr_Private_float %37 %uint_0
+               OpStore %42 %41 None
+         %44 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %45 = OpAccessChain %_ptr_Private_float %44 %uint_0
+         %46 = OpLoad %float %45 None
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.glsl
index 0a81ef2..3c4c8cb 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[2];
-  v_1.inner[1][0] = v.inner[0][1].ywxz;
-  v_1.inner[1][0][0u] = v.inner[0][1].x;
+  v_1.inner[1u] = v.inner[2u];
+  v_1.inner[1u][0u] = v.inner[0u][1u].ywxz;
+  v_1.inner[1u][0u][0u] = v.inner[0u][1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.ir.msl
index 8bcb683..445a87f 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<float2x4, 4>* u [[buffer(0)]], device tint_array<float2x4, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.spvasm
index 41bb1c7..1e3d5eb 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,12 +45,10 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer__arr_mat2v4float_uint_4 = OpTypePointer StorageBuffer %_arr_mat2v4float_uint_4
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -60,20 +58,20 @@
          %20 = OpLoad %_arr_mat2v4float_uint_4 %17 None
          %21 = OpAccessChain %_ptr_StorageBuffer__arr_mat2v4float_uint_4 %10 %uint_0
                OpStore %21 %20 None
-         %23 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %10 %uint_0 %int_1
-         %27 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2
-         %30 = OpLoad %mat2v4float %27 None
-               OpStore %23 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %36 = OpLoad %v4float %34 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-               OpStore %31 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %38 %uint_0
-               OpStore %43 %42 None
+         %23 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %10 %uint_0 %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2
+         %29 = OpLoad %mat2v4float %26 None
+               OpStore %23 %29 None
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %34 = OpLoad %v4float %32 None
+         %35 = OpVectorShuffle %v4float %34 %34 1 3 0 2
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_float %37 %uint_0
+         %40 = OpLoad %float %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %36 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.glsl
index 8391cf6..d44acab 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.glsl
@@ -23,9 +23,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[1][0] = v.inner[0][1].ywxz;
-  w[1][0][0u] = v.inner[0][1].x;
+  w[1u] = v.inner[2u];
+  w[1u][0u] = v.inner[0u][1u].ywxz;
+  w[1u][0u][0u] = v.inner[0u][1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index f9897d1..57dbb75 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index f9897d1..57dbb75 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float2x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
index fc5bc06..76941b3 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<float2x4, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<float2x4, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<float2x4, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.msl
index d837c80..2b487fa 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<float2x4, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<float2x4, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = float2x4(float4(0.0f), float4(0.0f));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
index db99327..ed63b20 100644
--- a/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,16 +46,12 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_mat2v4float_uint_4 = OpTypePointer Uniform %_arr_mat2v4float_uint_4
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %63 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
     %f_inner = OpFunction %void None %17
 %tint_local_index = OpFunctionParameter %uint
          %18 = OpLabel
@@ -84,26 +80,26 @@
          %37 = OpAccessChain %_ptr_Uniform__arr_mat2v4float_uint_4 %1 %uint_0
          %40 = OpLoad %_arr_mat2v4float_uint_4 %37 None
                OpStore %w %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_mat2v4float %w %int_1
-         %44 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2
-         %47 = OpLoad %mat2v4float %44 None
-               OpStore %41 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %53 = OpLoad %v4float %51 None
-         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
-               OpStore %48 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_float %56 %uint_0
-         %59 = OpLoad %float %57 None
-         %60 = OpAccessChain %_ptr_Workgroup_float %55 %uint_0
-               OpStore %60 %59 None
+         %41 = OpAccessChain %_ptr_Workgroup_mat2v4float %w %uint_1
+         %42 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2
+         %44 = OpLoad %mat2v4float %42 None
+               OpStore %41 %44 None
+         %45 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+               OpStore %45 %50 None
+         %51 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %52 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_float %52 %uint_0
+         %55 = OpLoad %float %53 None
+         %56 = OpAccessChain %_ptr_Workgroup_float %51 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpLoad %uint %f_local_invocation_index_Input None
+         %62 = OpFunctionCall %void %f_inner %61
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 49897c2..e72ecc8 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -32,10 +32,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float3x3 l_a[4] = a_load(0u);
-  float3x3 l_a_i = a_load_1((48u * uint(p_a_i_save)));
-  const uint scalar_offset_3 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float3x3 l_a_i = a_load_1((48u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_3 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_3 / 4].xyz);
-  const uint scalar_offset_4 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_4 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 49897c2..e72ecc8 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -32,10 +32,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float3x3 l_a[4] = a_load(0u);
-  float3x3 l_a_i = a_load_1((48u * uint(p_a_i_save)));
-  const uint scalar_offset_3 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float3x3 l_a_i = a_load_1((48u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_3 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_3 / 4].xyz);
-  const uint scalar_offset_4 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_4 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 2d11430..594cda9 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -25,9 +25,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   mat3 v_3 = mat3(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2);
-  vec3 v_4 = v_3[i()];
+  vec3 v_4 = v_3[min(uint(i()), 2u)];
   mat3x3_f32_std140 v_5[4] = v.inner;
   mat3 v_6[4] = mat3[4](mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   {
@@ -48,5 +48,5 @@
   mat3 l_a[4] = v_6;
   mat3 l_a_i = v_3;
   vec3 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 790df42..3fc98f6 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (48u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (48u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 2u)));
   float3x3 l_a[4] = v_1(0u);
   float3x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 790df42..3fc98f6 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (48u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (48u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 2u)));
   float3x3 l_a[4] = v_1(0u);
   float3x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index ed3e893..8bb956f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -52,13 +52,13 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 2u)].packed);
   tint_array<float3x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 3> const v_15 = (*p_a_i);
   float3 const v_16 = float3(v_15[0u].packed);
   float3 const v_17 = float3(v_15[1u].packed);
   float3x3 const l_a_i = float3x3(v_16, v_17, float3(v_15[2u].packed));
   float3 const l_a_i_i = float3((*p_a_i_i));
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 912d2ba..3dcfd94 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -42,9 +42,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 2u);
   tint_array<float3x3, 4> const l_a = tint_unpack_vec3_in_composite_1(*(tint_symbol_2));
   float3x3 const l_a_i = tint_unpack_vec3_in_composite((*(tint_symbol_2))[p_a_i_save]);
   float3 const l_a_i_i = float3((*(tint_symbol_2))[p_a_i_save][p_a_i_i_save].elements);
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 3378211..6b91c2b 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 85
+; Bound: 91
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -58,6 +59,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat3x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat3x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
@@ -67,7 +69,7 @@
 %_ptr_Function__arr_mat3x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat3x3_f32_std140_uint_4
 %_arr_mat3v3float_uint_4 = OpTypeArray %mat3v3float %uint_4
 %_ptr_Function__arr_mat3v3float_uint_4 = OpTypePointer Function %_arr_mat3v3float_uint_4
-         %55 = OpConstantNull %_arr_mat3v3float_uint_4
+         %61 = OpConstantNull %_arr_mat3v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -81,60 +83,64 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %43 = OpVariable %_ptr_Function_mat3v3float Function
-         %50 = OpVariable %_ptr_Function__arr_mat3x3_f32_std140_uint_4 Function
-         %52 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function %55
+         %47 = OpVariable %_ptr_Function_mat3v3float Function
+         %56 = OpVariable %_ptr_Function__arr_mat3x3_f32_std140_uint_4 Function
+         %58 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function %61
          %28 = OpAccessChain %_ptr_Uniform__arr_mat3x3_f32_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_0
-         %34 = OpLoad %v3float %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_1
-         %37 = OpLoad %v3float %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_2
-         %40 = OpLoad %v3float %38 None
-      %l_a_i = OpCompositeConstruct %mat3v3float %34 %37 %40
-               OpStore %43 %l_a_i
-         %45 = OpFunctionCall %int %i
-         %46 = OpAccessChain %_ptr_Function_v3float %43 %45
-    %l_a_i_i = OpLoad %v3float %46 None
-         %49 = OpLoad %_arr_mat3x3_f32_std140_uint_4 %28 None
-               OpStore %50 %49
-               OpBranch %56
-         %56 = OpLabel
-               OpBranch %59
-         %59 = OpLabel
-         %61 = OpPhi %uint %uint_0 %56 %62 %58
-               OpLoopMerge %60 %58 None
-               OpBranch %57
-         %57 = OpLabel
-         %63 = OpUGreaterThanEqual %bool %61 %uint_4
-               OpSelectionMerge %65 None
-               OpBranchConditional %63 %66 %65
-         %66 = OpLabel
-               OpBranch %60
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_0
+         %38 = OpLoad %v3float %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_1
+         %41 = OpLoad %v3float %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_2
+         %44 = OpLoad %v3float %42 None
+      %l_a_i = OpCompositeConstruct %mat3v3float %38 %41 %44
+               OpStore %47 %l_a_i
+         %49 = OpFunctionCall %int %i
+         %50 = OpBitcast %uint %49
+         %51 = OpExtInst %uint %34 UMin %50 %uint_2
+         %52 = OpAccessChain %_ptr_Function_v3float %47 %51
+    %l_a_i_i = OpLoad %v3float %52 None
+         %55 = OpLoad %_arr_mat3x3_f32_std140_uint_4 %28 None
+               OpStore %56 %55
+               OpBranch %62
+         %62 = OpLabel
+               OpBranch %65
          %65 = OpLabel
-         %67 = OpAccessChain %_ptr_Function_mat3v3float %52 %61
-         %68 = OpAccessChain %_ptr_Function_mat3x3_f32_std140 %50 %61
-         %70 = OpLoad %mat3x3_f32_std140 %68 None
-         %71 = OpCompositeExtract %v3float %70 0
-         %72 = OpCompositeExtract %v3float %70 1
-         %73 = OpCompositeExtract %v3float %70 2
-         %74 = OpCompositeConstruct %mat3v3float %71 %72 %73
-               OpStore %67 %74 None
-               OpBranch %58
-         %58 = OpLabel
-         %62 = OpIAdd %uint %61 %uint_1
-               OpBranch %59
-         %60 = OpLabel
-        %l_a = OpLoad %_arr_mat3v3float_uint_4 %52 None
-         %76 = OpCompositeExtract %float %l_a_i_i 0
-         %77 = OpCompositeExtract %float %l_a 0 0 0
-         %78 = OpFAdd %float %76 %77
-         %79 = OpCompositeExtract %float %l_a_i 0 0
-         %80 = OpFAdd %float %78 %79
-         %81 = OpCompositeExtract %float %l_a_i_i 0
-         %82 = OpFAdd %float %80 %81
-         %83 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %83 %82 None
+         %67 = OpPhi %uint %uint_0 %62 %68 %64
+               OpLoopMerge %66 %64 None
+               OpBranch %63
+         %63 = OpLabel
+         %69 = OpUGreaterThanEqual %bool %67 %uint_4
+               OpSelectionMerge %71 None
+               OpBranchConditional %69 %72 %71
+         %72 = OpLabel
+               OpBranch %66
+         %71 = OpLabel
+         %73 = OpAccessChain %_ptr_Function_mat3v3float %58 %67
+         %74 = OpAccessChain %_ptr_Function_mat3x3_f32_std140 %56 %67
+         %76 = OpLoad %mat3x3_f32_std140 %74 None
+         %77 = OpCompositeExtract %v3float %76 0
+         %78 = OpCompositeExtract %v3float %76 1
+         %79 = OpCompositeExtract %v3float %76 2
+         %80 = OpCompositeConstruct %mat3v3float %77 %78 %79
+               OpStore %73 %80 None
+               OpBranch %64
+         %64 = OpLabel
+         %68 = OpIAdd %uint %67 %uint_1
+               OpBranch %65
+         %66 = OpLabel
+        %l_a = OpLoad %_arr_mat3v3float_uint_4 %58 None
+         %82 = OpCompositeExtract %float %l_a_i_i 0
+         %83 = OpCompositeExtract %float %l_a 0 0 0
+         %84 = OpFAdd %float %82 %83
+         %85 = OpCompositeExtract %float %l_a_i 0 0
+         %86 = OpFAdd %float %84 %85
+         %87 = OpCompositeExtract %float %l_a_i_i 0
+         %88 = OpFAdd %float %86 %87
+         %89 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %89 %88 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 0e66d7a..7b4f9cc 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -20,7 +20,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3 v_2 = mat3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2);
+  mat3 v_2 = mat3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2);
   mat3x3_f32_std140 v_3[4] = v.inner;
   mat3 v_4[4] = mat3[4](mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   {
@@ -40,6 +40,6 @@
   }
   mat3 l_a[4] = v_4;
   mat3 l_a_i = v_2;
-  vec3 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  vec3 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 2e94a14..1dec737 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float3x3 l_a[4] = v_1(0u);
   float3x3 l_a_i = v(96u);
   float3 l_a_i_i = asfloat(a[7u].xyz);
-  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 2e94a14..1dec737 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float3x3 l_a[4] = v_1(0u);
   float3x3 l_a_i = v(96u);
   float3 l_a_i_i = asfloat(a[7u].xyz);
-  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 4d39231..da002ce 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -45,13 +45,13 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_2 = (&(*p_a)[2]);
-  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_2 = (&(*p_a)[2u]);
+  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1u].packed);
   tint_array<float3x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 3> const v_15 = (*p_a_2);
   float3 const v_16 = float3(v_15[0u].packed);
   float3 const v_17 = float3(v_15[1u].packed);
   float3x3 const l_a_i = float3x3(v_16, v_17, float3(v_15[2u].packed));
   float3 const l_a_i_i = float3((*p_a_2_1));
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index dbdbbf3..9fc3085 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -51,70 +51,68 @@
 %_ptr_Uniform__arr_mat3x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat3x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
 %mat3v3float = OpTypeMatrix %v3float 3
 %_ptr_Function__arr_mat3x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat3x3_f32_std140_uint_4
 %_arr_mat3v3float_uint_4 = OpTypeArray %mat3v3float %uint_4
 %_ptr_Function__arr_mat3v3float_uint_4 = OpTypePointer Function %_arr_mat3v3float_uint_4
-         %40 = OpConstantNull %_arr_mat3v3float_uint_4
+         %38 = OpConstantNull %_arr_mat3v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %35 = OpVariable %_ptr_Function__arr_mat3x3_f32_std140_uint_4 Function
-         %37 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function %40
+         %33 = OpVariable %_ptr_Function__arr_mat3x3_f32_std140_uint_4 Function
+         %35 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function %38
          %17 = OpAccessChain %_ptr_Uniform__arr_mat3x3_f32_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_0
-         %24 = OpLoad %v3float %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_1
-         %27 = OpLoad %v3float %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_2
-         %30 = OpLoad %v3float %28 None
-      %l_a_i = OpCompositeConstruct %mat3v3float %24 %27 %30
+         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_0
+         %23 = OpLoad %v3float %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_1
+         %26 = OpLoad %v3float %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_2
+         %28 = OpLoad %v3float %27 None
+      %l_a_i = OpCompositeConstruct %mat3v3float %23 %26 %28
     %l_a_i_i = OpCompositeExtract %v3float %l_a_i 1
-         %34 = OpLoad %_arr_mat3x3_f32_std140_uint_4 %17 None
-               OpStore %35 %34
-               OpBranch %41
-         %41 = OpLabel
-               OpBranch %44
-         %44 = OpLabel
-         %46 = OpPhi %uint %uint_0 %41 %47 %43
-               OpLoopMerge %45 %43 None
+         %32 = OpLoad %_arr_mat3x3_f32_std140_uint_4 %17 None
+               OpStore %33 %32
+               OpBranch %39
+         %39 = OpLabel
                OpBranch %42
          %42 = OpLabel
-         %48 = OpUGreaterThanEqual %bool %46 %uint_4
-               OpSelectionMerge %50 None
-               OpBranchConditional %48 %51 %50
-         %51 = OpLabel
-               OpBranch %45
-         %50 = OpLabel
-         %52 = OpAccessChain %_ptr_Function_mat3v3float %37 %46
-         %54 = OpAccessChain %_ptr_Function_mat3x3_f32_std140 %35 %46
-         %56 = OpLoad %mat3x3_f32_std140 %54 None
-         %57 = OpCompositeExtract %v3float %56 0
-         %58 = OpCompositeExtract %v3float %56 1
-         %59 = OpCompositeExtract %v3float %56 2
-         %60 = OpCompositeConstruct %mat3v3float %57 %58 %59
-               OpStore %52 %60 None
+         %44 = OpPhi %uint %uint_0 %39 %45 %41
+               OpLoopMerge %43 %41 None
+               OpBranch %40
+         %40 = OpLabel
+         %46 = OpUGreaterThanEqual %bool %44 %uint_4
+               OpSelectionMerge %48 None
+               OpBranchConditional %46 %49 %48
+         %49 = OpLabel
                OpBranch %43
+         %48 = OpLabel
+         %50 = OpAccessChain %_ptr_Function_mat3v3float %35 %44
+         %52 = OpAccessChain %_ptr_Function_mat3x3_f32_std140 %33 %44
+         %54 = OpLoad %mat3x3_f32_std140 %52 None
+         %55 = OpCompositeExtract %v3float %54 0
+         %56 = OpCompositeExtract %v3float %54 1
+         %57 = OpCompositeExtract %v3float %54 2
+         %58 = OpCompositeConstruct %mat3v3float %55 %56 %57
+               OpStore %50 %58 None
+               OpBranch %41
+         %41 = OpLabel
+         %45 = OpIAdd %uint %44 %uint_1
+               OpBranch %42
          %43 = OpLabel
-         %47 = OpIAdd %uint %46 %uint_1
-               OpBranch %44
-         %45 = OpLabel
-        %l_a = OpLoad %_arr_mat3v3float_uint_4 %37 None
-         %62 = OpCompositeExtract %float %l_a_i_i 0
-         %63 = OpCompositeExtract %float %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat3v3float_uint_4 %35 None
+         %60 = OpCompositeExtract %float %l_a_i_i 0
+         %61 = OpCompositeExtract %float %l_a 0 0 0
+         %62 = OpFAdd %float %60 %61
+         %63 = OpCompositeExtract %float %l_a_i 0 0
          %64 = OpFAdd %float %62 %63
-         %65 = OpCompositeExtract %float %l_a_i 0 0
+         %65 = OpCompositeExtract %float %l_a_i_i 0
          %66 = OpFAdd %float %64 %65
-         %67 = OpCompositeExtract %float %l_a_i_i 0
-         %68 = OpFAdd %float %66 %67
-         %69 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %69 %68 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %67 %66 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.glsl
index 2ba4367..a47e816 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.glsl
@@ -20,9 +20,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3 t = transpose(mat3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2));
-  float l = length(v.inner[0].col1.zxy);
-  float a = abs(v.inner[0].col1.zxy[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat3 t = transpose(mat3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2));
+  float l = length(v.inner[0u].col1.zxy);
+  float a = abs(v.inner[0u].col1.zxy[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index fbd4f6d..66a482a1 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float3x3 t = transpose(v(96u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index fbd4f6d..66a482a1 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float3x3 t = transpose(v(96u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
index bd00621..9757b4d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -25,12 +25,12 @@
 
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*tint_module_vars.u)[2u];
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   float3x3 const t = transpose(float3x3(v_1, v_2, float3(v[2u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0][1].packed).zxy[0u]);
-  float const v_3 = (t[0][0u] + float(l));
+  float const l = length(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u][1u].packed).zxy[0u]);
+  float const v_3 = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v_3 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.spvasm
index a89437c..84dbe3a 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 48
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
-         %37 = OpExtInstImport "GLSL.std.450"
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,36 +50,33 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
 %mat3v3float = OpTypeMatrix %v3float 3
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v3float %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v3float %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v3float %26 None
-         %30 = OpCompositeConstruct %mat3v3float %22 %25 %28
-          %t = OpTranspose %mat3v3float %30
-         %32 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %34 = OpLoad %v3float %32 None
-         %35 = OpVectorShuffle %v3float %34 %34 2 0 1
-          %l = OpExtInst %float %37 Length %35
-         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %39 = OpLoad %v3float %38 None
-         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
-         %41 = OpCompositeExtract %float %40 0
-          %a = OpExtInst %float %37 FAbs %41
-         %43 = OpCompositeExtract %float %t 0 0
-         %44 = OpFAdd %float %43 %l
-         %45 = OpFAdd %float %44 %a
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %46 %45 None
+         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v3float %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v3float %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v3float %25 None
+         %28 = OpCompositeConstruct %mat3v3float %21 %24 %26
+          %t = OpTranspose %mat3v3float %28
+         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %31 = OpLoad %v3float %30 None
+         %32 = OpVectorShuffle %v3float %31 %31 2 0 1
+          %l = OpExtInst %float %34 Length %32
+         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v3float %35 None
+         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
+         %38 = OpCompositeExtract %float %37 0
+          %a = OpExtInst %float %34 FAbs %38
+         %40 = OpCompositeExtract %float %t 0 0
+         %41 = OpFAdd %float %40 %l
+         %42 = OpFAdd %float %41 %a
+         %43 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.glsl
index 7156933..5e80119 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.glsl
@@ -19,10 +19,10 @@
   float inner;
 } v_2;
 float a(mat3 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec3 v) {
   return v[0u];
@@ -50,7 +50,7 @@
     }
   }
   float v_7 = a(v_4);
-  float v_8 = (v_7 + b(mat3(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2)));
-  float v_9 = (v_8 + c(v_1.inner[1].col0.zxy));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.zxy[0u]));
+  float v_8 = (v_7 + b(mat3(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2)));
+  float v_9 = (v_8 + c(v_1.inner[1u].col0.zxy));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index 8998ecc..5fa6515 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float3x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float3x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index 8998ecc..5fa6515 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float3x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float3x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.msl
index f2633c3..2fb850d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.ir.msl
@@ -24,11 +24,11 @@
 };
 
 float a(tint_array<float3x3, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float3x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float3 v) {
@@ -61,10 +61,10 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_16 = a(tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[1];
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[1u];
   float3 const v_18 = float3(v_17[0u].packed);
   float3 const v_19 = float3(v_17[1u].packed);
   float const v_20 = (v_16 + b(float3x3(v_18, v_19, float3(v_17[2u].packed))));
-  float const v_21 = (v_20 + c(float3((*tint_module_vars.u)[1][0].packed).zxy));
-  (*tint_module_vars.s) = (v_21 + d(float3((*tint_module_vars.u)[1][0].packed).zxy[0u]));
+  float const v_21 = (v_20 + c(float3((*tint_module_vars.u)[1u][0u].packed).zxy));
+  (*tint_module_vars.s) = (v_21 + d(float3((*tint_module_vars.u)[1u][0u].packed).zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.spvasm
index b94cff5..fbe8158 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 96
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -69,8 +69,6 @@
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %17
@@ -132,27 +130,27 @@
          %51 = OpLabel
          %68 = OpLoad %_arr_mat3v3float_uint_4 %44 None
          %69 = OpFunctionCall %float %a %68
-         %70 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %74 = OpLoad %v3float %70 None
-         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_1
-         %76 = OpLoad %v3float %75 None
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_2
-         %79 = OpLoad %v3float %77 None
-         %80 = OpCompositeConstruct %mat3v3float %74 %76 %79
-         %81 = OpFunctionCall %float %b %80
-         %82 = OpFAdd %float %69 %81
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %84 = OpLoad %v3float %83 None
-         %85 = OpVectorShuffle %v3float %84 %84 2 0 1
-         %86 = OpFunctionCall %float %c %85
-         %87 = OpFAdd %float %82 %86
-         %88 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %89 = OpLoad %v3float %88 None
-         %90 = OpVectorShuffle %v3float %89 %89 2 0 1
-         %91 = OpCompositeExtract %float %90 0
-         %92 = OpFunctionCall %float %d %91
-         %93 = OpFAdd %float %87 %92
-         %94 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %94 %93 None
+         %70 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %72 = OpLoad %v3float %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_1
+         %74 = OpLoad %v3float %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_2
+         %77 = OpLoad %v3float %75 None
+         %78 = OpCompositeConstruct %mat3v3float %72 %74 %77
+         %79 = OpFunctionCall %float %b %78
+         %80 = OpFAdd %float %69 %79
+         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %82 = OpLoad %v3float %81 None
+         %83 = OpVectorShuffle %v3float %82 %82 2 0 1
+         %84 = OpFunctionCall %float %c %83
+         %85 = OpFAdd %float %80 %84
+         %86 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %87 = OpLoad %v3float %86 None
+         %88 = OpVectorShuffle %v3float %87 %87 2 0 1
+         %89 = OpCompositeExtract %float %88 0
+         %90 = OpFunctionCall %float %d %89
+         %91 = OpFAdd %float %85 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.glsl
index 07d4011..b3f02ba 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.glsl
@@ -39,8 +39,8 @@
     }
   }
   p = v_3;
-  p[1] = mat3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2);
-  p[1][0] = v.inner[0].col1.zxy;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = mat3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2);
+  p[1u][0u] = v.inner[0u].col1.zxy;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 90ed4bd3..6690569 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float3x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(96u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(96u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 90ed4bd3..6690569 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float3x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(96u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(96u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.msl
index 46add22..d1ec10f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.ir.msl
@@ -47,11 +47,11 @@
   thread tint_array<float3x3, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_15 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_15 = (*tint_module_vars.u)[2u];
   float3 const v_16 = float3(v_15[0u].packed);
   float3 const v_17 = float3(v_15[1u].packed);
-  (*tint_module_vars.p)[1] = float3x3(v_16, v_17, float3(v_15[2u].packed));
-  (*tint_module_vars.p)[1][0] = float3((*tint_module_vars.u)[0][1].packed).zxy;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = float3x3(v_16, v_17, float3(v_15[2u].packed));
+  (*tint_module_vars.p)[1u][0u] = float3((*tint_module_vars.u)[0u][1u].packed).zxy;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.spvasm
index a9cea00..68df78d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 84
+; Bound: 80
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -60,13 +60,9 @@
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat3v3float = OpTypePointer Private %mat3v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -106,30 +102,30 @@
          %34 = OpLabel
          %51 = OpLoad %_arr_mat3v3float_uint_4 %28 None
                OpStore %p %51 None
-         %52 = OpAccessChain %_ptr_Private_mat3v3float %p %int_1
-         %56 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %59 = OpLoad %v3float %56 None
-         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %52 = OpAccessChain %_ptr_Private_mat3v3float %p %uint_1
+         %54 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %57 = OpLoad %v3float %54 None
+         %58 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %59 = OpLoad %v3float %58 None
+         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
          %61 = OpLoad %v3float %60 None
-         %62 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %64 = OpLoad %v3float %62 None
-         %65 = OpCompositeConstruct %mat3v3float %59 %61 %64
-               OpStore %52 %65 None
-         %66 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %70 = OpLoad %v3float %69 None
-         %71 = OpVectorShuffle %v3float %70 %70 2 0 1
-               OpStore %66 %71 None
-         %72 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %74 = OpAccessChain %_ptr_Uniform_float %73 %uint_0
-         %76 = OpLoad %float %74 None
-         %77 = OpAccessChain %_ptr_Private_float %72 %uint_0
-               OpStore %77 %76 None
-         %79 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Private_float %79 %uint_0
-         %81 = OpLoad %float %80 None
-         %82 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %82 %81 None
+         %62 = OpCompositeConstruct %mat3v3float %57 %59 %61
+               OpStore %52 %62 None
+         %63 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %65 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %66 = OpLoad %v3float %65 None
+         %67 = OpVectorShuffle %v3float %66 %66 2 0 1
+               OpStore %63 %67 None
+         %68 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_float %69 %uint_0
+         %72 = OpLoad %float %70 None
+         %73 = OpAccessChain %_ptr_Private_float %68 %uint_0
+               OpStore %73 %72 None
+         %75 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Private_float %75 %uint_0
+         %77 = OpLoad %float %76 None
+         %78 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %78 %77 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
index 86edab8..208806c 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -60,8 +60,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  mat3 v_8 = mat3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[1][0] = v.inner[0].col1.zxy;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  mat3 v_8 = mat3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[1u][0u] = v.inner[0u].col1.zxy;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.ir.msl
index 592c479..5770d70 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* u;
   device tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* s;
@@ -34,6 +37,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -69,10 +73,10 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* u [[buffer(0)]], device tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[2u];
   float3 const v_18 = float3(v_17[0u].packed);
   float3 const v_19 = float3(v_17[1u].packed);
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), float3x3(v_18, v_19, float3(v_17[2u].packed)));
-  (*tint_module_vars.s)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.s)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), float3x3(v_18, v_19, float3(v_17[2u].packed)));
+  (*tint_module_vars.s)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.s)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
index 18b8efa..25dbd6b 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -37,7 +40,8 @@
 
 void assign_and_preserve_padding(device tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* const dest, tint_array<float3x3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
index 9e93e0f..c8c515f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -65,17 +65,13 @@
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-      %int_1 = OpConstant %int 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %83 = OpTypeFunction %void %_arr_mat3v3float_uint_4
-        %102 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+         %78 = OpTypeFunction %void %_arr_mat3v3float_uint_4
+         %97 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %23 = OpVariable %_ptr_Function__arr_mat3x3_f32_std140_uint_4 Function
@@ -112,72 +108,71 @@
          %32 = OpLabel
          %49 = OpLoad %_arr_mat3v3float_uint_4 %25 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %56 = OpLoad %v3float %52 None
-         %57 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %58 = OpLoad %v3float %57 None
-         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %61 = OpLoad %v3float %59 None
-         %62 = OpCompositeConstruct %mat3v3float %56 %58 %61
-         %63 = OpBitcast %uint %int_1
-         %66 = OpCompositeConstruct %_arr_uint_uint_1 %63
-         %67 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %66 %62
-         %69 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %73 = OpLoad %v3float %72 None
-         %74 = OpVectorShuffle %v3float %73 %73 2 0 1
-               OpStore %69 %74 None
-         %75 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %77 = OpAccessChain %_ptr_Uniform_float %76 %uint_0
-         %79 = OpLoad %float %77 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_float %75 %uint_0
-               OpStore %80 %79 None
+         %52 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %55 = OpLoad %v3float %52 None
+         %56 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %57 = OpLoad %v3float %56 None
+         %58 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %59 = OpLoad %v3float %58 None
+         %60 = OpCompositeConstruct %mat3v3float %55 %57 %59
+         %62 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %63 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %62 %60
+         %65 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %68 = OpLoad %v3float %67 None
+         %69 = OpVectorShuffle %v3float %68 %68 2 0 1
+               OpStore %65 %69 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %72 = OpAccessChain %_ptr_Uniform_float %71 %uint_0
+         %74 = OpLoad %float %72 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_float %70 %uint_0
+               OpStore %75 %74 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %83
+%tint_store_and_preserve_padding = OpFunction %void None %78
 %value_param = OpFunctionParameter %_arr_mat3v3float_uint_4
+         %79 = OpLabel
+         %80 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function
+               OpStore %80 %value_param
+               OpBranch %81
+         %81 = OpLabel
+               OpBranch %84
          %84 = OpLabel
-         %85 = OpVariable %_ptr_Function__arr_mat3v3float_uint_4 Function
-               OpStore %85 %value_param
-               OpBranch %86
-         %86 = OpLabel
-               OpBranch %89
-         %89 = OpLabel
-         %91 = OpPhi %uint %uint_0 %86 %92 %88
-               OpLoopMerge %90 %88 None
-               OpBranch %87
-         %87 = OpLabel
-         %93 = OpUGreaterThanEqual %bool %91 %uint_4
-               OpSelectionMerge %94 None
-               OpBranchConditional %93 %95 %94
-         %95 = OpLabel
-               OpBranch %90
-         %94 = OpLabel
-         %96 = OpAccessChain %_ptr_Function_mat3v3float %85 %91
-         %97 = OpLoad %mat3v3float %96 None
-         %98 = OpCompositeConstruct %_arr_uint_uint_1 %91
-         %99 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %98 %97
-               OpBranch %88
-         %88 = OpLabel
-         %92 = OpIAdd %uint %91 %uint_1
-               OpBranch %89
+         %86 = OpPhi %uint %uint_0 %81 %87 %83
+               OpLoopMerge %85 %83 None
+               OpBranch %82
+         %82 = OpLabel
+         %88 = OpUGreaterThanEqual %bool %86 %uint_4
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
          %90 = OpLabel
+               OpBranch %85
+         %89 = OpLabel
+         %91 = OpAccessChain %_ptr_Function_mat3v3float %80 %86
+         %92 = OpLoad %mat3v3float %91 None
+         %93 = OpCompositeConstruct %_arr_uint_uint_1 %86
+         %94 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %93 %92
+               OpBranch %83
+         %83 = OpLabel
+         %87 = OpIAdd %uint %86 %uint_1
+               OpBranch %84
+         %85 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %102
+%tint_store_and_preserve_padding_0 = OpFunction %void None %97
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat3v3float
-        %103 = OpLabel
-        %104 = OpCompositeExtract %uint %target_indices 0
-        %105 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %104 %uint_0
-        %106 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %105 %106 None
-        %107 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %104 %uint_1
-        %108 = OpCompositeExtract %v3float %value_param_0 1
-               OpStore %107 %108 None
-        %109 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %104 %uint_2
-        %110 = OpCompositeExtract %v3float %value_param_0 2
-               OpStore %109 %110 None
+         %98 = OpLabel
+         %99 = OpCompositeExtract %uint %target_indices 0
+        %100 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %99 %uint_0
+        %101 = OpCompositeExtract %v3float %value_param_0 0
+               OpStore %100 %101 None
+        %102 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %99 %uint_1
+        %103 = OpCompositeExtract %v3float %value_param_0 1
+               OpStore %102 %103 None
+        %104 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %99 %uint_2
+        %105 = OpCompositeExtract %v3float %value_param_0 2
+               OpStore %104 %105 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.glsl
index ab037fb..585a6d3f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.glsl
@@ -50,9 +50,9 @@
     }
   }
   w = v_4;
-  w[1] = mat3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2);
-  w[1][0] = v.inner[0].col1.zxy;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = mat3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2);
+  w[1u][0u] = v.inner[0u].col1.zxy;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 106b597..edf09ed 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float3x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(96u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(96u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 106b597..edf09ed 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float3x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(96u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(96u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
index d15a906..5f6e52d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -23,6 +23,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4> tint_symbol;
 };
@@ -66,6 +69,7 @@
     uint v_15 = 0u;
     v_15 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_16 = v_15;
       if ((v_16 >= 4u)) {
         break;
@@ -81,15 +85,15 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_17 = (*tint_module_vars.u)[2u];
   float3 const v_18 = float3(v_17[0u].packed);
   float3 const v_19 = float3(v_17[1u].packed);
   float3x3 const v_20 = float3x3(v_18, v_19, float3(v_17[2u].packed));
-  (*tint_module_vars.w)[1][0u].packed = packed_float3(v_20[0u]);
-  (*tint_module_vars.w)[1][1u].packed = packed_float3(v_20[1u]);
-  (*tint_module_vars.w)[1][2u].packed = packed_float3(v_20[2u]);
-  (*tint_module_vars.w)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.w)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(v_20[0u]);
+  (*tint_module_vars.w)[1u][1u].packed = packed_float3(v_20[1u]);
+  (*tint_module_vars.w)[1u][2u].packed = packed_float3(v_20[2u]);
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.w)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_21 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.msl
index 104fdbe..91fb2d9 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = tint_pack_vec3_in_composite(float3x3(float3(0.0f), float3(0.0f), float3(0.0f)));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
index fe84450..c33c5be 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 98
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -59,15 +59,11 @@
          %47 = OpConstantNull %_arr_mat3v3float_uint_4
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
 %_ptr_Function_mat3x3_f32_std140 = OpTypePointer Function %mat3x3_f32_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %94 = OpTypeFunction %void
+         %90 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -127,31 +123,31 @@
          %52 = OpLabel
          %67 = OpLoad %_arr_mat3v3float_uint_4 %45 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_mat3v3float %w %int_1
-         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %74 = OpLoad %v3float %71 None
-         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %76 = OpLoad %v3float %75 None
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %78 = OpLoad %v3float %77 None
-         %79 = OpCompositeConstruct %mat3v3float %74 %76 %78
-               OpStore %68 %79 None
-         %80 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %84 = OpLoad %v3float %83 None
-         %85 = OpVectorShuffle %v3float %84 %84 2 0 1
-               OpStore %80 %85 None
-         %86 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %88 = OpAccessChain %_ptr_Uniform_float %87 %uint_0
-         %90 = OpLoad %float %88 None
-         %91 = OpAccessChain %_ptr_Workgroup_float %86 %uint_0
-               OpStore %91 %90 None
+         %68 = OpAccessChain %_ptr_Workgroup_mat3v3float %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %71 = OpLoad %v3float %69 None
+         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %73 = OpLoad %v3float %72 None
+         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %75 = OpLoad %v3float %74 None
+         %76 = OpCompositeConstruct %mat3v3float %71 %73 %75
+               OpStore %68 %76 None
+         %77 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %80 = OpLoad %v3float %79 None
+         %81 = OpVectorShuffle %v3float %80 %80 2 0 1
+               OpStore %77 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %84 = OpAccessChain %_ptr_Uniform_float %83 %uint_0
+         %86 = OpLoad %float %84 None
+         %87 = OpAccessChain %_ptr_Workgroup_float %82 %uint_0
+               OpStore %87 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index cd11ad4..3931e11 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -32,10 +32,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float3x4 l_a[4] = a_load(0u);
-  float3x4 l_a_i = a_load_1((48u * uint(p_a_i_save)));
-  const uint scalar_offset_3 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float3x4 l_a_i = a_load_1((48u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_3 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_3 / 4]);
-  const uint scalar_offset_4 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_4 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index cd11ad4..3931e11 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -32,10 +32,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float3x4 l_a[4] = a_load(0u);
-  float3x4 l_a_i = a_load_1((48u * uint(p_a_i_save)));
-  const uint scalar_offset_3 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float3x4 l_a_i = a_load_1((48u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_3 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_3 / 4]);
-  const uint scalar_offset_4 = (((48u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_4 = (((48u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 2u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 295ced6..84cc948 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,10 +15,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
-  int v_3 = i();
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 2u);
   mat3x4 l_a[4] = v.inner;
   mat3x4 l_a_i = v.inner[v_2];
   vec4 l_a_i_i = v.inner[v_2][v_3];
-  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 7d36075..42b4e3d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (48u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (48u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 2u)));
   float3x4 l_a[4] = v_1(0u);
   float3x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 7d36075..42b4e3d 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (48u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (48u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 2u)));
   float3x4 l_a[4] = v_1(0u);
   float3x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 33ad6f1..5942c3a 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<float3x4, 4>* const p_a = tint_module_vars.a;
-  const constant float3x4* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant float4* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant float3x4* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant float4* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 2u)]);
   tint_array<float3x4, 4> const l_a = (*p_a);
   float3x4 const l_a_i = (*p_a_i);
   float4 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index b49a569..e77ccb9 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 2u);
   tint_array<float3x4, 4> const l_a = *(tint_symbol_2);
   float3x4 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   float4 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 23d22dd..b95fd2c 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,7 +56,9 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat3v4float_uint_4 = OpTypePointer Uniform %_arr_mat3v4float_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -71,21 +74,25 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat3v4float_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_mat3v4float %p_a %31
-         %34 = OpFunctionCall %int %i
-    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %34
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_mat3v4float %p_a %33
+         %38 = OpFunctionCall %int %i
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %34 UMin %39 %uint_2
+    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %40
         %l_a = OpLoad %_arr_mat3v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat3v4float %p_a_i None
     %l_a_i_i = OpLoad %v4float %p_a_i_i None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpCompositeExtract %float %l_a 0 0 0
-         %44 = OpFAdd %float %42 %43
-         %45 = OpCompositeExtract %float %l_a_i 0 0
-         %46 = OpFAdd %float %44 %45
-         %47 = OpCompositeExtract %float %l_a_i_i 0
-         %48 = OpFAdd %float %46 %47
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %47 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
+         %49 = OpLoad %float %47 None
+         %50 = OpCompositeExtract %float %l_a 0 0 0
+         %51 = OpFAdd %float %49 %50
+         %52 = OpCompositeExtract %float %l_a_i 0 0
+         %53 = OpFAdd %float %51 %52
+         %54 = OpCompositeExtract %float %l_a_i_i 0
+         %55 = OpFAdd %float %53 %54
+         %56 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
index fb61b14..394fdf8 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3x4 l_a[4] = v.inner;
-  mat3x4 l_a_i = v.inner[2];
-  vec4 l_a_i_i = v.inner[2][1];
-  v_1.inner = (((v.inner[2][1].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  mat3x4 l_a_i = v.inner[2u];
+  vec4 l_a_i_i = v.inner[2u][1u];
+  v_1.inner = (((v.inner[2u][1u].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 1a3fc8c..a6c881f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float3x4 l_a[4] = v_1(0u);
   float3x4 l_a_i = v(96u);
   float4 l_a_i_i = asfloat(a[7u]);
-  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 1a3fc8c..a6c881f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float3x4 l_a[4] = v_1(0u);
   float3x4 l_a_i = v(96u);
   float4 l_a_i_i = asfloat(a[7u]);
-  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[7u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 01f31d5f..0f8bff2 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<float3x4, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<float3x4, 4>* const p_a = tint_module_vars.a;
-  const constant float3x4* const p_a_2 = (&(*p_a)[2]);
-  const constant float4* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant float3x4* const p_a_2 = (&(*p_a)[2u]);
+  const constant float4* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<float3x4, 4> const l_a = (*p_a);
   float3x4 const l_a_i = (*p_a_2);
   float4 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index d00ced6..393a409 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -48,29 +48,28 @@
 %_ptr_Uniform__arr_mat3v4float_uint_4 = OpTypePointer Uniform %_arr_mat3v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat3v4float_uint_4 %1 %uint_0
-      %p_a_2 = OpAccessChain %_ptr_Uniform_mat3v4float %p_a %int_2
-    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %int_1
+      %p_a_2 = OpAccessChain %_ptr_Uniform_mat3v4float %p_a %uint_2
+    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %uint_1
         %l_a = OpLoad %_arr_mat3v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat3v4float %p_a_2 None
     %l_a_i_i = OpLoad %v4float %p_a_2_1 None
-         %30 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
-         %32 = OpLoad %float %30 None
-         %33 = OpCompositeExtract %float %l_a 0 0 0
-         %34 = OpFAdd %float %32 %33
-         %35 = OpCompositeExtract %float %l_a_i 0 0
-         %36 = OpFAdd %float %34 %35
-         %37 = OpCompositeExtract %float %l_a_i_i 0
-         %38 = OpFAdd %float %36 %37
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %39 %38 None
+         %29 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
+         %31 = OpLoad %float %29 None
+         %32 = OpCompositeExtract %float %l_a 0 0 0
+         %33 = OpFAdd %float %31 %32
+         %34 = OpCompositeExtract %float %l_a_i 0 0
+         %35 = OpFAdd %float %33 %34
+         %36 = OpCompositeExtract %float %l_a_i_i 0
+         %37 = OpFAdd %float %35 %36
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.glsl
index 316df50..692d42b 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.glsl
@@ -10,9 +10,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x3 t = transpose(v.inner[2]);
-  float l = length(v.inner[0][1].ywxz);
-  float a = abs(v.inner[0][1].ywxz[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat4x3 t = transpose(v.inner[2u]);
+  float l = length(v.inner[0u][1u].ywxz);
+  float a = abs(v.inner[0u][1u].ywxz[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 4a82d5f..e04c865 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float4x3 t = transpose(v(96u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 4a82d5f..e04c865 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float4x3 t = transpose(v(96u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
index 58361b7..ca2488b 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<float3x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  float4x3 const t = transpose((*tint_module_vars.u)[2]);
-  float const l = length((*tint_module_vars.u)[0][1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0][1].ywxz[0u]);
-  float const v = (t[0][0u] + float(l));
+  float4x3 const t = transpose((*tint_module_vars.u)[2u]);
+  float const l = length((*tint_module_vars.u)[0u][1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u][1u].ywxz[0u]);
+  float const v = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.spvasm
index a70a2c7..f29b1f0 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
-         %33 = OpExtInstImport "GLSL.std.450"
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -45,32 +45,30 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2
-         %22 = OpLoad %mat3v4float %17 None
-          %t = OpTranspose %mat4v3float %22
-         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %30 = OpLoad %v4float %26 None
-         %31 = OpVectorShuffle %v4float %30 %30 1 3 0 2
-          %l = OpExtInst %float %33 Length %31
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %35 = OpLoad %v4float %34 None
-         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
-         %37 = OpCompositeExtract %float %36 0
-          %a = OpExtInst %float %33 FAbs %37
-         %39 = OpCompositeExtract %float %t 0 0
-         %40 = OpFAdd %float %39 %l
-         %41 = OpFAdd %float %40 %a
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %42 %41 None
+         %17 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2
+         %21 = OpLoad %mat3v4float %17 None
+          %t = OpTranspose %mat4v3float %21
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %28 = OpLoad %v4float %25 None
+         %29 = OpVectorShuffle %v4float %28 %28 1 3 0 2
+          %l = OpExtInst %float %31 Length %29
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %33 = OpLoad %v4float %32 None
+         %34 = OpVectorShuffle %v4float %33 %33 1 3 0 2
+         %35 = OpCompositeExtract %float %34 0
+          %a = OpExtInst %float %31 FAbs %35
+         %37 = OpCompositeExtract %float %t 0 0
+         %38 = OpFAdd %float %37 %l
+         %39 = OpFAdd %float %38 %a
+         %40 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.glsl
index b3acfe9..5ba2e41 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.glsl
@@ -9,10 +9,10 @@
   float inner;
 } v_2;
 float a(mat3x4 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat3x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec4 v) {
   return v[0u];
@@ -23,7 +23,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   float v_3 = a(v_1.inner);
-  float v_4 = (v_3 + b(v_1.inner[1]));
-  float v_5 = (v_4 + c(v_1.inner[1][0].ywxz));
-  v_2.inner = (v_5 + d(v_1.inner[1][0].ywxz[0u]));
+  float v_4 = (v_3 + b(v_1.inner[1u]));
+  float v_5 = (v_4 + c(v_1.inner[1u][0u].ywxz));
+  v_2.inner = (v_5 + d(v_1.inner[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index 36e6d94..24979b0 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float3x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float3x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index 36e6d94..24979b0 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float3x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float3x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.msl
index 4978604..2bece44 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 float a(tint_array<float3x4, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float3x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float4 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<float3x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_1 = a((*tint_module_vars.u));
-  float const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  float const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].ywxz));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].ywxz[0u]));
+  float const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  float const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].ywxz));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.spvasm
index f386216..5543c7f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -54,10 +54,8 @@
 %_ptr_Uniform__arr_mat3v4float_uint_4 = OpTypePointer Uniform %_arr_mat3v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %15
         %a_0 = OpFunctionParameter %_arr_mat3v4float_uint_4
@@ -87,22 +85,22 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_mat3v4float_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_mat3v4float_uint_4 %36 None
          %40 = OpFunctionCall %float %a %39
-         %41 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_1
-         %45 = OpLoad %mat3v4float %41 None
-         %46 = OpFunctionCall %float %b %45
-         %47 = OpFAdd %float %40 %46
-         %48 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %51 = OpLoad %v4float %48 None
-         %52 = OpVectorShuffle %v4float %51 %51 1 3 0 2
-         %53 = OpFunctionCall %float %c %52
-         %54 = OpFAdd %float %47 %53
-         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %56 = OpLoad %v4float %55 None
-         %57 = OpVectorShuffle %v4float %56 %56 1 3 0 2
-         %58 = OpCompositeExtract %float %57 0
-         %59 = OpFunctionCall %float %d %58
-         %60 = OpFAdd %float %54 %59
-         %61 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %61 %60 None
+         %41 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %mat3v4float %41 None
+         %45 = OpFunctionCall %float %b %44
+         %46 = OpFAdd %float %40 %45
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+         %51 = OpFunctionCall %float %c %50
+         %52 = OpFAdd %float %46 %51
+         %53 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %54 = OpLoad %v4float %53 None
+         %55 = OpVectorShuffle %v4float %54 %54 1 3 0 2
+         %56 = OpCompositeExtract %float %55 0
+         %57 = OpFunctionCall %float %d %56
+         %58 = OpFAdd %float %52 %57
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.glsl
index 63fcd15..82b2bdc 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.glsl
@@ -12,8 +12,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[1][0] = v.inner[0][1].ywxz;
-  p[1][0][0u] = v.inner[0][1].x;
-  v_1.inner = p[1][0].x;
+  p[1u] = v.inner[2u];
+  p[1u][0u] = v.inner[0u][1u].ywxz;
+  p[1u][0u][0u] = v.inner[0u][1u].x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index bd09db8..5b438aa 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float3x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(96u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(96u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index bd09db8..5b438aa 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float3x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(96u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(96u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.msl
index 672922c..bc25b12 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<float3x4, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.spvasm
index a7cc524..be36298 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,12 +46,10 @@
 %_ptr_Uniform__arr_mat3v4float_uint_4 = OpTypePointer Uniform %_arr_mat3v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_mat3v4float = OpTypePointer Private %mat3v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
@@ -61,25 +59,25 @@
          %20 = OpAccessChain %_ptr_Uniform__arr_mat3v4float_uint_4 %1 %uint_0
          %23 = OpLoad %_arr_mat3v4float_uint_4 %20 None
                OpStore %p %23 None
-         %24 = OpAccessChain %_ptr_Private_mat3v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2
-         %31 = OpLoad %mat3v4float %28 None
-               OpStore %24 %31 None
-         %32 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %37 = OpLoad %v4float %35 None
-         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
-               OpStore %32 %38 None
-         %39 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
-         %43 = OpLoad %float %41 None
-         %44 = OpAccessChain %_ptr_Private_float %39 %uint_0
-               OpStore %44 %43 None
-         %46 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %47 = OpAccessChain %_ptr_Private_float %46 %uint_0
-         %48 = OpLoad %float %47 None
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %24 = OpAccessChain %_ptr_Private_mat3v4float %p %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2
+         %30 = OpLoad %mat3v4float %27 None
+               OpStore %24 %30 None
+         %31 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %33 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %35 = OpLoad %v4float %33 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+               OpStore %31 %36 None
+         %37 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpAccessChain %_ptr_Private_float %37 %uint_0
+               OpStore %42 %41 None
+         %44 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %45 = OpAccessChain %_ptr_Private_float %44 %uint_0
+         %46 = OpLoad %float %45 None
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.glsl
index c8aceb8..f7939b2 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[2];
-  v_1.inner[1][0] = v.inner[0][1].ywxz;
-  v_1.inner[1][0][0u] = v.inner[0][1].x;
+  v_1.inner[1u] = v.inner[2u];
+  v_1.inner[1u][0u] = v.inner[0u][1u].ywxz;
+  v_1.inner[1u][0u][0u] = v.inner[0u][1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.ir.msl
index 401544d..c1c6e3f 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<float3x4, 4>* u [[buffer(0)]], device tint_array<float3x4, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.spvasm
index 5462040..f876e31 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,12 +45,10 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer__arr_mat3v4float_uint_4 = OpTypePointer StorageBuffer %_arr_mat3v4float_uint_4
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -60,20 +58,20 @@
          %20 = OpLoad %_arr_mat3v4float_uint_4 %17 None
          %21 = OpAccessChain %_ptr_StorageBuffer__arr_mat3v4float_uint_4 %10 %uint_0
                OpStore %21 %20 None
-         %23 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %10 %uint_0 %int_1
-         %27 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2
-         %30 = OpLoad %mat3v4float %27 None
-               OpStore %23 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %36 = OpLoad %v4float %34 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-               OpStore %31 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %38 %uint_0
-               OpStore %43 %42 None
+         %23 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %10 %uint_0 %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2
+         %29 = OpLoad %mat3v4float %26 None
+               OpStore %23 %29 None
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %34 = OpLoad %v4float %32 None
+         %35 = OpVectorShuffle %v4float %34 %34 1 3 0 2
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_float %37 %uint_0
+         %40 = OpLoad %float %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %36 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.glsl
index 8bef166..8b7e273 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.glsl
@@ -23,9 +23,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[1][0] = v.inner[0][1].ywxz;
-  w[1][0][0u] = v.inner[0][1].x;
+  w[1u] = v.inner[2u];
+  w[1u][0u] = v.inner[0u][1u].ywxz;
+  w[1u][0u][0u] = v.inner[0u][1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index a3e17e0..9ab69ee 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float3x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(96u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(96u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index a3e17e0..9ab69ee 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float3x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(96u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(96u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
index ab712f0..1d6267c 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<float3x4, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<float3x4, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<float3x4, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.msl
index 8a36f48..c629971 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<float3x4, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<float3x4, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = float3x4(float4(0.0f), float4(0.0f), float4(0.0f));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
index 4304a2b..efe45fd 100644
--- a/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,16 +46,12 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_mat3v4float_uint_4 = OpTypePointer Uniform %_arr_mat3v4float_uint_4
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %63 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
     %f_inner = OpFunction %void None %17
 %tint_local_index = OpFunctionParameter %uint
          %18 = OpLabel
@@ -84,26 +80,26 @@
          %37 = OpAccessChain %_ptr_Uniform__arr_mat3v4float_uint_4 %1 %uint_0
          %40 = OpLoad %_arr_mat3v4float_uint_4 %37 None
                OpStore %w %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_mat3v4float %w %int_1
-         %44 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2
-         %47 = OpLoad %mat3v4float %44 None
-               OpStore %41 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %53 = OpLoad %v4float %51 None
-         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
-               OpStore %48 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_float %56 %uint_0
-         %59 = OpLoad %float %57 None
-         %60 = OpAccessChain %_ptr_Workgroup_float %55 %uint_0
-               OpStore %60 %59 None
+         %41 = OpAccessChain %_ptr_Workgroup_mat3v4float %w %uint_1
+         %42 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2
+         %44 = OpLoad %mat3v4float %42 None
+               OpStore %41 %44 None
+         %45 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+               OpStore %45 %50 None
+         %51 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %52 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_float %52 %uint_0
+         %55 = OpLoad %float %53 None
+         %56 = OpAccessChain %_ptr_Workgroup_float %51 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpLoad %uint %f_local_invocation_index_Input None
+         %62 = OpFunctionCall %void %f_inner %61
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4410d60..d2a1589 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -37,11 +37,11 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   matrix<float16_t, 4, 2> l_a[4] = a_load(0u);
-  matrix<float16_t, 4, 2> l_a_i = a_load_1((16u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((16u * uint(p_a_i_save)) + (4u * uint(p_a_i_i_save)))) / 4;
+  matrix<float16_t, 4, 2> l_a_i = a_load_1((16u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((16u * min(uint(p_a_i_save), 3u)) + (4u * min(uint(p_a_i_i_save), 3u)))) / 4;
   uint ubo_load_4 = a[scalar_offset_4 / 4][scalar_offset_4 % 4];
   vector<float16_t, 2> l_a_i_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_4 & 0xFFFF)), float16_t(f16tof32(ubo_load_4 >> 16)));
-  const uint scalar_offset_bytes = (((16u * uint(p_a_i_save)) + (4u * uint(p_a_i_i_save))));
+  const uint scalar_offset_bytes = (((16u * min(uint(p_a_i_save), 3u)) + (4u * min(uint(p_a_i_i_save), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   s.Store<float16_t>(0u, (((float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF))) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x));
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 5cd179a..9449a7b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -24,9 +24,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   f16mat4x2 v_3 = f16mat4x2(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2, v.inner[v_2].col3);
-  f16vec2 v_4 = v_3[i()];
+  f16vec2 v_4 = v_3[min(uint(i()), 3u)];
   mat4x2_f16_std140 v_5[4] = v.inner;
   f16mat4x2 v_6[4] = f16mat4x2[4](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
   {
@@ -47,5 +47,5 @@
   f16mat4x2 l_a[4] = v_6;
   f16mat4x2 l_a_i = v_3;
   f16vec2 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 6920906..a67b282 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -48,12 +48,12 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_10 = (16u * uint(i()));
-  uint v_11 = (4u * uint(i()));
+  uint v_10 = (16u * uint(min(uint(i()), 3u)));
+  uint v_11 = (4u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 2> l_a[4] = v_6(0u);
   matrix<float16_t, 4, 2> l_a_i = v_2(v_10);
   vector<float16_t, 2> l_a_i_i = tint_bitcast_to_f16(a[((v_10 + v_11) / 16u)][(((v_10 + v_11) % 16u) / 4u)]);
   uint v_12 = a[((v_10 + v_11) / 16u)][(((v_10 + v_11) % 16u) / 4u)];
-  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_12 >> (((((v_10 + v_11) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_12 >> (((((v_10 + v_11) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 3184a3b..4da315b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<half4x2, 4>* const p_a = tint_module_vars.a;
-  const constant half4x2* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant half2* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant half4x2* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant half2* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<half4x2, 4> const l_a = (*p_a);
   half4x2 const l_a_i = (*p_a_i);
   half2 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 4133401..5a2dad1 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<half4x2, 4> const l_a = *(tint_symbol_2);
   half4x2 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   half2 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 6e1cd5e..188122b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -63,17 +64,17 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4x2_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x2_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_v2half = OpTypePointer Function %v2half
 %_ptr_Function__arr_mat4x2_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x2_f16_std140_uint_4
 %_arr_mat4v2half_uint_4 = OpTypeArray %mat4v2half %uint_4
 %_ptr_Function__arr_mat4v2half_uint_4 = OpTypePointer Function %_arr_mat4v2half_uint_4
-         %58 = OpConstantNull %_arr_mat4v2half_uint_4
+         %63 = OpConstantNull %_arr_mat4v2half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -87,63 +88,67 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat4v2half Function
-         %53 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_mat4v2half_uint_4 Function %58
+         %49 = OpVariable %_ptr_Function_mat4v2half Function
+         %58 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_4 Function
+         %60 = OpVariable %_ptr_Function__arr_mat4v2half_uint_4 Function %63
          %28 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f16_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v2half %28 %31 %uint_0
-         %34 = OpLoad %v2half %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v2half %28 %31 %uint_1
-         %37 = OpLoad %v2half %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v2half %28 %31 %uint_2
-         %40 = OpLoad %v2half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2half %28 %31 %uint_3
-         %43 = OpLoad %v2half %41 None
-      %l_a_i = OpCompositeConstruct %mat4v2half %34 %37 %40 %43
-               OpStore %46 %l_a_i
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v2half %46 %48
-    %l_a_i_i = OpLoad %v2half %49 None
-         %52 = OpLoad %_arr_mat4x2_f16_std140_uint_4 %28 None
-               OpStore %53 %52
-               OpBranch %59
-         %59 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-         %64 = OpPhi %uint %uint_0 %59 %65 %61
-               OpLoopMerge %63 %61 None
-               OpBranch %60
-         %60 = OpLabel
-         %66 = OpUGreaterThanEqual %bool %64 %uint_4
-               OpSelectionMerge %68 None
-               OpBranchConditional %66 %69 %68
-         %69 = OpLabel
-               OpBranch %63
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v2half %28 %33 %uint_0
+         %38 = OpLoad %v2half %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v2half %28 %33 %uint_1
+         %41 = OpLoad %v2half %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v2half %28 %33 %uint_2
+         %44 = OpLoad %v2half %42 None
+         %45 = OpAccessChain %_ptr_Uniform_v2half %28 %33 %uint_3
+         %46 = OpLoad %v2half %45 None
+      %l_a_i = OpCompositeConstruct %mat4v2half %38 %41 %44 %46
+               OpStore %49 %l_a_i
+         %51 = OpFunctionCall %int %i
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %34 UMin %52 %uint_3
+         %54 = OpAccessChain %_ptr_Function_v2half %49 %53
+    %l_a_i_i = OpLoad %v2half %54 None
+         %57 = OpLoad %_arr_mat4x2_f16_std140_uint_4 %28 None
+               OpStore %58 %57
+               OpBranch %64
+         %64 = OpLabel
+               OpBranch %67
+         %67 = OpLabel
+         %69 = OpPhi %uint %uint_0 %64 %70 %66
+               OpLoopMerge %68 %66 None
+               OpBranch %65
+         %65 = OpLabel
+         %71 = OpUGreaterThanEqual %bool %69 %uint_4
+               OpSelectionMerge %73 None
+               OpBranchConditional %71 %74 %73
+         %74 = OpLabel
+               OpBranch %68
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Function_mat4v2half %60 %69
+         %76 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %58 %69
+         %78 = OpLoad %mat4x2_f16_std140 %76 None
+         %79 = OpCompositeExtract %v2half %78 0
+         %80 = OpCompositeExtract %v2half %78 1
+         %81 = OpCompositeExtract %v2half %78 2
+         %82 = OpCompositeExtract %v2half %78 3
+         %83 = OpCompositeConstruct %mat4v2half %79 %80 %81 %82
+               OpStore %75 %83 None
+               OpBranch %66
+         %66 = OpLabel
+         %70 = OpIAdd %uint %69 %uint_1
+               OpBranch %67
          %68 = OpLabel
-         %70 = OpAccessChain %_ptr_Function_mat4v2half %55 %64
-         %71 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %53 %64
-         %73 = OpLoad %mat4x2_f16_std140 %71 None
-         %74 = OpCompositeExtract %v2half %73 0
-         %75 = OpCompositeExtract %v2half %73 1
-         %76 = OpCompositeExtract %v2half %73 2
-         %77 = OpCompositeExtract %v2half %73 3
-         %78 = OpCompositeConstruct %mat4v2half %74 %75 %76 %77
-               OpStore %70 %78 None
-               OpBranch %61
-         %61 = OpLabel
-         %65 = OpIAdd %uint %64 %uint_1
-               OpBranch %62
-         %63 = OpLabel
-        %l_a = OpLoad %_arr_mat4v2half_uint_4 %55 None
-         %80 = OpCompositeExtract %half %l_a_i_i 0
-         %81 = OpCompositeExtract %half %l_a 0 0 0
-         %82 = OpFAdd %half %80 %81
-         %83 = OpCompositeExtract %half %l_a_i 0 0
-         %84 = OpFAdd %half %82 %83
+        %l_a = OpLoad %_arr_mat4v2half_uint_4 %60 None
          %85 = OpCompositeExtract %half %l_a_i_i 0
-         %86 = OpFAdd %half %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %87 %86 None
+         %86 = OpCompositeExtract %half %l_a 0 0 0
+         %87 = OpFAdd %half %85 %86
+         %88 = OpCompositeExtract %half %l_a_i 0 0
+         %89 = OpFAdd %half %87 %88
+         %90 = OpCompositeExtract %half %l_a_i_i 0
+         %91 = OpFAdd %half %89 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 546fede..89115e9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -19,7 +19,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x2 v_2 = f16mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
+  f16mat4x2 v_2 = f16mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
   mat4x2_f16_std140 v_3[4] = v.inner;
   f16mat4x2 v_4[4] = f16mat4x2[4](f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)), f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf)));
   {
@@ -39,6 +39,6 @@
   }
   f16mat4x2 l_a[4] = v_4;
   f16mat4x2 l_a_i = v_2;
-  f16vec2 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  f16vec2 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index d98a175..a6ac73a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -45,6 +45,6 @@
   matrix<float16_t, 4, 2> l_a[4] = v_6(0u);
   matrix<float16_t, 4, 2> l_a_i = v_2(32u);
   vector<float16_t, 2> l_a_i_i = tint_bitcast_to_f16(a[2u].y);
-  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].y)) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[2u].y)) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 245cac6..202a798 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<half4x2, 4>* a [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<half4x2, 4>* const p_a = tint_module_vars.a;
-  const constant half4x2* const p_a_2 = (&(*p_a)[2]);
-  const constant half2* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant half4x2* const p_a_2 = (&(*p_a)[2u]);
+  const constant half2* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<half4x2, 4> const l_a = (*p_a);
   half4x2 const l_a_i = (*p_a_2);
   half2 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
index 3eefe6e..f6f817f 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -56,74 +56,72 @@
 %_ptr_Uniform__arr_mat4x2_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x2_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
 %_ptr_Function__arr_mat4x2_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x2_f16_std140_uint_4
 %_arr_mat4v2half_uint_4 = OpTypeArray %mat4v2half %uint_4
 %_ptr_Function__arr_mat4v2half_uint_4 = OpTypePointer Function %_arr_mat4v2half_uint_4
-         %43 = OpConstantNull %_arr_mat4v2half_uint_4
+         %41 = OpConstantNull %_arr_mat4v2half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_mat4v2half_uint_4 Function %43
+         %36 = OpVariable %_ptr_Function__arr_mat4x2_f16_std140_uint_4 Function
+         %38 = OpVariable %_ptr_Function__arr_mat4v2half_uint_4 Function %41
          %17 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f16_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v2half %17 %int_2 %uint_0
-         %24 = OpLoad %v2half %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v2half %17 %int_2 %uint_1
-         %27 = OpLoad %v2half %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v2half %17 %int_2 %uint_2
-         %30 = OpLoad %v2half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2half %17 %int_2 %uint_3
-         %33 = OpLoad %v2half %31 None
-      %l_a_i = OpCompositeConstruct %mat4v2half %24 %27 %30 %33
+         %20 = OpAccessChain %_ptr_Uniform_v2half %17 %uint_2 %uint_0
+         %23 = OpLoad %v2half %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v2half %17 %uint_2 %uint_1
+         %26 = OpLoad %v2half %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v2half %17 %uint_2 %uint_2
+         %28 = OpLoad %v2half %27 None
+         %29 = OpAccessChain %_ptr_Uniform_v2half %17 %uint_2 %uint_3
+         %31 = OpLoad %v2half %29 None
+      %l_a_i = OpCompositeConstruct %mat4v2half %23 %26 %28 %31
     %l_a_i_i = OpCompositeExtract %v2half %l_a_i 1
-         %37 = OpLoad %_arr_mat4x2_f16_std140_uint_4 %17 None
-               OpStore %38 %37
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-         %49 = OpPhi %uint %uint_0 %44 %50 %46
-               OpLoopMerge %48 %46 None
+         %35 = OpLoad %_arr_mat4x2_f16_std140_uint_4 %17 None
+               OpStore %36 %35
+               OpBranch %42
+         %42 = OpLabel
                OpBranch %45
          %45 = OpLabel
-         %51 = OpUGreaterThanEqual %bool %49 %uint_4
-               OpSelectionMerge %53 None
-               OpBranchConditional %51 %54 %53
-         %54 = OpLabel
-               OpBranch %48
-         %53 = OpLabel
-         %55 = OpAccessChain %_ptr_Function_mat4v2half %40 %49
-         %57 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %38 %49
-         %59 = OpLoad %mat4x2_f16_std140 %57 None
-         %60 = OpCompositeExtract %v2half %59 0
-         %61 = OpCompositeExtract %v2half %59 1
-         %62 = OpCompositeExtract %v2half %59 2
-         %63 = OpCompositeExtract %v2half %59 3
-         %64 = OpCompositeConstruct %mat4v2half %60 %61 %62 %63
-               OpStore %55 %64 None
+         %47 = OpPhi %uint %uint_0 %42 %48 %44
+               OpLoopMerge %46 %44 None
+               OpBranch %43
+         %43 = OpLabel
+         %49 = OpUGreaterThanEqual %bool %47 %uint_4
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %52 %51
+         %52 = OpLabel
                OpBranch %46
+         %51 = OpLabel
+         %53 = OpAccessChain %_ptr_Function_mat4v2half %38 %47
+         %55 = OpAccessChain %_ptr_Function_mat4x2_f16_std140 %36 %47
+         %57 = OpLoad %mat4x2_f16_std140 %55 None
+         %58 = OpCompositeExtract %v2half %57 0
+         %59 = OpCompositeExtract %v2half %57 1
+         %60 = OpCompositeExtract %v2half %57 2
+         %61 = OpCompositeExtract %v2half %57 3
+         %62 = OpCompositeConstruct %mat4v2half %58 %59 %60 %61
+               OpStore %53 %62 None
+               OpBranch %44
+         %44 = OpLabel
+         %48 = OpIAdd %uint %47 %uint_1
+               OpBranch %45
          %46 = OpLabel
-         %50 = OpIAdd %uint %49 %uint_1
-               OpBranch %47
-         %48 = OpLabel
-        %l_a = OpLoad %_arr_mat4v2half_uint_4 %40 None
-         %66 = OpCompositeExtract %half %l_a_i_i 0
-         %67 = OpCompositeExtract %half %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat4v2half_uint_4 %38 None
+         %64 = OpCompositeExtract %half %l_a_i_i 0
+         %65 = OpCompositeExtract %half %l_a 0 0 0
+         %66 = OpFAdd %half %64 %65
+         %67 = OpCompositeExtract %half %l_a_i 0 0
          %68 = OpFAdd %half %66 %67
-         %69 = OpCompositeExtract %half %l_a_i 0 0
+         %69 = OpCompositeExtract %half %l_a_i_i 0
          %70 = OpFAdd %half %68 %69
-         %71 = OpCompositeExtract %half %l_a_i_i 0
-         %72 = OpFAdd %half %70 %71
-         %73 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %73 %72 None
+         %71 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %71 %70 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.glsl
index 2e4172f..a3b44c6 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.glsl
@@ -19,9 +19,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x4 t = transpose(f16mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3));
-  float16_t l = length(v.inner[0].col1.yx);
-  float16_t a = abs(v.inner[0].col1.yx[0u]);
-  float16_t v_2 = (t[0][0u] + float16_t(l));
+  f16mat2x4 t = transpose(f16mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3));
+  float16_t l = length(v.inner[0u].col1.yx);
+  float16_t a = abs(v.inner[0u].col1.yx[0u]);
+  float16_t v_2 = (t[0u][0u] + float16_t(l));
   v_1.inner = (v_2 + float16_t(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
index d8308d8..c474d9a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
   matrix<float16_t, 2, 4> t = transpose(v_2(32u));
   float16_t l = length(tint_bitcast_to_f16(u[0u].y).yx);
   float16_t a = abs(tint_bitcast_to_f16(u[0u].y).yx.x);
-  float16_t v_6 = (t[int(0)].x + float16_t(l));
+  float16_t v_6 = (t[0u].x + float16_t(l));
   s.Store<float16_t>(0u, (v_6 + float16_t(a)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
index 5eb824c..3d1a729 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<half4x2, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  half2x4 const t = transpose((*tint_module_vars.u)[2]);
-  half const l = length((*tint_module_vars.u)[0][1].yx);
-  half const a = abs((*tint_module_vars.u)[0][1].yx[0u]);
-  half const v = (t[0][0u] + half(l));
+  half2x4 const t = transpose((*tint_module_vars.u)[2u]);
+  half const l = length((*tint_module_vars.u)[0u][1u].yx);
+  half const a = abs((*tint_module_vars.u)[0u][1u].yx[0u]);
+  half const v = (t[0u][0u] + half(l));
   (*tint_module_vars.s) = (v + half(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.spvasm
index 82995c1..987afc2 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 53
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %42 = OpExtInstImport "GLSL.std.450"
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,41 +55,38 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
      %v4half = OpTypeVector %half 4
  %mat2v4half = OpTypeMatrix %v4half 2
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v2half %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v2half %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v2half %26 None
-         %29 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %31 = OpLoad %v2half %29 None
-         %33 = OpCompositeConstruct %mat4v2half %22 %25 %28 %31
-          %t = OpTranspose %mat2v4half %33
-         %37 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %39 = OpLoad %v2half %37 None
-         %40 = OpVectorShuffle %v2half %39 %39 1 0
-          %l = OpExtInst %half %42 Length %40
-         %43 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %44 = OpLoad %v2half %43 None
-         %45 = OpVectorShuffle %v2half %44 %44 1 0
-         %46 = OpCompositeExtract %half %45 0
-          %a = OpExtInst %half %42 FAbs %46
-         %48 = OpCompositeExtract %half %t 0 0
-         %49 = OpFAdd %half %48 %l
-         %50 = OpFAdd %half %49 %a
-         %51 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %51 %50 None
+         %17 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v2half %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v2half %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v2half %25 None
+         %27 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %29 = OpLoad %v2half %27 None
+         %31 = OpCompositeConstruct %mat4v2half %21 %24 %26 %29
+          %t = OpTranspose %mat2v4half %31
+         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v2half %35 None
+         %37 = OpVectorShuffle %v2half %36 %36 1 0
+          %l = OpExtInst %half %39 Length %37
+         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %41 = OpLoad %v2half %40 None
+         %42 = OpVectorShuffle %v2half %41 %41 1 0
+         %43 = OpCompositeExtract %half %42 0
+          %a = OpExtInst %half %39 FAbs %43
+         %45 = OpCompositeExtract %half %t 0 0
+         %46 = OpFAdd %half %45 %l
+         %47 = OpFAdd %half %46 %a
+         %48 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.glsl
index bdde7d0..222af89 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.glsl
@@ -18,10 +18,10 @@
   float16_t inner;
 } v_2;
 float16_t a(f16mat4x2 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float16_t b(f16mat4x2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float16_t c(f16vec2 v) {
   return v[0u];
@@ -49,7 +49,7 @@
     }
   }
   float16_t v_7 = a(v_4);
-  float16_t v_8 = (v_7 + b(f16mat4x2(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2, v_1.inner[1].col3)));
-  float16_t v_9 = (v_8 + c(v_1.inner[1].col0.yx));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.yx[0u]));
+  float16_t v_8 = (v_7 + b(f16mat4x2(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2, v_1.inner[1u].col3)));
+  float16_t v_9 = (v_8 + c(v_1.inner[1u].col0.yx));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.dxc.hlsl
index 98aa43a..cee7c49 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float16_t a(matrix<float16_t, 4, 2> a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float16_t b(matrix<float16_t, 4, 2> m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float16_t c(vector<float16_t, 2> v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.msl
index 4bfb291..a0701b8 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 half a(tint_array<half4x2, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 half b(half4x2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 half c(half2 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<half4x2, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   half const v_1 = a((*tint_module_vars.u));
-  half const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  half const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].yx));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].yx[0u]));
+  half const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  half const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].yx));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.spvasm
index e4bb704..ef2c640 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 100
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -74,8 +74,6 @@
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -139,29 +137,29 @@
          %51 = OpLabel
          %69 = OpLoad %_arr_mat4v2half_uint_4 %44 None
          %70 = OpFunctionCall %half %a %69
-         %71 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_0
-         %75 = OpLoad %v2half %71 None
-         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_1
-         %77 = OpLoad %v2half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_2
-         %80 = OpLoad %v2half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_3
-         %83 = OpLoad %v2half %81 None
-         %84 = OpCompositeConstruct %mat4v2half %75 %77 %80 %83
-         %85 = OpFunctionCall %half %b %84
-         %86 = OpFAdd %half %70 %85
-         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_0
-         %88 = OpLoad %v2half %87 None
-         %89 = OpVectorShuffle %v2half %88 %88 1 0
-         %90 = OpFunctionCall %half %c %89
-         %91 = OpFAdd %half %86 %90
-         %92 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_1 %uint_0
-         %93 = OpLoad %v2half %92 None
-         %94 = OpVectorShuffle %v2half %93 %93 1 0
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %half %d %95
-         %97 = OpFAdd %half %91 %96
-         %98 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %98 %97 None
+         %71 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_0
+         %73 = OpLoad %v2half %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_1
+         %75 = OpLoad %v2half %74 None
+         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_2
+         %78 = OpLoad %v2half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_3
+         %81 = OpLoad %v2half %79 None
+         %82 = OpCompositeConstruct %mat4v2half %73 %75 %78 %81
+         %83 = OpFunctionCall %half %b %82
+         %84 = OpFAdd %half %70 %83
+         %85 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_0
+         %86 = OpLoad %v2half %85 None
+         %87 = OpVectorShuffle %v2half %86 %86 1 0
+         %88 = OpFunctionCall %half %c %87
+         %89 = OpFAdd %half %84 %88
+         %90 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_1 %uint_0
+         %91 = OpLoad %v2half %90 None
+         %92 = OpVectorShuffle %v2half %91 %91 1 0
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %half %d %93
+         %95 = OpFAdd %half %89 %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %96 %95 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.glsl
index 6f91e36..5749693 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.glsl
@@ -38,8 +38,8 @@
     }
   }
   p = v_3;
-  p[1] = f16mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  p[1][0] = v.inner[0].col1.yx;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = f16mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  p[1u][0u] = v.inner[0u].col1.yx;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 860da1a..096561d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -45,9 +45,9 @@
 void f() {
   matrix<float16_t, 4, 2> v_10[4] = v_6(0u);
   p = v_10;
-  p[int(1)] = v_2(32u);
-  p[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].y).yx;
-  p[int(1)][int(0)].x = float16_t(f16tof32(u[0u].y));
-  s.Store<float16_t>(0u, p[int(1)][int(0)].x);
+  p[1u] = v_2(32u);
+  p[1u][0u] = tint_bitcast_to_f16(u[0u].y).yx;
+  p[1u][0u].x = float16_t(f16tof32(u[0u].y));
+  s.Store<float16_t>(0u, p[1u][0u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.msl
index 08476b7..3091d2a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<half4x2, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.spvasm
index 874df86..a63a438 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 88
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,14 +65,10 @@
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat4v2half = OpTypePointer Private %mat4v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -113,32 +109,32 @@
          %34 = OpLabel
          %52 = OpLoad %_arr_mat4v2half_uint_4 %28 None
                OpStore %p %52 None
-         %53 = OpAccessChain %_ptr_Private_mat4v2half %p %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v2half %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_Private_mat4v2half %p %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v2half %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v2half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v2half %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v2half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2half %66 None
-         %69 = OpCompositeConstruct %mat4v2half %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_Private_v2half %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v2half %73 None
-         %75 = OpVectorShuffle %v2half %74 %74 1 0
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_Private_v2half %p %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_half %77 %uint_0
-         %80 = OpLoad %half %78 None
-         %81 = OpAccessChain %_ptr_Private_half %76 %uint_0
-               OpStore %81 %80 None
-         %83 = OpAccessChain %_ptr_Private_v2half %p %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Private_half %83 %uint_0
-         %85 = OpLoad %half %84 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %86 %85 None
+         %66 = OpCompositeConstruct %mat4v2half %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v2half %69 None
+         %71 = OpVectorShuffle %v2half %70 %70 1 0
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_half %73 %uint_0
+         %76 = OpLoad %half %74 None
+         %77 = OpAccessChain %_ptr_Private_half %72 %uint_0
+               OpStore %77 %76 None
+         %79 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Private_half %79 %uint_0
+         %81 = OpLoad %half %80 None
+         %82 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %82 %81 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.glsl
index 838cc67..e73e255 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.glsl
@@ -37,7 +37,7 @@
     }
   }
   v_1.inner = v_3;
-  v_1.inner[1] = f16mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  v_1.inner[1][0] = v.inner[0].col1.yx;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  v_1.inner[1u] = f16mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  v_1.inner[1u][0u] = v.inner[0u].col1.yx;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.ir.msl
index 33822ff..ba345fe 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<half4x2, 4>* u [[buffer(0)]], device tint_array<half4x2, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.spvasm
index b5d088b..d4ff41f 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,14 +65,10 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer__arr_mat4v2half_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v2half_uint_4
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %17
@@ -113,27 +109,27 @@
          %50 = OpLoad %_arr_mat4v2half_uint_4 %25 None
          %51 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2half_uint_4 %10 %uint_0
                OpStore %51 %50 None
-         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %10 %uint_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v2half %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %10 %uint_0 %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v2half %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v2half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v2half %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v2half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2half %66 None
-         %69 = OpCompositeConstruct %mat4v2half %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_StorageBuffer_v2half %10 %uint_0 %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v2half %73 None
-         %75 = OpVectorShuffle %v2half %74 %74 1 0
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2half %10 %uint_0 %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_half %77 %uint_0
-         %80 = OpLoad %half %78 None
-         %81 = OpAccessChain %_ptr_StorageBuffer_half %76 %uint_0
-               OpStore %81 %80 None
+         %66 = OpCompositeConstruct %mat4v2half %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_v2half %10 %uint_0 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v2half %69 None
+         %71 = OpVectorShuffle %v2half %70 %70 1 0
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v2half %10 %uint_0 %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_half %73 %uint_0
+         %76 = OpLoad %half %74 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_half %72 %uint_0
+               OpStore %77 %76 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.glsl
index 4bd29e7..71d902c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.glsl
@@ -49,9 +49,9 @@
     }
   }
   w = v_4;
-  w[1] = f16mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  w[1][0] = v.inner[0].col1.yx;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = f16mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  w[1u][0u] = v.inner[0u].col1.yx;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 3bd985a..360aa92 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -63,9 +63,9 @@
   GroupMemoryBarrierWithGroupSync();
   matrix<float16_t, 4, 2> v_12[4] = v_6(0u);
   w = v_12;
-  w[int(1)] = v_2(32u);
-  w[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].y).yx;
-  w[int(1)][int(0)].x = float16_t(f16tof32(u[0u].y));
+  w[1u] = v_2(32u);
+  w[1u][0u] = tint_bitcast_to_f16(u[0u].y).yx;
+  w[1u][0u].x = float16_t(f16tof32(u[0u].y));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
index 32af314..db8d89e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<half4x2, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<half4x2, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<half4x2, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.msl
index 4c8ae75..309bd54 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<half4x2, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<half4x2, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = half4x2(half2(0.0h), half2(0.0h), half2(0.0h), half2(0.0h));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
index 8c076ad..992aa4e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 102
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -64,16 +64,12 @@
          %47 = OpConstantNull %_arr_mat4v2half_uint_4
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_mat4x2_f16_std140 = OpTypePointer Function %mat4x2_f16_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-      %int_2 = OpConstant %int 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %98 = OpTypeFunction %void
+         %94 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -134,33 +130,33 @@
          %52 = OpLabel
          %68 = OpLoad %_arr_mat4v2half_uint_4 %45 None
                OpStore %w %68 None
-         %69 = OpAccessChain %_ptr_Workgroup_mat4v2half %w %int_1
-         %72 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_0
-         %75 = OpLoad %v2half %72 None
-         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %77 = OpLoad %v2half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2half %78 None
-         %80 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2half %80 None
-         %83 = OpCompositeConstruct %mat4v2half %75 %77 %79 %82
-               OpStore %69 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %88 = OpLoad %v2half %87 None
-         %89 = OpVectorShuffle %v2half %88 %88 1 0
-               OpStore %84 %89 None
-         %90 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1 %int_0
-         %91 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_1
-         %92 = OpAccessChain %_ptr_Uniform_half %91 %uint_0
-         %94 = OpLoad %half %92 None
-         %95 = OpAccessChain %_ptr_Workgroup_half %90 %uint_0
-               OpStore %95 %94 None
+         %69 = OpAccessChain %_ptr_Workgroup_mat4v2half %w %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_0
+         %72 = OpLoad %v2half %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %74 = OpLoad %v2half %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %76 = OpLoad %v2half %75 None
+         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %79 = OpLoad %v2half %77 None
+         %80 = OpCompositeConstruct %mat4v2half %72 %74 %76 %79
+               OpStore %69 %80 None
+         %81 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %84 = OpLoad %v2half %83 None
+         %85 = OpVectorShuffle %v2half %84 %84 1 0
+               OpStore %81 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1 %uint_0
+         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_1
+         %88 = OpAccessChain %_ptr_Uniform_half %87 %uint_0
+         %90 = OpLoad %half %88 None
+         %91 = OpAccessChain %_ptr_Workgroup_half %86 %uint_0
+               OpStore %91 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %98
-         %99 = OpLabel
-        %100 = OpLoad %uint %f_local_invocation_index_Input None
-        %101 = OpFunctionCall %void %f_inner %100
+          %f = OpFunction %void None %94
+         %95 = OpLabel
+         %96 = OpLoad %uint %f_local_invocation_index_Input None
+         %97 = OpFunctionCall %void %f_inner %96
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index a60db0b..ae34ce4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -37,11 +37,11 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x2 l_a[4] = a_load(0u);
-  float4x2 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  float4x2 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   uint4 ubo_load_4 = a[scalar_offset_4 / 4];
   float2 l_a_i_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
-  const uint scalar_offset_5 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index a60db0b..ae34ce4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -37,11 +37,11 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x2 l_a[4] = a_load(0u);
-  float4x2 l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  float4x2 l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   uint4 ubo_load_4 = a[scalar_offset_4 / 4];
   float2 l_a_i_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
-  const uint scalar_offset_5 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 23f4391..ae91d1d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -23,9 +23,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   mat4x2 v_3 = mat4x2(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2, v.inner[v_2].col3);
-  vec2 v_4 = v_3[i()];
+  vec2 v_4 = v_3[min(uint(i()), 3u)];
   mat4x2_f32_std140 v_5[4] = v.inner;
   mat4x2 v_6[4] = mat4x2[4](mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)));
   {
@@ -46,5 +46,5 @@
   mat4x2 l_a[4] = v_6;
   mat4x2 l_a_i = v_3;
   vec2 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index da3c5ac..875efe9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -44,12 +44,12 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (32u * uint(i()));
-  uint v_13 = (8u * uint(i()));
+  uint v_12 = (32u * uint(min(uint(i()), 3u)));
+  uint v_13 = (8u * uint(min(uint(i()), 3u)));
   float4x2 l_a[4] = v_8(0u);
   float4x2 l_a_i = v(v_12);
   uint4 v_14 = a[((v_12 + v_13) / 16u)];
   float2 l_a_i_i = asfloat(((((((v_12 + v_13) % 16u) / 4u) == 2u)) ? (v_14.zw) : (v_14.xy)));
-  s.Store(0u, asuint((((asfloat(a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index da3c5ac..875efe9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -44,12 +44,12 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (32u * uint(i()));
-  uint v_13 = (8u * uint(i()));
+  uint v_12 = (32u * uint(min(uint(i()), 3u)));
+  uint v_13 = (8u * uint(min(uint(i()), 3u)));
   float4x2 l_a[4] = v_8(0u);
   float4x2 l_a_i = v(v_12);
   uint4 v_14 = a[((v_12 + v_13) / 16u)];
   float2 l_a_i_i = asfloat(((((((v_12 + v_13) % 16u) / 4u) == 2u)) ? (v_14.zw) : (v_14.xy)));
-  s.Store(0u, asuint((((asfloat(a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_12 + v_13) / 16u)][(((v_12 + v_13) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 1812c24..03dd4b4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<float4x2, 4>* const p_a = tint_module_vars.a;
-  const constant float4x2* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant float2* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant float4x2* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant float2* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<float4x2, 4> const l_a = (*p_a);
   float4x2 const l_a_i = (*p_a_i);
   float2 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 91e3a84..a238c7c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<float4x2, 4> const l_a = *(tint_symbol_2);
   float4x2 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   float2 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index b4fec96..7b9b140 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -60,17 +61,17 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4x2_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x2_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
 %_ptr_Function__arr_mat4x2_f32_std140_uint_4 = OpTypePointer Function %_arr_mat4x2_f32_std140_uint_4
 %_arr_mat4v2float_uint_4 = OpTypeArray %mat4v2float %uint_4
 %_ptr_Function__arr_mat4v2float_uint_4 = OpTypePointer Function %_arr_mat4v2float_uint_4
-         %58 = OpConstantNull %_arr_mat4v2float_uint_4
+         %63 = OpConstantNull %_arr_mat4v2float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4x2_f32_std140 = OpTypePointer Function %mat4x2_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -84,63 +85,67 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat4v2float Function
-         %53 = OpVariable %_ptr_Function__arr_mat4x2_f32_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_mat4v2float_uint_4 Function %58
+         %49 = OpVariable %_ptr_Function_mat4v2float Function
+         %58 = OpVariable %_ptr_Function__arr_mat4x2_f32_std140_uint_4 Function
+         %60 = OpVariable %_ptr_Function__arr_mat4v2float_uint_4 Function %63
          %28 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f32_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_0
-         %34 = OpLoad %v2float %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_1
-         %37 = OpLoad %v2float %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_2
-         %40 = OpLoad %v2float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2float %28 %31 %uint_3
-         %43 = OpLoad %v2float %41 None
-      %l_a_i = OpCompositeConstruct %mat4v2float %34 %37 %40 %43
-               OpStore %46 %l_a_i
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v2float %46 %48
-    %l_a_i_i = OpLoad %v2float %49 None
-         %52 = OpLoad %_arr_mat4x2_f32_std140_uint_4 %28 None
-               OpStore %53 %52
-               OpBranch %59
-         %59 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-         %64 = OpPhi %uint %uint_0 %59 %65 %61
-               OpLoopMerge %63 %61 None
-               OpBranch %60
-         %60 = OpLabel
-         %66 = OpUGreaterThanEqual %bool %64 %uint_4
-               OpSelectionMerge %68 None
-               OpBranchConditional %66 %69 %68
-         %69 = OpLabel
-               OpBranch %63
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_0
+         %38 = OpLoad %v2float %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_1
+         %41 = OpLoad %v2float %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_2
+         %44 = OpLoad %v2float %42 None
+         %45 = OpAccessChain %_ptr_Uniform_v2float %28 %33 %uint_3
+         %46 = OpLoad %v2float %45 None
+      %l_a_i = OpCompositeConstruct %mat4v2float %38 %41 %44 %46
+               OpStore %49 %l_a_i
+         %51 = OpFunctionCall %int %i
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %34 UMin %52 %uint_3
+         %54 = OpAccessChain %_ptr_Function_v2float %49 %53
+    %l_a_i_i = OpLoad %v2float %54 None
+         %57 = OpLoad %_arr_mat4x2_f32_std140_uint_4 %28 None
+               OpStore %58 %57
+               OpBranch %64
+         %64 = OpLabel
+               OpBranch %67
+         %67 = OpLabel
+         %69 = OpPhi %uint %uint_0 %64 %70 %66
+               OpLoopMerge %68 %66 None
+               OpBranch %65
+         %65 = OpLabel
+         %71 = OpUGreaterThanEqual %bool %69 %uint_4
+               OpSelectionMerge %73 None
+               OpBranchConditional %71 %74 %73
+         %74 = OpLabel
+               OpBranch %68
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Function_mat4v2float %60 %69
+         %76 = OpAccessChain %_ptr_Function_mat4x2_f32_std140 %58 %69
+         %78 = OpLoad %mat4x2_f32_std140 %76 None
+         %79 = OpCompositeExtract %v2float %78 0
+         %80 = OpCompositeExtract %v2float %78 1
+         %81 = OpCompositeExtract %v2float %78 2
+         %82 = OpCompositeExtract %v2float %78 3
+         %83 = OpCompositeConstruct %mat4v2float %79 %80 %81 %82
+               OpStore %75 %83 None
+               OpBranch %66
+         %66 = OpLabel
+         %70 = OpIAdd %uint %69 %uint_1
+               OpBranch %67
          %68 = OpLabel
-         %70 = OpAccessChain %_ptr_Function_mat4v2float %55 %64
-         %71 = OpAccessChain %_ptr_Function_mat4x2_f32_std140 %53 %64
-         %73 = OpLoad %mat4x2_f32_std140 %71 None
-         %74 = OpCompositeExtract %v2float %73 0
-         %75 = OpCompositeExtract %v2float %73 1
-         %76 = OpCompositeExtract %v2float %73 2
-         %77 = OpCompositeExtract %v2float %73 3
-         %78 = OpCompositeConstruct %mat4v2float %74 %75 %76 %77
-               OpStore %70 %78 None
-               OpBranch %61
-         %61 = OpLabel
-         %65 = OpIAdd %uint %64 %uint_1
-               OpBranch %62
-         %63 = OpLabel
-        %l_a = OpLoad %_arr_mat4v2float_uint_4 %55 None
-         %80 = OpCompositeExtract %float %l_a_i_i 0
-         %81 = OpCompositeExtract %float %l_a 0 0 0
-         %82 = OpFAdd %float %80 %81
-         %83 = OpCompositeExtract %float %l_a_i 0 0
-         %84 = OpFAdd %float %82 %83
+        %l_a = OpLoad %_arr_mat4v2float_uint_4 %60 None
          %85 = OpCompositeExtract %float %l_a_i_i 0
-         %86 = OpFAdd %float %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %87 %86 None
+         %86 = OpCompositeExtract %float %l_a 0 0 0
+         %87 = OpFAdd %float %85 %86
+         %88 = OpCompositeExtract %float %l_a_i 0 0
+         %89 = OpFAdd %float %87 %88
+         %90 = OpCompositeExtract %float %l_a_i_i 0
+         %91 = OpFAdd %float %89 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
index da9d873..3b027e9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -18,7 +18,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x2 v_2 = mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
+  mat4x2 v_2 = mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
   mat4x2_f32_std140 v_3[4] = v.inner;
   mat4x2 v_4[4] = mat4x2[4](mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)), mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f)));
   {
@@ -38,6 +38,6 @@
   }
   mat4x2 l_a[4] = v_4;
   mat4x2 l_a_i = v_2;
-  vec2 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  vec2 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index ba98fa2..3278282 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -41,6 +41,6 @@
   float4x2 l_a[4] = v_8(0u);
   float4x2 l_a_i = v(64u);
   float2 l_a_i_i = asfloat(a[4u].zw);
-  s.Store(0u, asuint((((asfloat(a[4u].z) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[4u].z) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index ba98fa2..3278282 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -41,6 +41,6 @@
   float4x2 l_a[4] = v_8(0u);
   float4x2 l_a_i = v(64u);
   float2 l_a_i_i = asfloat(a[4u].zw);
-  s.Store(0u, asuint((((asfloat(a[4u].z) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[4u].z) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 5581311..1131c45 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<float4x2, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<float4x2, 4>* const p_a = tint_module_vars.a;
-  const constant float4x2* const p_a_2 = (&(*p_a)[2]);
-  const constant float2* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant float4x2* const p_a_2 = (&(*p_a)[2u]);
+  const constant float2* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<float4x2, 4> const l_a = (*p_a);
   float4x2 const l_a_i = (*p_a_2);
   float2 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
index 7a696bf..629d4b1 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -53,74 +53,72 @@
 %_ptr_Uniform__arr_mat4x2_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x2_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Function__arr_mat4x2_f32_std140_uint_4 = OpTypePointer Function %_arr_mat4x2_f32_std140_uint_4
 %_arr_mat4v2float_uint_4 = OpTypeArray %mat4v2float %uint_4
 %_ptr_Function__arr_mat4v2float_uint_4 = OpTypePointer Function %_arr_mat4v2float_uint_4
-         %43 = OpConstantNull %_arr_mat4v2float_uint_4
+         %41 = OpConstantNull %_arr_mat4v2float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
 %_ptr_Function_mat4x2_f32_std140 = OpTypePointer Function %mat4x2_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_mat4x2_f32_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_mat4v2float_uint_4 Function %43
+         %36 = OpVariable %_ptr_Function__arr_mat4x2_f32_std140_uint_4 Function
+         %38 = OpVariable %_ptr_Function__arr_mat4v2float_uint_4 Function %41
          %17 = OpAccessChain %_ptr_Uniform__arr_mat4x2_f32_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_0
-         %24 = OpLoad %v2float %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_1
-         %27 = OpLoad %v2float %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_2
-         %30 = OpLoad %v2float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2float %17 %int_2 %uint_3
-         %33 = OpLoad %v2float %31 None
-      %l_a_i = OpCompositeConstruct %mat4v2float %24 %27 %30 %33
+         %20 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_0
+         %23 = OpLoad %v2float %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_1
+         %26 = OpLoad %v2float %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_2
+         %28 = OpLoad %v2float %27 None
+         %29 = OpAccessChain %_ptr_Uniform_v2float %17 %uint_2 %uint_3
+         %31 = OpLoad %v2float %29 None
+      %l_a_i = OpCompositeConstruct %mat4v2float %23 %26 %28 %31
     %l_a_i_i = OpCompositeExtract %v2float %l_a_i 1
-         %37 = OpLoad %_arr_mat4x2_f32_std140_uint_4 %17 None
-               OpStore %38 %37
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-         %49 = OpPhi %uint %uint_0 %44 %50 %46
-               OpLoopMerge %48 %46 None
+         %35 = OpLoad %_arr_mat4x2_f32_std140_uint_4 %17 None
+               OpStore %36 %35
+               OpBranch %42
+         %42 = OpLabel
                OpBranch %45
          %45 = OpLabel
-         %51 = OpUGreaterThanEqual %bool %49 %uint_4
-               OpSelectionMerge %53 None
-               OpBranchConditional %51 %54 %53
-         %54 = OpLabel
-               OpBranch %48
-         %53 = OpLabel
-         %55 = OpAccessChain %_ptr_Function_mat4v2float %40 %49
-         %57 = OpAccessChain %_ptr_Function_mat4x2_f32_std140 %38 %49
-         %59 = OpLoad %mat4x2_f32_std140 %57 None
-         %60 = OpCompositeExtract %v2float %59 0
-         %61 = OpCompositeExtract %v2float %59 1
-         %62 = OpCompositeExtract %v2float %59 2
-         %63 = OpCompositeExtract %v2float %59 3
-         %64 = OpCompositeConstruct %mat4v2float %60 %61 %62 %63
-               OpStore %55 %64 None
+         %47 = OpPhi %uint %uint_0 %42 %48 %44
+               OpLoopMerge %46 %44 None
+               OpBranch %43
+         %43 = OpLabel
+         %49 = OpUGreaterThanEqual %bool %47 %uint_4
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %52 %51
+         %52 = OpLabel
                OpBranch %46
+         %51 = OpLabel
+         %53 = OpAccessChain %_ptr_Function_mat4v2float %38 %47
+         %55 = OpAccessChain %_ptr_Function_mat4x2_f32_std140 %36 %47
+         %57 = OpLoad %mat4x2_f32_std140 %55 None
+         %58 = OpCompositeExtract %v2float %57 0
+         %59 = OpCompositeExtract %v2float %57 1
+         %60 = OpCompositeExtract %v2float %57 2
+         %61 = OpCompositeExtract %v2float %57 3
+         %62 = OpCompositeConstruct %mat4v2float %58 %59 %60 %61
+               OpStore %53 %62 None
+               OpBranch %44
+         %44 = OpLabel
+         %48 = OpIAdd %uint %47 %uint_1
+               OpBranch %45
          %46 = OpLabel
-         %50 = OpIAdd %uint %49 %uint_1
-               OpBranch %47
-         %48 = OpLabel
-        %l_a = OpLoad %_arr_mat4v2float_uint_4 %40 None
-         %66 = OpCompositeExtract %float %l_a_i_i 0
-         %67 = OpCompositeExtract %float %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat4v2float_uint_4 %38 None
+         %64 = OpCompositeExtract %float %l_a_i_i 0
+         %65 = OpCompositeExtract %float %l_a 0 0 0
+         %66 = OpFAdd %float %64 %65
+         %67 = OpCompositeExtract %float %l_a_i 0 0
          %68 = OpFAdd %float %66 %67
-         %69 = OpCompositeExtract %float %l_a_i 0 0
+         %69 = OpCompositeExtract %float %l_a_i_i 0
          %70 = OpFAdd %float %68 %69
-         %71 = OpCompositeExtract %float %l_a_i_i 0
-         %72 = OpFAdd %float %70 %71
-         %73 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %73 %72 None
+         %71 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %71 %70 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.glsl
index c5be9b3..c9a70a9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.glsl
@@ -18,9 +18,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2x4 t = transpose(mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3));
-  float l = length(v.inner[0].col1.yx);
-  float a = abs(v.inner[0].col1.yx[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat2x4 t = transpose(mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3));
+  float l = length(v.inner[0u].col1.yx);
+  float a = abs(v.inner[0u].col1.yx[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 44f8e74..d2c7bfc 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -19,7 +19,7 @@
   float2x4 t = transpose(v(64u));
   float l = length(asfloat(u[0u].zw).yx);
   float a = abs(asfloat(u[0u].zw).yx.x);
-  float v_8 = (t[int(0)].x + float(l));
+  float v_8 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_8 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 44f8e74..d2c7bfc 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -19,7 +19,7 @@
   float2x4 t = transpose(v(64u));
   float l = length(asfloat(u[0u].zw).yx);
   float a = abs(asfloat(u[0u].zw).yx.x);
-  float v_8 = (t[int(0)].x + float(l));
+  float v_8 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_8 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
index 4a8b24d..52e4db3 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<float4x2, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  float2x4 const t = transpose((*tint_module_vars.u)[2]);
-  float const l = length((*tint_module_vars.u)[0][1].yx);
-  float const a = abs((*tint_module_vars.u)[0][1].yx[0u]);
-  float const v = (t[0][0u] + float(l));
+  float2x4 const t = transpose((*tint_module_vars.u)[2u]);
+  float const l = length((*tint_module_vars.u)[0u][1u].yx);
+  float const a = abs((*tint_module_vars.u)[0u][1u].yx[0u]);
+  float const v = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.spvasm
index 47aea0f..7c6bda2 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 53
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
-         %42 = OpExtInstImport "GLSL.std.450"
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -52,41 +52,38 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
     %v4float = OpTypeVector %float 4
 %mat2v4float = OpTypeMatrix %v4float 2
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v2float %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v2float %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v2float %26 None
-         %29 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %31 = OpLoad %v2float %29 None
-         %33 = OpCompositeConstruct %mat4v2float %22 %25 %28 %31
-          %t = OpTranspose %mat2v4float %33
-         %37 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %39 = OpLoad %v2float %37 None
-         %40 = OpVectorShuffle %v2float %39 %39 1 0
-          %l = OpExtInst %float %42 Length %40
-         %43 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %44 = OpLoad %v2float %43 None
-         %45 = OpVectorShuffle %v2float %44 %44 1 0
-         %46 = OpCompositeExtract %float %45 0
-          %a = OpExtInst %float %42 FAbs %46
-         %48 = OpCompositeExtract %float %t 0 0
-         %49 = OpFAdd %float %48 %l
-         %50 = OpFAdd %float %49 %a
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %51 %50 None
+         %17 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v2float %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v2float %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v2float %25 None
+         %27 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %29 = OpLoad %v2float %27 None
+         %31 = OpCompositeConstruct %mat4v2float %21 %24 %26 %29
+          %t = OpTranspose %mat2v4float %31
+         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v2float %35 None
+         %37 = OpVectorShuffle %v2float %36 %36 1 0
+          %l = OpExtInst %float %39 Length %37
+         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %41 = OpLoad %v2float %40 None
+         %42 = OpVectorShuffle %v2float %41 %41 1 0
+         %43 = OpCompositeExtract %float %42 0
+          %a = OpExtInst %float %39 FAbs %43
+         %45 = OpCompositeExtract %float %t 0 0
+         %46 = OpFAdd %float %45 %l
+         %47 = OpFAdd %float %46 %a
+         %48 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.glsl
index a2d699b..93d55ac 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.glsl
@@ -17,10 +17,10 @@
   float inner;
 } v_2;
 float a(mat4x2 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat4x2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec2 v) {
   return v[0u];
@@ -48,7 +48,7 @@
     }
   }
   float v_7 = a(v_4);
-  float v_8 = (v_7 + b(mat4x2(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2, v_1.inner[1].col3)));
-  float v_9 = (v_8 + c(v_1.inner[1].col0.yx));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.yx[0u]));
+  float v_8 = (v_7 + b(mat4x2(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2, v_1.inner[1u].col3)));
+  float v_9 = (v_8 + c(v_1.inner[1u].col0.yx));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index 196d194..136e41a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x2 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x2 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float2 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index 196d194..136e41a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x2 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x2 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float2 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.msl
index 6e3ab62..283c166 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 float a(tint_array<float4x2, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float4x2 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float2 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<float4x2, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_1 = a((*tint_module_vars.u));
-  float const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  float const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].yx));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].yx[0u]));
+  float const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  float const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].yx));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].yx[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.spvasm
index 6ea18d9..7e62a5d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 100
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -71,8 +71,6 @@
 %_ptr_Function_mat4x2_f32_std140 = OpTypePointer Function %mat4x2_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -136,29 +134,29 @@
          %51 = OpLabel
          %69 = OpLoad %_arr_mat4v2float_uint_4 %44 None
          %70 = OpFunctionCall %float %a %69
-         %71 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %75 = OpLoad %v2float %71 None
-         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_1
-         %77 = OpLoad %v2float %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_2
-         %80 = OpLoad %v2float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_3
-         %83 = OpLoad %v2float %81 None
-         %84 = OpCompositeConstruct %mat4v2float %75 %77 %80 %83
-         %85 = OpFunctionCall %float %b %84
-         %86 = OpFAdd %float %70 %85
-         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %88 = OpLoad %v2float %87 None
-         %89 = OpVectorShuffle %v2float %88 %88 1 0
-         %90 = OpFunctionCall %float %c %89
-         %91 = OpFAdd %float %86 %90
-         %92 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_1 %uint_0
-         %93 = OpLoad %v2float %92 None
-         %94 = OpVectorShuffle %v2float %93 %93 1 0
-         %95 = OpCompositeExtract %float %94 0
-         %96 = OpFunctionCall %float %d %95
-         %97 = OpFAdd %float %91 %96
-         %98 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %98 %97 None
+         %71 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %73 = OpLoad %v2float %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_1
+         %75 = OpLoad %v2float %74 None
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_2
+         %78 = OpLoad %v2float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_3
+         %81 = OpLoad %v2float %79 None
+         %82 = OpCompositeConstruct %mat4v2float %73 %75 %78 %81
+         %83 = OpFunctionCall %float %b %82
+         %84 = OpFAdd %float %70 %83
+         %85 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %86 = OpLoad %v2float %85 None
+         %87 = OpVectorShuffle %v2float %86 %86 1 0
+         %88 = OpFunctionCall %float %c %87
+         %89 = OpFAdd %float %84 %88
+         %90 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1 %uint_0
+         %91 = OpLoad %v2float %90 None
+         %92 = OpVectorShuffle %v2float %91 %91 1 0
+         %93 = OpCompositeExtract %float %92 0
+         %94 = OpFunctionCall %float %d %93
+         %95 = OpFAdd %float %89 %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %96 %95 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.glsl
index 2f848d7..49f8357 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.glsl
@@ -37,8 +37,8 @@
     }
   }
   p = v_3;
-  p[1] = mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  p[1][0] = v.inner[0].col1.yx;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  p[1u][0u] = v.inner[0u].col1.yx;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 9375f10..39a4abb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -41,9 +41,9 @@
 void f() {
   float4x2 v_12[4] = v_8(0u);
   p = v_12;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  p[int(1)][int(0)].x = asfloat(u[0u].z);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[0u].zw).yx;
+  p[1u][0u].x = asfloat(u[0u].z);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 9375f10..39a4abb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -41,9 +41,9 @@
 void f() {
   float4x2 v_12[4] = v_8(0u);
   p = v_12;
-  p[int(1)] = v(64u);
-  p[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  p[int(1)][int(0)].x = asfloat(u[0u].z);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(64u);
+  p[1u][0u] = asfloat(u[0u].zw).yx;
+  p[1u][0u].x = asfloat(u[0u].z);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.msl
index a8d214a..edb55f7 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<float4x2, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.spvasm
index 7fa7a4d..ca35907 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 88
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -62,14 +62,10 @@
 %_ptr_Function_mat4x2_f32_std140 = OpTypePointer Function %mat4x2_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat4v2float = OpTypePointer Private %mat4v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -110,32 +106,32 @@
          %34 = OpLabel
          %52 = OpLoad %_arr_mat4v2float_uint_4 %28 None
                OpStore %p %52 None
-         %53 = OpAccessChain %_ptr_Private_mat4v2float %p %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v2float %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_Private_mat4v2float %p %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v2float %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v2float %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v2float %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v2float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2float %66 None
-         %69 = OpCompositeConstruct %mat4v2float %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v2float %73 None
-         %75 = OpVectorShuffle %v2float %74 %74 1 0
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_float %77 %uint_0
-         %80 = OpLoad %float %78 None
-         %81 = OpAccessChain %_ptr_Private_float %76 %uint_0
-               OpStore %81 %80 None
-         %83 = OpAccessChain %_ptr_Private_v2float %p %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Private_float %83 %uint_0
-         %85 = OpLoad %float %84 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %86 %85 None
+         %66 = OpCompositeConstruct %mat4v2float %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v2float %69 None
+         %71 = OpVectorShuffle %v2float %70 %70 1 0
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_float %73 %uint_0
+         %76 = OpLoad %float %74 None
+         %77 = OpAccessChain %_ptr_Private_float %72 %uint_0
+               OpStore %77 %76 None
+         %79 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Private_float %79 %uint_0
+         %81 = OpLoad %float %80 None
+         %82 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %82 %81 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.glsl
index 6854e34..da25c4e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.glsl
@@ -36,7 +36,7 @@
     }
   }
   v_1.inner = v_3;
-  v_1.inner[1] = mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  v_1.inner[1][0] = v.inner[0].col1.yx;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  v_1.inner[1u] = mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  v_1.inner[1u][0u] = v.inner[0u].col1.yx;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.ir.msl
index 0fbd10d..51981de 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<float4x2, 4>* u [[buffer(0)]], device tint_array<float4x2, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.spvasm
index 4e12579..2f647c0 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -62,14 +62,10 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer__arr_mat4v2float_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v2float_uint_4
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %17
@@ -110,27 +106,27 @@
          %50 = OpLoad %_arr_mat4v2float_uint_4 %25 None
          %51 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v2float_uint_4 %10 %uint_0
                OpStore %51 %50 None
-         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %10 %uint_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v2float %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %10 %uint_0 %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v2float %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v2float %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v2float %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v2float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2float %66 None
-         %69 = OpCompositeConstruct %mat4v2float %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v2float %73 None
-         %75 = OpVectorShuffle %v2float %74 %74 1 0
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_float %77 %uint_0
-         %80 = OpLoad %float %78 None
-         %81 = OpAccessChain %_ptr_StorageBuffer_float %76 %uint_0
-               OpStore %81 %80 None
+         %66 = OpCompositeConstruct %mat4v2float %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v2float %69 None
+         %71 = OpVectorShuffle %v2float %70 %70 1 0
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v2float %10 %uint_0 %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_float %73 %uint_0
+         %76 = OpLoad %float %74 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_float %72 %uint_0
+               OpStore %77 %76 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.glsl
index a6f0935..0485554 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.glsl
@@ -48,9 +48,9 @@
     }
   }
   w = v_4;
-  w[1] = mat4x2(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  w[1][0] = v.inner[0].col1.yx;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = mat4x2(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  w[1u][0u] = v.inner[0u].col1.yx;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index ae521c0..16aaa94 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -59,9 +59,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x2 v_14[4] = v_8(0u);
   w = v_14;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  w[int(1)][int(0)].x = asfloat(u[0u].z);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[0u].zw).yx;
+  w[1u][0u].x = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index ae521c0..16aaa94 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -59,9 +59,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x2 v_14[4] = v_8(0u);
   w = v_14;
-  w[int(1)] = v(64u);
-  w[int(1)][int(0)] = asfloat(u[0u].zw).yx;
-  w[int(1)][int(0)].x = asfloat(u[0u].z);
+  w[1u] = v(64u);
+  w[1u][0u] = asfloat(u[0u].zw).yx;
+  w[1u][0u].x = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
index eaf51f2..54d0885 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<float4x2, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<float4x2, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].yx;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].yx;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<float4x2, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.msl
index ee95d46..c30d5be 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<float4x2, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<float4x2, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = float4x2(float2(0.0f), float2(0.0f), float2(0.0f), float2(0.0f));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
index 9a64a4a..46e1f21 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 102
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -61,16 +61,12 @@
          %47 = OpConstantNull %_arr_mat4v2float_uint_4
 %_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
 %_ptr_Function_mat4x2_f32_std140 = OpTypePointer Function %mat4x2_f32_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-      %int_2 = OpConstant %int 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %98 = OpTypeFunction %void
+         %94 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -131,33 +127,33 @@
          %52 = OpLabel
          %68 = OpLoad %_arr_mat4v2float_uint_4 %45 None
                OpStore %w %68 None
-         %69 = OpAccessChain %_ptr_Workgroup_mat4v2float %w %int_1
-         %72 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_0
-         %75 = OpLoad %v2float %72 None
-         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %77 = OpLoad %v2float %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2float %78 None
-         %80 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2float %80 None
-         %83 = OpCompositeConstruct %mat4v2float %75 %77 %79 %82
-               OpStore %69 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %88 = OpLoad %v2float %87 None
-         %89 = OpVectorShuffle %v2float %88 %88 1 0
-               OpStore %84 %89 None
-         %90 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %int_0
-         %91 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_1
-         %92 = OpAccessChain %_ptr_Uniform_float %91 %uint_0
-         %94 = OpLoad %float %92 None
-         %95 = OpAccessChain %_ptr_Workgroup_float %90 %uint_0
-               OpStore %95 %94 None
+         %69 = OpAccessChain %_ptr_Workgroup_mat4v2float %w %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_0
+         %72 = OpLoad %v2float %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %74 = OpLoad %v2float %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %76 = OpLoad %v2float %75 None
+         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %79 = OpLoad %v2float %77 None
+         %80 = OpCompositeConstruct %mat4v2float %72 %74 %76 %79
+               OpStore %69 %80 None
+         %81 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %84 = OpLoad %v2float %83 None
+         %85 = OpVectorShuffle %v2float %84 %84 1 0
+               OpStore %81 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_0
+         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_1
+         %88 = OpAccessChain %_ptr_Uniform_float %87 %uint_0
+         %90 = OpLoad %float %88 None
+         %91 = OpAccessChain %_ptr_Workgroup_float %86 %uint_0
+               OpStore %91 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %98
-         %99 = OpLabel
-        %100 = OpLoad %uint %f_local_invocation_index_Input None
-        %101 = OpFunctionCall %void %f_inner %100
+          %f = OpFunction %void None %94
+         %95 = OpLabel
+         %96 = OpLoad %uint %f_local_invocation_index_Input None
+         %97 = OpFunctionCall %void %f_inner %96
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index dbdab23..981a9ca 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -49,14 +49,14 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   matrix<float16_t, 4, 3> l_a[4] = a_load(0u);
-  matrix<float16_t, 4, 3> l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  matrix<float16_t, 4, 3> l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   uint4 ubo_load_9 = a[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
   float16_t ubo_load_8_y = f16tof32(ubo_load_8[0] >> 16);
   vector<float16_t, 3> l_a_i_i = vector<float16_t, 3>(ubo_load_8_xz[0], ubo_load_8_y, ubo_load_8_xz[1]);
-  const uint scalar_offset_bytes = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save))));
+  const uint scalar_offset_bytes = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   s.Store<float16_t>(0u, (((float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF))) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x));
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index c343d9a..8cc9f51 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -24,9 +24,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   f16mat4x3 v_3 = f16mat4x3(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2, v.inner[v_2].col3);
-  f16vec3 v_4 = v_3[i()];
+  f16vec3 v_4 = v_3[min(uint(i()), 3u)];
   mat4x3_f16_std140 v_5[4] = v.inner;
   f16mat4x3 v_6[4] = f16mat4x3[4](f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   {
@@ -47,5 +47,5 @@
   f16mat4x3 l_a[4] = v_6;
   f16mat4x3 l_a_i = v_3;
   f16vec3 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 440d79f..79a0f26 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -56,13 +56,13 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (32u * uint(i()));
-  uint v_17 = (8u * uint(i()));
+  uint v_16 = (32u * uint(min(uint(i()), 3u)));
+  uint v_17 = (8u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 3> l_a[4] = v_12(0u);
   matrix<float16_t, 4, 3> l_a_i = v_4(v_16);
   uint4 v_18 = a[((v_16 + v_17) / 16u)];
   vector<float16_t, 3> l_a_i_i = tint_bitcast_to_f16(((((((v_16 + v_17) % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy))).xyz;
   uint v_19 = a[((v_16 + v_17) / 16u)][(((v_16 + v_17) % 16u) / 4u)];
-  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_19 >> (((((v_16 + v_17) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_19 >> (((((v_16 + v_17) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index b8d1a15..e2341a6 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -56,8 +56,8 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant packed_half3* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)].packed);
+  const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant packed_half3* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<half4x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f16_array_element, 4> const v_19 = (*p_a_i);
   half3 const v_20 = half3(v_19[0u].packed);
@@ -65,5 +65,5 @@
   half3 const v_22 = half3(v_19[2u].packed);
   half4x3 const l_a_i = half4x3(v_20, v_21, v_22, half3(v_19[3u].packed));
   half3 const l_a_i_i = half3((*p_a_i_i));
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 4fb4eb95..44f1d90 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -42,9 +42,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<half4x3, 4> const l_a = tint_unpack_vec3_in_composite_1(*(tint_symbol_2));
   half4x3 const l_a_i = tint_unpack_vec3_in_composite((*(tint_symbol_2))[p_a_i_save]);
   half3 const l_a_i_i = half3((*(tint_symbol_2))[p_a_i_save][p_a_i_i_save].elements);
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 2567084..9ec179a 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -63,17 +64,17 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4x3_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
 %_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
 %_ptr_Function_v3half = OpTypePointer Function %v3half
 %_ptr_Function__arr_mat4x3_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x3_f16_std140_uint_4
 %_arr_mat4v3half_uint_4 = OpTypeArray %mat4v3half %uint_4
 %_ptr_Function__arr_mat4v3half_uint_4 = OpTypePointer Function %_arr_mat4v3half_uint_4
-         %58 = OpConstantNull %_arr_mat4v3half_uint_4
+         %63 = OpConstantNull %_arr_mat4v3half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -87,63 +88,67 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat4v3half Function
-         %53 = OpVariable %_ptr_Function__arr_mat4x3_f16_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %58
+         %49 = OpVariable %_ptr_Function_mat4v3half Function
+         %58 = OpVariable %_ptr_Function__arr_mat4x3_f16_std140_uint_4 Function
+         %60 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %63
          %28 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f16_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_0
-         %34 = OpLoad %v3half %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_1
-         %37 = OpLoad %v3half %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_2
-         %40 = OpLoad %v3half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3half %28 %31 %uint_3
-         %43 = OpLoad %v3half %41 None
-      %l_a_i = OpCompositeConstruct %mat4v3half %34 %37 %40 %43
-               OpStore %46 %l_a_i
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v3half %46 %48
-    %l_a_i_i = OpLoad %v3half %49 None
-         %52 = OpLoad %_arr_mat4x3_f16_std140_uint_4 %28 None
-               OpStore %53 %52
-               OpBranch %59
-         %59 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-         %64 = OpPhi %uint %uint_0 %59 %65 %61
-               OpLoopMerge %63 %61 None
-               OpBranch %60
-         %60 = OpLabel
-         %66 = OpUGreaterThanEqual %bool %64 %uint_4
-               OpSelectionMerge %68 None
-               OpBranchConditional %66 %69 %68
-         %69 = OpLabel
-               OpBranch %63
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_0
+         %38 = OpLoad %v3half %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_1
+         %41 = OpLoad %v3half %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_2
+         %44 = OpLoad %v3half %42 None
+         %45 = OpAccessChain %_ptr_Uniform_v3half %28 %33 %uint_3
+         %46 = OpLoad %v3half %45 None
+      %l_a_i = OpCompositeConstruct %mat4v3half %38 %41 %44 %46
+               OpStore %49 %l_a_i
+         %51 = OpFunctionCall %int %i
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %34 UMin %52 %uint_3
+         %54 = OpAccessChain %_ptr_Function_v3half %49 %53
+    %l_a_i_i = OpLoad %v3half %54 None
+         %57 = OpLoad %_arr_mat4x3_f16_std140_uint_4 %28 None
+               OpStore %58 %57
+               OpBranch %64
+         %64 = OpLabel
+               OpBranch %67
+         %67 = OpLabel
+         %69 = OpPhi %uint %uint_0 %64 %70 %66
+               OpLoopMerge %68 %66 None
+               OpBranch %65
+         %65 = OpLabel
+         %71 = OpUGreaterThanEqual %bool %69 %uint_4
+               OpSelectionMerge %73 None
+               OpBranchConditional %71 %74 %73
+         %74 = OpLabel
+               OpBranch %68
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Function_mat4v3half %60 %69
+         %76 = OpAccessChain %_ptr_Function_mat4x3_f16_std140 %58 %69
+         %78 = OpLoad %mat4x3_f16_std140 %76 None
+         %79 = OpCompositeExtract %v3half %78 0
+         %80 = OpCompositeExtract %v3half %78 1
+         %81 = OpCompositeExtract %v3half %78 2
+         %82 = OpCompositeExtract %v3half %78 3
+         %83 = OpCompositeConstruct %mat4v3half %79 %80 %81 %82
+               OpStore %75 %83 None
+               OpBranch %66
+         %66 = OpLabel
+         %70 = OpIAdd %uint %69 %uint_1
+               OpBranch %67
          %68 = OpLabel
-         %70 = OpAccessChain %_ptr_Function_mat4v3half %55 %64
-         %71 = OpAccessChain %_ptr_Function_mat4x3_f16_std140 %53 %64
-         %73 = OpLoad %mat4x3_f16_std140 %71 None
-         %74 = OpCompositeExtract %v3half %73 0
-         %75 = OpCompositeExtract %v3half %73 1
-         %76 = OpCompositeExtract %v3half %73 2
-         %77 = OpCompositeExtract %v3half %73 3
-         %78 = OpCompositeConstruct %mat4v3half %74 %75 %76 %77
-               OpStore %70 %78 None
-               OpBranch %61
-         %61 = OpLabel
-         %65 = OpIAdd %uint %64 %uint_1
-               OpBranch %62
-         %63 = OpLabel
-        %l_a = OpLoad %_arr_mat4v3half_uint_4 %55 None
-         %80 = OpCompositeExtract %half %l_a_i_i 0
-         %81 = OpCompositeExtract %half %l_a 0 0 0
-         %82 = OpFAdd %half %80 %81
-         %83 = OpCompositeExtract %half %l_a_i 0 0
-         %84 = OpFAdd %half %82 %83
+        %l_a = OpLoad %_arr_mat4v3half_uint_4 %60 None
          %85 = OpCompositeExtract %half %l_a_i_i 0
-         %86 = OpFAdd %half %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %87 %86 None
+         %86 = OpCompositeExtract %half %l_a 0 0 0
+         %87 = OpFAdd %half %85 %86
+         %88 = OpCompositeExtract %half %l_a_i 0 0
+         %89 = OpFAdd %half %87 %88
+         %90 = OpCompositeExtract %half %l_a_i_i 0
+         %91 = OpFAdd %half %89 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
index a90af29..790eab9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -19,7 +19,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x3 v_2 = f16mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
+  f16mat4x3 v_2 = f16mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
   mat4x3_f16_std140 v_3[4] = v.inner;
   f16mat4x3 v_4[4] = f16mat4x3[4](f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)), f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf)));
   {
@@ -39,6 +39,6 @@
   }
   f16mat4x3 l_a[4] = v_4;
   f16mat4x3 l_a_i = v_2;
-  f16vec3 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  f16vec3 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index c1ee3f4..e4682c2 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -53,6 +53,6 @@
   matrix<float16_t, 4, 3> l_a[4] = v_12(0u);
   matrix<float16_t, 4, 3> l_a_i = v_4(64u);
   vector<float16_t, 3> l_a_i_i = tint_bitcast_to_f16(a[4u].zw).xyz;
-  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[4u].z)) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[4u].z)) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 7f1fa48..7ce54a9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -49,8 +49,8 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* a [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_2 = (&(*p_a)[2]);
-  const constant packed_half3* const p_a_2_1 = (&(*p_a_2)[1].packed);
+  const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_2 = (&(*p_a)[2u]);
+  const constant packed_half3* const p_a_2_1 = (&(*p_a_2)[1u].packed);
   tint_array<half4x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f16_array_element, 4> const v_19 = (*p_a_2);
   half3 const v_20 = half3(v_19[0u].packed);
@@ -58,5 +58,5 @@
   half3 const v_22 = half3(v_19[2u].packed);
   half4x3 const l_a_i = half4x3(v_20, v_21, v_22, half3(v_19[3u].packed));
   half3 const l_a_i_i = half3((*p_a_2_1));
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
index e56a0c3..a0519fe 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -56,74 +56,72 @@
 %_ptr_Uniform__arr_mat4x3_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
 %_ptr_Function__arr_mat4x3_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x3_f16_std140_uint_4
 %_arr_mat4v3half_uint_4 = OpTypeArray %mat4v3half %uint_4
 %_ptr_Function__arr_mat4v3half_uint_4 = OpTypePointer Function %_arr_mat4v3half_uint_4
-         %43 = OpConstantNull %_arr_mat4v3half_uint_4
+         %41 = OpConstantNull %_arr_mat4v3half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_mat4x3_f16_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %43
+         %36 = OpVariable %_ptr_Function__arr_mat4x3_f16_std140_uint_4 Function
+         %38 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function %41
          %17 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f16_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_0
-         %24 = OpLoad %v3half %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_1
-         %27 = OpLoad %v3half %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_2
-         %30 = OpLoad %v3half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3half %17 %int_2 %uint_3
-         %33 = OpLoad %v3half %31 None
-      %l_a_i = OpCompositeConstruct %mat4v3half %24 %27 %30 %33
+         %20 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_0
+         %23 = OpLoad %v3half %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_1
+         %26 = OpLoad %v3half %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_2
+         %28 = OpLoad %v3half %27 None
+         %29 = OpAccessChain %_ptr_Uniform_v3half %17 %uint_2 %uint_3
+         %31 = OpLoad %v3half %29 None
+      %l_a_i = OpCompositeConstruct %mat4v3half %23 %26 %28 %31
     %l_a_i_i = OpCompositeExtract %v3half %l_a_i 1
-         %37 = OpLoad %_arr_mat4x3_f16_std140_uint_4 %17 None
-               OpStore %38 %37
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-         %49 = OpPhi %uint %uint_0 %44 %50 %46
-               OpLoopMerge %48 %46 None
+         %35 = OpLoad %_arr_mat4x3_f16_std140_uint_4 %17 None
+               OpStore %36 %35
+               OpBranch %42
+         %42 = OpLabel
                OpBranch %45
          %45 = OpLabel
-         %51 = OpUGreaterThanEqual %bool %49 %uint_4
-               OpSelectionMerge %53 None
-               OpBranchConditional %51 %54 %53
-         %54 = OpLabel
-               OpBranch %48
-         %53 = OpLabel
-         %55 = OpAccessChain %_ptr_Function_mat4v3half %40 %49
-         %57 = OpAccessChain %_ptr_Function_mat4x3_f16_std140 %38 %49
-         %59 = OpLoad %mat4x3_f16_std140 %57 None
-         %60 = OpCompositeExtract %v3half %59 0
-         %61 = OpCompositeExtract %v3half %59 1
-         %62 = OpCompositeExtract %v3half %59 2
-         %63 = OpCompositeExtract %v3half %59 3
-         %64 = OpCompositeConstruct %mat4v3half %60 %61 %62 %63
-               OpStore %55 %64 None
+         %47 = OpPhi %uint %uint_0 %42 %48 %44
+               OpLoopMerge %46 %44 None
+               OpBranch %43
+         %43 = OpLabel
+         %49 = OpUGreaterThanEqual %bool %47 %uint_4
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %52 %51
+         %52 = OpLabel
                OpBranch %46
+         %51 = OpLabel
+         %53 = OpAccessChain %_ptr_Function_mat4v3half %38 %47
+         %55 = OpAccessChain %_ptr_Function_mat4x3_f16_std140 %36 %47
+         %57 = OpLoad %mat4x3_f16_std140 %55 None
+         %58 = OpCompositeExtract %v3half %57 0
+         %59 = OpCompositeExtract %v3half %57 1
+         %60 = OpCompositeExtract %v3half %57 2
+         %61 = OpCompositeExtract %v3half %57 3
+         %62 = OpCompositeConstruct %mat4v3half %58 %59 %60 %61
+               OpStore %53 %62 None
+               OpBranch %44
+         %44 = OpLabel
+         %48 = OpIAdd %uint %47 %uint_1
+               OpBranch %45
          %46 = OpLabel
-         %50 = OpIAdd %uint %49 %uint_1
-               OpBranch %47
-         %48 = OpLabel
-        %l_a = OpLoad %_arr_mat4v3half_uint_4 %40 None
-         %66 = OpCompositeExtract %half %l_a_i_i 0
-         %67 = OpCompositeExtract %half %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat4v3half_uint_4 %38 None
+         %64 = OpCompositeExtract %half %l_a_i_i 0
+         %65 = OpCompositeExtract %half %l_a 0 0 0
+         %66 = OpFAdd %half %64 %65
+         %67 = OpCompositeExtract %half %l_a_i 0 0
          %68 = OpFAdd %half %66 %67
-         %69 = OpCompositeExtract %half %l_a_i 0 0
+         %69 = OpCompositeExtract %half %l_a_i_i 0
          %70 = OpFAdd %half %68 %69
-         %71 = OpCompositeExtract %half %l_a_i_i 0
-         %72 = OpFAdd %half %70 %71
-         %73 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %73 %72 None
+         %71 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %71 %70 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.glsl
index 413de80..8377777 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.glsl
@@ -19,9 +19,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x4 t = transpose(f16mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3));
-  float16_t l = length(v.inner[0].col1.zxy);
-  float16_t a = abs(v.inner[0].col1.zxy[0u]);
-  float16_t v_2 = (t[0][0u] + float16_t(l));
+  f16mat3x4 t = transpose(f16mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3));
+  float16_t l = length(v.inner[0u].col1.zxy);
+  float16_t a = abs(v.inner[0u].col1.zxy[0u]);
+  float16_t v_2 = (t[0u][0u] + float16_t(l));
   v_1.inner = (v_2 + float16_t(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
index d3ddd8e..b3f1010 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
   matrix<float16_t, 3, 4> t = transpose(v_4(64u));
   float16_t l = length(tint_bitcast_to_f16(u[0u].zw).xyz.zxy);
   float16_t a = abs(tint_bitcast_to_f16(u[0u].zw).xyz.zxy.x);
-  float16_t v_12 = (t[int(0)].x + float16_t(l));
+  float16_t v_12 = (t[0u].x + float16_t(l));
   s.Store<float16_t>(0u, (v_12 + float16_t(a)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
index 38ebcc0..2455fb9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -25,13 +25,13 @@
 
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*tint_module_vars.u)[2u];
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   half3 const v_3 = half3(v[2u].packed);
   half3x4 const t = transpose(half4x3(v_1, v_2, v_3, half3(v[3u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  half const a = abs(half3((*tint_module_vars.u)[0][1].packed).zxy[0u]);
-  half const v_4 = (t[0][0u] + half(l));
+  half const l = length(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  half const a = abs(half3((*tint_module_vars.u)[0u][1u].packed).zxy[0u]);
+  half const v_4 = (t[0u][0u] + half(l));
   (*tint_module_vars.s) = (v_4 + half(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.spvasm
index 27b966b..c0bc878 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 53
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %42 = OpExtInstImport "GLSL.std.450"
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,41 +55,38 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
      %v4half = OpTypeVector %half 4
  %mat3v4half = OpTypeMatrix %v4half 3
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v3half %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v3half %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v3half %26 None
-         %29 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %31 = OpLoad %v3half %29 None
-         %33 = OpCompositeConstruct %mat4v3half %22 %25 %28 %31
-          %t = OpTranspose %mat3v4half %33
-         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %39 = OpLoad %v3half %37 None
-         %40 = OpVectorShuffle %v3half %39 %39 2 0 1
-          %l = OpExtInst %half %42 Length %40
-         %43 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %44 = OpLoad %v3half %43 None
-         %45 = OpVectorShuffle %v3half %44 %44 2 0 1
-         %46 = OpCompositeExtract %half %45 0
-          %a = OpExtInst %half %42 FAbs %46
-         %48 = OpCompositeExtract %half %t 0 0
-         %49 = OpFAdd %half %48 %l
-         %50 = OpFAdd %half %49 %a
-         %51 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %51 %50 None
+         %17 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v3half %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v3half %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v3half %25 None
+         %27 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %29 = OpLoad %v3half %27 None
+         %31 = OpCompositeConstruct %mat4v3half %21 %24 %26 %29
+          %t = OpTranspose %mat3v4half %31
+         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v3half %35 None
+         %37 = OpVectorShuffle %v3half %36 %36 2 0 1
+          %l = OpExtInst %half %39 Length %37
+         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %41 = OpLoad %v3half %40 None
+         %42 = OpVectorShuffle %v3half %41 %41 2 0 1
+         %43 = OpCompositeExtract %half %42 0
+          %a = OpExtInst %half %39 FAbs %43
+         %45 = OpCompositeExtract %half %t 0 0
+         %46 = OpFAdd %half %45 %l
+         %47 = OpFAdd %half %46 %a
+         %48 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.glsl
index d61f0fa..6bd7a9f 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.glsl
@@ -18,10 +18,10 @@
   float16_t inner;
 } v_2;
 float16_t a(f16mat4x3 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float16_t b(f16mat4x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float16_t c(f16vec3 v) {
   return v[0u];
@@ -49,7 +49,7 @@
     }
   }
   float16_t v_7 = a(v_4);
-  float16_t v_8 = (v_7 + b(f16mat4x3(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2, v_1.inner[1].col3)));
-  float16_t v_9 = (v_8 + c(v_1.inner[1].col0.zxy));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.zxy[0u]));
+  float16_t v_8 = (v_7 + b(f16mat4x3(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2, v_1.inner[1u].col3)));
+  float16_t v_9 = (v_8 + c(v_1.inner[1u].col0.zxy));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
index 12cc5f1..64bea91 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float16_t a(matrix<float16_t, 4, 3> a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float16_t b(matrix<float16_t, 4, 3> m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float16_t c(vector<float16_t, 3> v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.msl
index 9057f56..850218d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.ir.msl
@@ -24,11 +24,11 @@
 };
 
 half a(tint_array<half4x3, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 half b(half4x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 half c(half3 v) {
@@ -65,11 +65,11 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   half const v_20 = a(tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[1];
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[1u];
   half3 const v_22 = half3(v_21[0u].packed);
   half3 const v_23 = half3(v_21[1u].packed);
   half3 const v_24 = half3(v_21[2u].packed);
   half const v_25 = (v_20 + b(half4x3(v_22, v_23, v_24, half3(v_21[3u].packed))));
-  half const v_26 = (v_25 + c(half3((*tint_module_vars.u)[1][0].packed).zxy));
-  (*tint_module_vars.s) = (v_26 + d(half3((*tint_module_vars.u)[1][0].packed).zxy[0u]));
+  half const v_26 = (v_25 + c(half3((*tint_module_vars.u)[1u][0u].packed).zxy));
+  (*tint_module_vars.s) = (v_26 + d(half3((*tint_module_vars.u)[1u][0u].packed).zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.spvasm
index e58504a..41fc632 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 100
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -74,8 +74,6 @@
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -139,29 +137,29 @@
          %51 = OpLabel
          %69 = OpLoad %_arr_mat4v3half_uint_4 %44 None
          %70 = OpFunctionCall %half %a %69
-         %71 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %75 = OpLoad %v3half %71 None
-         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_1
-         %77 = OpLoad %v3half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_2
-         %80 = OpLoad %v3half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_3
-         %83 = OpLoad %v3half %81 None
-         %84 = OpCompositeConstruct %mat4v3half %75 %77 %80 %83
-         %85 = OpFunctionCall %half %b %84
-         %86 = OpFAdd %half %70 %85
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %88 = OpLoad %v3half %87 None
-         %89 = OpVectorShuffle %v3half %88 %88 2 0 1
-         %90 = OpFunctionCall %half %c %89
-         %91 = OpFAdd %half %86 %90
-         %92 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_1 %uint_0
-         %93 = OpLoad %v3half %92 None
-         %94 = OpVectorShuffle %v3half %93 %93 2 0 1
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %half %d %95
-         %97 = OpFAdd %half %91 %96
-         %98 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %98 %97 None
+         %71 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %73 = OpLoad %v3half %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_1
+         %75 = OpLoad %v3half %74 None
+         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_2
+         %78 = OpLoad %v3half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_3
+         %81 = OpLoad %v3half %79 None
+         %82 = OpCompositeConstruct %mat4v3half %73 %75 %78 %81
+         %83 = OpFunctionCall %half %b %82
+         %84 = OpFAdd %half %70 %83
+         %85 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %86 = OpLoad %v3half %85 None
+         %87 = OpVectorShuffle %v3half %86 %86 2 0 1
+         %88 = OpFunctionCall %half %c %87
+         %89 = OpFAdd %half %84 %88
+         %90 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_1 %uint_0
+         %91 = OpLoad %v3half %90 None
+         %92 = OpVectorShuffle %v3half %91 %91 2 0 1
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %half %d %93
+         %95 = OpFAdd %half %89 %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %96 %95 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.glsl
index b51ce8d..d130b38 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.glsl
@@ -38,8 +38,8 @@
     }
   }
   p = v_3;
-  p[1] = f16mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  p[1][0] = v.inner[0].col1.zxy;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = f16mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  p[1u][0u] = v.inner[0u].col1.zxy;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 6aaadc7..3a92202 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -53,9 +53,9 @@
 void f() {
   matrix<float16_t, 4, 3> v_16[4] = v_12(0u);
   p = v_16;
-  p[int(1)] = v_4(64u);
-  p[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
-  p[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
-  s.Store<float16_t>(0u, p[int(1)][int(0)].x);
+  p[1u] = v_4(64u);
+  p[1u][0u] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
+  p[1u][0u].x = float16_t(f16tof32(u[0u].z));
+  s.Store<float16_t>(0u, p[1u][0u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.msl
index 5338c02..f93e05b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.ir.msl
@@ -51,12 +51,12 @@
   thread tint_array<half4x3, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_19 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_19 = (*tint_module_vars.u)[2u];
   half3 const v_20 = half3(v_19[0u].packed);
   half3 const v_21 = half3(v_19[1u].packed);
   half3 const v_22 = half3(v_19[2u].packed);
-  (*tint_module_vars.p)[1] = half4x3(v_20, v_21, v_22, half3(v_19[3u].packed));
-  (*tint_module_vars.p)[1][0] = half3((*tint_module_vars.u)[0][1].packed).zxy;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = half4x3(v_20, v_21, v_22, half3(v_19[3u].packed));
+  (*tint_module_vars.p)[1u][0u] = half3((*tint_module_vars.u)[0u][1u].packed).zxy;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.spvasm
index 272e37f..26d8095 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 88
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,14 +65,10 @@
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat4v3half = OpTypePointer Private %mat4v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -113,32 +109,32 @@
          %34 = OpLabel
          %52 = OpLoad %_arr_mat4v3half_uint_4 %28 None
                OpStore %p %52 None
-         %53 = OpAccessChain %_ptr_Private_mat4v3half %p %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v3half %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_Private_mat4v3half %p %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v3half %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v3half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v3half %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3half %66 None
-         %69 = OpCompositeConstruct %mat4v3half %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v3half %73 None
-         %75 = OpVectorShuffle %v3half %74 %74 2 0 1
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_half %77 %uint_0
-         %80 = OpLoad %half %78 None
-         %81 = OpAccessChain %_ptr_Private_half %76 %uint_0
-               OpStore %81 %80 None
-         %83 = OpAccessChain %_ptr_Private_v3half %p %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Private_half %83 %uint_0
-         %85 = OpLoad %half %84 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %86 %85 None
+         %66 = OpCompositeConstruct %mat4v3half %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v3half %69 None
+         %71 = OpVectorShuffle %v3half %70 %70 2 0 1
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_half %73 %uint_0
+         %76 = OpLoad %half %74 None
+         %77 = OpAccessChain %_ptr_Private_half %72 %uint_0
+               OpStore %77 %76 None
+         %79 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Private_half %79 %uint_0
+         %81 = OpLoad %half %80 None
+         %82 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %82 %81 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
index acb5e48..806b2fa 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -60,8 +60,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  f16mat4x3 v_8 = f16mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[1][0] = v.inner[0].col1.zxy;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  f16mat4x3 v_8 = f16mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[1u][0u] = v.inner[0u].col1.zxy;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.ir.msl
index c850e03..31309e8 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* u;
   device tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* s;
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -74,11 +78,11 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* u [[buffer(0)]], device tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[2u];
   half3 const v_22 = half3(v_21[0u].packed);
   half3 const v_23 = half3(v_21[1u].packed);
   half3 const v_24 = half3(v_21[2u].packed);
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), half4x3(v_22, v_23, v_24, half3(v_21[3u].packed)));
-  (*tint_module_vars.s)[1][0].packed = packed_half3(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.s)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), half4x3(v_22, v_23, v_24, half3(v_21[3u].packed)));
+  (*tint_module_vars.s)[1u][0u].packed = packed_half3(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.s)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
index df5e6a9..8f695b5 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -38,7 +41,8 @@
 
 void assign_and_preserve_padding(device tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* const dest, tint_array<half4x3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
index 1e6f8ba..9dcd5b8 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 117
+; Bound: 112
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,18 +70,14 @@
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_1 = OpConstant %int 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %87 = OpTypeFunction %void %_arr_mat4v3half_uint_4
-        %106 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
+         %82 = OpTypeFunction %void %_arr_mat4v3half_uint_4
+        %101 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
           %f = OpFunction %void None %17
          %18 = OpLabel
          %23 = OpVariable %_ptr_Function__arr_mat4x3_f16_std140_uint_4 Function
@@ -119,77 +115,76 @@
          %32 = OpLabel
          %50 = OpLoad %_arr_mat4v3half_uint_4 %25 None
          %51 = OpFunctionCall %void %tint_store_and_preserve_padding %50
-         %53 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %57 = OpLoad %v3half %53 None
-         %58 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %59 = OpLoad %v3half %58 None
-         %60 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %62 = OpLoad %v3half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %65 = OpLoad %v3half %63 None
-         %66 = OpCompositeConstruct %mat4v3half %57 %59 %62 %65
-         %67 = OpBitcast %uint %int_1
-         %70 = OpCompositeConstruct %_arr_uint_uint_1 %67
-         %71 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %70 %66
-         %73 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %77 = OpLoad %v3half %76 None
-         %78 = OpVectorShuffle %v3half %77 %77 2 0 1
-               OpStore %73 %78 None
-         %79 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %81 = OpAccessChain %_ptr_Uniform_half %80 %uint_0
-         %83 = OpLoad %half %81 None
-         %84 = OpAccessChain %_ptr_StorageBuffer_half %79 %uint_0
-               OpStore %84 %83 None
+         %53 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v3half %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v3half %57 None
+         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %60 = OpLoad %v3half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %63 = OpLoad %v3half %61 None
+         %64 = OpCompositeConstruct %mat4v3half %56 %58 %60 %63
+         %66 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %67 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %66 %64
+         %69 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %72 = OpLoad %v3half %71 None
+         %73 = OpVectorShuffle %v3half %72 %72 2 0 1
+               OpStore %69 %73 None
+         %74 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %uint_1 %uint_0
+         %75 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_half %75 %uint_0
+         %78 = OpLoad %half %76 None
+         %79 = OpAccessChain %_ptr_StorageBuffer_half %74 %uint_0
+               OpStore %79 %78 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %87
+%tint_store_and_preserve_padding = OpFunction %void None %82
 %value_param = OpFunctionParameter %_arr_mat4v3half_uint_4
+         %83 = OpLabel
+         %84 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function
+               OpStore %84 %value_param
+               OpBranch %85
+         %85 = OpLabel
+               OpBranch %88
          %88 = OpLabel
-         %89 = OpVariable %_ptr_Function__arr_mat4v3half_uint_4 Function
-               OpStore %89 %value_param
-               OpBranch %90
-         %90 = OpLabel
-               OpBranch %93
-         %93 = OpLabel
-         %95 = OpPhi %uint %uint_0 %90 %96 %92
-               OpLoopMerge %94 %92 None
-               OpBranch %91
-         %91 = OpLabel
-         %97 = OpUGreaterThanEqual %bool %95 %uint_4
-               OpSelectionMerge %98 None
-               OpBranchConditional %97 %99 %98
-         %99 = OpLabel
-               OpBranch %94
-         %98 = OpLabel
-        %100 = OpAccessChain %_ptr_Function_mat4v3half %89 %95
-        %101 = OpLoad %mat4v3half %100 None
-        %102 = OpCompositeConstruct %_arr_uint_uint_1 %95
-        %103 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %102 %101
-               OpBranch %92
-         %92 = OpLabel
-         %96 = OpIAdd %uint %95 %uint_1
-               OpBranch %93
+         %90 = OpPhi %uint %uint_0 %85 %91 %87
+               OpLoopMerge %89 %87 None
+               OpBranch %86
+         %86 = OpLabel
+         %92 = OpUGreaterThanEqual %bool %90 %uint_4
+               OpSelectionMerge %93 None
+               OpBranchConditional %92 %94 %93
          %94 = OpLabel
+               OpBranch %89
+         %93 = OpLabel
+         %95 = OpAccessChain %_ptr_Function_mat4v3half %84 %90
+         %96 = OpLoad %mat4v3half %95 None
+         %97 = OpCompositeConstruct %_arr_uint_uint_1 %90
+         %98 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %97 %96
+               OpBranch %87
+         %87 = OpLabel
+         %91 = OpIAdd %uint %90 %uint_1
+               OpBranch %88
+         %89 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %106
+%tint_store_and_preserve_padding_0 = OpFunction %void None %101
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat4v3half
-        %107 = OpLabel
-        %108 = OpCompositeExtract %uint %target_indices 0
-        %109 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %108 %uint_0
-        %110 = OpCompositeExtract %v3half %value_param_0 0
-               OpStore %109 %110 None
-        %111 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %108 %uint_1
-        %112 = OpCompositeExtract %v3half %value_param_0 1
-               OpStore %111 %112 None
-        %113 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %108 %uint_2
-        %114 = OpCompositeExtract %v3half %value_param_0 2
-               OpStore %113 %114 None
-        %115 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %108 %uint_3
-        %116 = OpCompositeExtract %v3half %value_param_0 3
-               OpStore %115 %116 None
+        %102 = OpLabel
+        %103 = OpCompositeExtract %uint %target_indices 0
+        %104 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %103 %uint_0
+        %105 = OpCompositeExtract %v3half %value_param_0 0
+               OpStore %104 %105 None
+        %106 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %103 %uint_1
+        %107 = OpCompositeExtract %v3half %value_param_0 1
+               OpStore %106 %107 None
+        %108 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %103 %uint_2
+        %109 = OpCompositeExtract %v3half %value_param_0 2
+               OpStore %108 %109 None
+        %110 = OpAccessChain %_ptr_StorageBuffer_v3half %10 %uint_0 %103 %uint_3
+        %111 = OpCompositeExtract %v3half %value_param_0 3
+               OpStore %110 %111 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.glsl
index 43ef6ff..3362684 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.glsl
@@ -49,9 +49,9 @@
     }
   }
   w = v_4;
-  w[1] = f16mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  w[1][0] = v.inner[0].col1.zxy;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = f16mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  w[1u][0u] = v.inner[0u].col1.zxy;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index f719909..8e20d35 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -71,9 +71,9 @@
   GroupMemoryBarrierWithGroupSync();
   matrix<float16_t, 4, 3> v_18[4] = v_12(0u);
   w = v_18;
-  w[int(1)] = v_4(64u);
-  w[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
-  w[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
+  w[1u] = v_4(64u);
+  w[1u][0u] = tint_bitcast_to_f16(u[0u].zw).xyz.zxy;
+  w[1u][0u].x = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
index 4aeb333..6e6d4df 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -23,6 +23,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4> tint_symbol;
 };
@@ -74,6 +77,7 @@
     uint v_19 = 0u;
     v_19 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_20 = v_19;
       if ((v_20 >= 4u)) {
         break;
@@ -90,17 +94,17 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_21 = (*tint_module_vars.u)[2u];
   half3 const v_22 = half3(v_21[0u].packed);
   half3 const v_23 = half3(v_21[1u].packed);
   half3 const v_24 = half3(v_21[2u].packed);
   half4x3 const v_25 = half4x3(v_22, v_23, v_24, half3(v_21[3u].packed));
-  (*tint_module_vars.w)[1][0u].packed = packed_half3(v_25[0u]);
-  (*tint_module_vars.w)[1][1u].packed = packed_half3(v_25[1u]);
-  (*tint_module_vars.w)[1][2u].packed = packed_half3(v_25[2u]);
-  (*tint_module_vars.w)[1][3u].packed = packed_half3(v_25[3u]);
-  (*tint_module_vars.w)[1][0].packed = packed_half3(half3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.w)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  (*tint_module_vars.w)[1u][0u].packed = packed_half3(v_25[0u]);
+  (*tint_module_vars.w)[1u][1u].packed = packed_half3(v_25[1u]);
+  (*tint_module_vars.w)[1u][2u].packed = packed_half3(v_25[2u]);
+  (*tint_module_vars.w)[1u][3u].packed = packed_half3(v_25[3u]);
+  (*tint_module_vars.w)[1u][0u].packed = packed_half3(half3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.w)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_26 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.msl
index 8d45195..531a1fe 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f16_array_element, 4>, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = tint_pack_vec3_in_composite(half4x3(half3(0.0h), half3(0.0h), half3(0.0h), half3(0.0h)));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
index 709c070..12f1e68 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 102
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -64,16 +64,12 @@
          %47 = OpConstantNull %_arr_mat4v3half_uint_4
 %_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
 %_ptr_Function_mat4x3_f16_std140 = OpTypePointer Function %mat4x3_f16_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-      %int_2 = OpConstant %int 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %98 = OpTypeFunction %void
+         %94 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -134,33 +130,33 @@
          %52 = OpLabel
          %68 = OpLoad %_arr_mat4v3half_uint_4 %45 None
                OpStore %w %68 None
-         %69 = OpAccessChain %_ptr_Workgroup_mat4v3half %w %int_1
-         %72 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_0
-         %75 = OpLoad %v3half %72 None
-         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %77 = OpLoad %v3half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3half %78 None
-         %80 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3half %80 None
-         %83 = OpCompositeConstruct %mat4v3half %75 %77 %79 %82
-               OpStore %69 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %88 = OpLoad %v3half %87 None
-         %89 = OpVectorShuffle %v3half %88 %88 2 0 1
-               OpStore %84 %89 None
-         %90 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %int_0
-         %91 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_1
-         %92 = OpAccessChain %_ptr_Uniform_half %91 %uint_0
-         %94 = OpLoad %half %92 None
-         %95 = OpAccessChain %_ptr_Workgroup_half %90 %uint_0
-               OpStore %95 %94 None
+         %69 = OpAccessChain %_ptr_Workgroup_mat4v3half %w %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_0
+         %72 = OpLoad %v3half %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %74 = OpLoad %v3half %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %76 = OpLoad %v3half %75 None
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %79 = OpLoad %v3half %77 None
+         %80 = OpCompositeConstruct %mat4v3half %72 %74 %76 %79
+               OpStore %69 %80 None
+         %81 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %84 = OpLoad %v3half %83 None
+         %85 = OpVectorShuffle %v3half %84 %84 2 0 1
+               OpStore %81 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_0
+         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_1
+         %88 = OpAccessChain %_ptr_Uniform_half %87 %uint_0
+         %90 = OpLoad %half %88 None
+         %91 = OpAccessChain %_ptr_Workgroup_half %86 %uint_0
+               OpStore %91 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %98
-         %99 = OpLabel
-        %100 = OpLoad %uint %f_local_invocation_index_Input None
-        %101 = OpFunctionCall %void %f_inner %100
+          %f = OpFunction %void None %94
+         %95 = OpLabel
+         %96 = OpLoad %uint %f_local_invocation_index_Input None
+         %97 = OpFunctionCall %void %f_inner %96
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 2df648f..adf319d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -33,10 +33,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x3 l_a[4] = a_load(0u);
-  float4x3 l_a_i = a_load_1((64u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float4x3 l_a_i = a_load_1((64u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_4 / 4].xyz);
-  const uint scalar_offset_5 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 2df648f..adf319d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -33,10 +33,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x3 l_a[4] = a_load(0u);
-  float4x3 l_a_i = a_load_1((64u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float4x3 l_a_i = a_load_1((64u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   float3 l_a_i_i = asfloat(a[scalar_offset_4 / 4].xyz);
-  const uint scalar_offset_5 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index bb93a08..ca268ff 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -27,9 +27,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   mat4x3 v_3 = mat4x3(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2, v.inner[v_2].col3);
-  vec3 v_4 = v_3[i()];
+  vec3 v_4 = v_3[min(uint(i()), 3u)];
   mat4x3_f32_std140 v_5[4] = v.inner;
   mat4x3 v_6[4] = mat4x3[4](mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   {
@@ -50,5 +50,5 @@
   mat4x3 l_a[4] = v_6;
   mat4x3 l_a_i = v_3;
   vec3 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 5d50185..b754a19 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (64u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (64u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 3u)));
   float4x3 l_a[4] = v_1(0u);
   float4x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 5d50185..b754a19 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (64u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (64u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 3u)));
   float4x3 l_a[4] = v_1(0u);
   float4x3 l_a_i = v(v_5);
   float3 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)].xyz);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index f9e9bd6..bf013f3 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -56,8 +56,8 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant packed_float3* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<float4x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 4> const v_19 = (*p_a_i);
   float3 const v_20 = float3(v_19[0u].packed);
@@ -65,5 +65,5 @@
   float3 const v_22 = float3(v_19[2u].packed);
   float4x3 const l_a_i = float4x3(v_20, v_21, v_22, float3(v_19[3u].packed));
   float3 const l_a_i_i = float3((*p_a_i_i));
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 1283bf3..7f75df1 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -42,9 +42,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<float4x3, 4> const l_a = tint_unpack_vec3_in_composite_1(*(tint_symbol_2));
   float4x3 const l_a_i = tint_unpack_vec3_in_composite((*(tint_symbol_2))[p_a_i_save]);
   float3 const l_a_i_i = float3((*(tint_symbol_2))[p_a_i_save][p_a_i_i_save].elements);
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 89240a4..3fbe569 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -60,17 +61,17 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
 %_ptr_Function__arr_mat4x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat4x3_f32_std140_uint_4
 %_arr_mat4v3float_uint_4 = OpTypeArray %mat4v3float %uint_4
 %_ptr_Function__arr_mat4v3float_uint_4 = OpTypePointer Function %_arr_mat4v3float_uint_4
-         %58 = OpConstantNull %_arr_mat4v3float_uint_4
+         %63 = OpConstantNull %_arr_mat4v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -84,63 +85,67 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat4v3float Function
-         %53 = OpVariable %_ptr_Function__arr_mat4x3_f32_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function %58
+         %49 = OpVariable %_ptr_Function_mat4v3float Function
+         %58 = OpVariable %_ptr_Function__arr_mat4x3_f32_std140_uint_4 Function
+         %60 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function %63
          %28 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f32_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_0
-         %34 = OpLoad %v3float %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_1
-         %37 = OpLoad %v3float %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_2
-         %40 = OpLoad %v3float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3float %28 %31 %uint_3
-         %43 = OpLoad %v3float %41 None
-      %l_a_i = OpCompositeConstruct %mat4v3float %34 %37 %40 %43
-               OpStore %46 %l_a_i
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v3float %46 %48
-    %l_a_i_i = OpLoad %v3float %49 None
-         %52 = OpLoad %_arr_mat4x3_f32_std140_uint_4 %28 None
-               OpStore %53 %52
-               OpBranch %59
-         %59 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-         %64 = OpPhi %uint %uint_0 %59 %65 %61
-               OpLoopMerge %63 %61 None
-               OpBranch %60
-         %60 = OpLabel
-         %66 = OpUGreaterThanEqual %bool %64 %uint_4
-               OpSelectionMerge %68 None
-               OpBranchConditional %66 %69 %68
-         %69 = OpLabel
-               OpBranch %63
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_0
+         %38 = OpLoad %v3float %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_1
+         %41 = OpLoad %v3float %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_2
+         %44 = OpLoad %v3float %42 None
+         %45 = OpAccessChain %_ptr_Uniform_v3float %28 %33 %uint_3
+         %46 = OpLoad %v3float %45 None
+      %l_a_i = OpCompositeConstruct %mat4v3float %38 %41 %44 %46
+               OpStore %49 %l_a_i
+         %51 = OpFunctionCall %int %i
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %34 UMin %52 %uint_3
+         %54 = OpAccessChain %_ptr_Function_v3float %49 %53
+    %l_a_i_i = OpLoad %v3float %54 None
+         %57 = OpLoad %_arr_mat4x3_f32_std140_uint_4 %28 None
+               OpStore %58 %57
+               OpBranch %64
+         %64 = OpLabel
+               OpBranch %67
+         %67 = OpLabel
+         %69 = OpPhi %uint %uint_0 %64 %70 %66
+               OpLoopMerge %68 %66 None
+               OpBranch %65
+         %65 = OpLabel
+         %71 = OpUGreaterThanEqual %bool %69 %uint_4
+               OpSelectionMerge %73 None
+               OpBranchConditional %71 %74 %73
+         %74 = OpLabel
+               OpBranch %68
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Function_mat4v3float %60 %69
+         %76 = OpAccessChain %_ptr_Function_mat4x3_f32_std140 %58 %69
+         %78 = OpLoad %mat4x3_f32_std140 %76 None
+         %79 = OpCompositeExtract %v3float %78 0
+         %80 = OpCompositeExtract %v3float %78 1
+         %81 = OpCompositeExtract %v3float %78 2
+         %82 = OpCompositeExtract %v3float %78 3
+         %83 = OpCompositeConstruct %mat4v3float %79 %80 %81 %82
+               OpStore %75 %83 None
+               OpBranch %66
+         %66 = OpLabel
+         %70 = OpIAdd %uint %69 %uint_1
+               OpBranch %67
          %68 = OpLabel
-         %70 = OpAccessChain %_ptr_Function_mat4v3float %55 %64
-         %71 = OpAccessChain %_ptr_Function_mat4x3_f32_std140 %53 %64
-         %73 = OpLoad %mat4x3_f32_std140 %71 None
-         %74 = OpCompositeExtract %v3float %73 0
-         %75 = OpCompositeExtract %v3float %73 1
-         %76 = OpCompositeExtract %v3float %73 2
-         %77 = OpCompositeExtract %v3float %73 3
-         %78 = OpCompositeConstruct %mat4v3float %74 %75 %76 %77
-               OpStore %70 %78 None
-               OpBranch %61
-         %61 = OpLabel
-         %65 = OpIAdd %uint %64 %uint_1
-               OpBranch %62
-         %63 = OpLabel
-        %l_a = OpLoad %_arr_mat4v3float_uint_4 %55 None
-         %80 = OpCompositeExtract %float %l_a_i_i 0
-         %81 = OpCompositeExtract %float %l_a 0 0 0
-         %82 = OpFAdd %float %80 %81
-         %83 = OpCompositeExtract %float %l_a_i 0 0
-         %84 = OpFAdd %float %82 %83
+        %l_a = OpLoad %_arr_mat4v3float_uint_4 %60 None
          %85 = OpCompositeExtract %float %l_a_i_i 0
-         %86 = OpFAdd %float %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %87 %86 None
+         %86 = OpCompositeExtract %float %l_a 0 0 0
+         %87 = OpFAdd %float %85 %86
+         %88 = OpCompositeExtract %float %l_a_i 0 0
+         %89 = OpFAdd %float %87 %88
+         %90 = OpCompositeExtract %float %l_a_i_i 0
+         %91 = OpFAdd %float %89 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 5e19699..bce2e5d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -22,7 +22,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x3 v_2 = mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
+  mat4x3 v_2 = mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
   mat4x3_f32_std140 v_3[4] = v.inner;
   mat4x3 v_4[4] = mat4x3[4](mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)), mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f)));
   {
@@ -42,6 +42,6 @@
   }
   mat4x3 l_a[4] = v_4;
   mat4x3 l_a_i = v_2;
-  vec3 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  vec3 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 6dd89a5..3b4f0e9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float4x3 l_a[4] = v_1(0u);
   float4x3 l_a_i = v(128u);
   float3 l_a_i_i = asfloat(a[9u].xyz);
-  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 6dd89a5..3b4f0e9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float4x3 l_a[4] = v_1(0u);
   float4x3 l_a_i = v(128u);
   float3 l_a_i_i = asfloat(a[9u].xyz);
-  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index df0d041..ec2e969 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -49,8 +49,8 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* const p_a = tint_module_vars.a;
-  const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_2 = (&(*p_a)[2]);
-  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1].packed);
+  const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_2 = (&(*p_a)[2u]);
+  const constant packed_float3* const p_a_2_1 = (&(*p_a_2)[1u].packed);
   tint_array<float4x3, 4> const l_a = tint_load_array_packed_vec3(p_a);
   tint_array<tint_packed_vec3_f32_array_element, 4> const v_19 = (*p_a_2);
   float3 const v_20 = float3(v_19[0u].packed);
@@ -58,5 +58,5 @@
   float3 const v_22 = float3(v_19[2u].packed);
   float4x3 const l_a_i = float4x3(v_20, v_21, v_22, float3(v_19[3u].packed));
   float3 const l_a_i_i = float3((*p_a_2_1));
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index 603e590..ed662c9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -53,74 +53,72 @@
 %_ptr_Uniform__arr_mat4x3_f32_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x3_f32_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Function__arr_mat4x3_f32_std140_uint_4 = OpTypePointer Function %_arr_mat4x3_f32_std140_uint_4
 %_arr_mat4v3float_uint_4 = OpTypeArray %mat4v3float %uint_4
 %_ptr_Function__arr_mat4v3float_uint_4 = OpTypePointer Function %_arr_mat4v3float_uint_4
-         %43 = OpConstantNull %_arr_mat4v3float_uint_4
+         %41 = OpConstantNull %_arr_mat4v3float_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_mat4x3_f32_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function %43
+         %36 = OpVariable %_ptr_Function__arr_mat4x3_f32_std140_uint_4 Function
+         %38 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function %41
          %17 = OpAccessChain %_ptr_Uniform__arr_mat4x3_f32_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_0
-         %24 = OpLoad %v3float %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_1
-         %27 = OpLoad %v3float %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_2
-         %30 = OpLoad %v3float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3float %17 %int_2 %uint_3
-         %33 = OpLoad %v3float %31 None
-      %l_a_i = OpCompositeConstruct %mat4v3float %24 %27 %30 %33
+         %20 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_0
+         %23 = OpLoad %v3float %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_1
+         %26 = OpLoad %v3float %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_2
+         %28 = OpLoad %v3float %27 None
+         %29 = OpAccessChain %_ptr_Uniform_v3float %17 %uint_2 %uint_3
+         %31 = OpLoad %v3float %29 None
+      %l_a_i = OpCompositeConstruct %mat4v3float %23 %26 %28 %31
     %l_a_i_i = OpCompositeExtract %v3float %l_a_i 1
-         %37 = OpLoad %_arr_mat4x3_f32_std140_uint_4 %17 None
-               OpStore %38 %37
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-         %49 = OpPhi %uint %uint_0 %44 %50 %46
-               OpLoopMerge %48 %46 None
+         %35 = OpLoad %_arr_mat4x3_f32_std140_uint_4 %17 None
+               OpStore %36 %35
+               OpBranch %42
+         %42 = OpLabel
                OpBranch %45
          %45 = OpLabel
-         %51 = OpUGreaterThanEqual %bool %49 %uint_4
-               OpSelectionMerge %53 None
-               OpBranchConditional %51 %54 %53
-         %54 = OpLabel
-               OpBranch %48
-         %53 = OpLabel
-         %55 = OpAccessChain %_ptr_Function_mat4v3float %40 %49
-         %57 = OpAccessChain %_ptr_Function_mat4x3_f32_std140 %38 %49
-         %59 = OpLoad %mat4x3_f32_std140 %57 None
-         %60 = OpCompositeExtract %v3float %59 0
-         %61 = OpCompositeExtract %v3float %59 1
-         %62 = OpCompositeExtract %v3float %59 2
-         %63 = OpCompositeExtract %v3float %59 3
-         %64 = OpCompositeConstruct %mat4v3float %60 %61 %62 %63
-               OpStore %55 %64 None
+         %47 = OpPhi %uint %uint_0 %42 %48 %44
+               OpLoopMerge %46 %44 None
+               OpBranch %43
+         %43 = OpLabel
+         %49 = OpUGreaterThanEqual %bool %47 %uint_4
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %52 %51
+         %52 = OpLabel
                OpBranch %46
+         %51 = OpLabel
+         %53 = OpAccessChain %_ptr_Function_mat4v3float %38 %47
+         %55 = OpAccessChain %_ptr_Function_mat4x3_f32_std140 %36 %47
+         %57 = OpLoad %mat4x3_f32_std140 %55 None
+         %58 = OpCompositeExtract %v3float %57 0
+         %59 = OpCompositeExtract %v3float %57 1
+         %60 = OpCompositeExtract %v3float %57 2
+         %61 = OpCompositeExtract %v3float %57 3
+         %62 = OpCompositeConstruct %mat4v3float %58 %59 %60 %61
+               OpStore %53 %62 None
+               OpBranch %44
+         %44 = OpLabel
+         %48 = OpIAdd %uint %47 %uint_1
+               OpBranch %45
          %46 = OpLabel
-         %50 = OpIAdd %uint %49 %uint_1
-               OpBranch %47
-         %48 = OpLabel
-        %l_a = OpLoad %_arr_mat4v3float_uint_4 %40 None
-         %66 = OpCompositeExtract %float %l_a_i_i 0
-         %67 = OpCompositeExtract %float %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat4v3float_uint_4 %38 None
+         %64 = OpCompositeExtract %float %l_a_i_i 0
+         %65 = OpCompositeExtract %float %l_a 0 0 0
+         %66 = OpFAdd %float %64 %65
+         %67 = OpCompositeExtract %float %l_a_i 0 0
          %68 = OpFAdd %float %66 %67
-         %69 = OpCompositeExtract %float %l_a_i 0 0
+         %69 = OpCompositeExtract %float %l_a_i_i 0
          %70 = OpFAdd %float %68 %69
-         %71 = OpCompositeExtract %float %l_a_i_i 0
-         %72 = OpFAdd %float %70 %71
-         %73 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %73 %72 None
+         %71 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %71 %70 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.glsl
index f8bedf6..ced9162 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.glsl
@@ -22,9 +22,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3x4 t = transpose(mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3));
-  float l = length(v.inner[0].col1.zxy);
-  float a = abs(v.inner[0].col1.zxy[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat3x4 t = transpose(mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3));
+  float l = length(v.inner[0u].col1.zxy);
+  float a = abs(v.inner[0u].col1.zxy[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 9b2aeb1..9579ac7 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float3x4 t = transpose(v(128u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 9b2aeb1..9579ac7 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float3x4 t = transpose(v(128u));
   float l = length(asfloat(u[1u].xyz).zxy);
   float a = abs(asfloat(u[1u].xyz).zxy.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
index 2bf760d..4c8a85b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -25,13 +25,13 @@
 
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*tint_module_vars.u)[2u];
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   float3 const v_3 = float3(v[2u].packed);
   float3x4 const t = transpose(float4x3(v_1, v_2, v_3, float3(v[3u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0][1].packed).zxy[0u]);
-  float const v_4 = (t[0][0u] + float(l));
+  float const l = length(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u][1u].packed).zxy[0u]);
+  float const v_4 = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v_4 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.spvasm
index 1d9d7c2..a8e3731 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 53
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
-         %42 = OpExtInstImport "GLSL.std.450"
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -52,41 +52,38 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
     %v4float = OpTypeVector %float 4
 %mat3v4float = OpTypeMatrix %v4float 3
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v3float %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v3float %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v3float %26 None
-         %29 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %31 = OpLoad %v3float %29 None
-         %33 = OpCompositeConstruct %mat4v3float %22 %25 %28 %31
-          %t = OpTranspose %mat3v4float %33
-         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %39 = OpLoad %v3float %37 None
-         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
-          %l = OpExtInst %float %42 Length %40
-         %43 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %44 = OpLoad %v3float %43 None
-         %45 = OpVectorShuffle %v3float %44 %44 2 0 1
-         %46 = OpCompositeExtract %float %45 0
-          %a = OpExtInst %float %42 FAbs %46
-         %48 = OpCompositeExtract %float %t 0 0
-         %49 = OpFAdd %float %48 %l
-         %50 = OpFAdd %float %49 %a
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %51 %50 None
+         %17 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v3float %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v3float %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v3float %25 None
+         %27 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %29 = OpLoad %v3float %27 None
+         %31 = OpCompositeConstruct %mat4v3float %21 %24 %26 %29
+          %t = OpTranspose %mat3v4float %31
+         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %36 = OpLoad %v3float %35 None
+         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
+          %l = OpExtInst %float %39 Length %37
+         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %41 = OpLoad %v3float %40 None
+         %42 = OpVectorShuffle %v3float %41 %41 2 0 1
+         %43 = OpCompositeExtract %float %42 0
+          %a = OpExtInst %float %39 FAbs %43
+         %45 = OpCompositeExtract %float %t 0 0
+         %46 = OpFAdd %float %45 %l
+         %47 = OpFAdd %float %46 %a
+         %48 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.glsl
index 058a933..8343a7c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.glsl
@@ -21,10 +21,10 @@
   float inner;
 } v_2;
 float a(mat4x3 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat4x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec3 v) {
   return v[0u];
@@ -52,7 +52,7 @@
     }
   }
   float v_7 = a(v_4);
-  float v_8 = (v_7 + b(mat4x3(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2, v_1.inner[1].col3)));
-  float v_9 = (v_8 + c(v_1.inner[1].col0.zxy));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.zxy[0u]));
+  float v_8 = (v_7 + b(mat4x3(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2, v_1.inner[1u].col3)));
+  float v_9 = (v_8 + c(v_1.inner[1u].col0.zxy));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index cabb32a..d343557 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index cabb32a..d343557 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x3 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x3 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float3 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.msl
index f586308..26b97d2 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.ir.msl
@@ -24,11 +24,11 @@
 };
 
 float a(tint_array<float4x3, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float4x3 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float3 v) {
@@ -65,11 +65,11 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_20 = a(tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[1];
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[1u];
   float3 const v_22 = float3(v_21[0u].packed);
   float3 const v_23 = float3(v_21[1u].packed);
   float3 const v_24 = float3(v_21[2u].packed);
   float const v_25 = (v_20 + b(float4x3(v_22, v_23, v_24, float3(v_21[3u].packed))));
-  float const v_26 = (v_25 + c(float3((*tint_module_vars.u)[1][0].packed).zxy));
-  (*tint_module_vars.s) = (v_26 + d(float3((*tint_module_vars.u)[1][0].packed).zxy[0u]));
+  float const v_26 = (v_25 + c(float3((*tint_module_vars.u)[1u][0u].packed).zxy));
+  (*tint_module_vars.s) = (v_26 + d(float3((*tint_module_vars.u)[1u][0u].packed).zxy[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.spvasm
index 3606365..dc54d76 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 100
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -71,8 +71,6 @@
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -136,29 +134,29 @@
          %51 = OpLabel
          %69 = OpLoad %_arr_mat4v3float_uint_4 %44 None
          %70 = OpFunctionCall %float %a %69
-         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %75 = OpLoad %v3float %71 None
-         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_1
-         %77 = OpLoad %v3float %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_2
-         %80 = OpLoad %v3float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_3
-         %83 = OpLoad %v3float %81 None
-         %84 = OpCompositeConstruct %mat4v3float %75 %77 %80 %83
-         %85 = OpFunctionCall %float %b %84
-         %86 = OpFAdd %float %70 %85
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %88 = OpLoad %v3float %87 None
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-         %90 = OpFunctionCall %float %c %89
-         %91 = OpFAdd %float %86 %90
-         %92 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_1 %uint_0
-         %93 = OpLoad %v3float %92 None
-         %94 = OpVectorShuffle %v3float %93 %93 2 0 1
-         %95 = OpCompositeExtract %float %94 0
-         %96 = OpFunctionCall %float %d %95
-         %97 = OpFAdd %float %91 %96
-         %98 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %98 %97 None
+         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %73 = OpLoad %v3float %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_1
+         %75 = OpLoad %v3float %74 None
+         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_2
+         %78 = OpLoad %v3float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_3
+         %81 = OpLoad %v3float %79 None
+         %82 = OpCompositeConstruct %mat4v3float %73 %75 %78 %81
+         %83 = OpFunctionCall %float %b %82
+         %84 = OpFAdd %float %70 %83
+         %85 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %86 = OpLoad %v3float %85 None
+         %87 = OpVectorShuffle %v3float %86 %86 2 0 1
+         %88 = OpFunctionCall %float %c %87
+         %89 = OpFAdd %float %84 %88
+         %90 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_1 %uint_0
+         %91 = OpLoad %v3float %90 None
+         %92 = OpVectorShuffle %v3float %91 %91 2 0 1
+         %93 = OpCompositeExtract %float %92 0
+         %94 = OpFunctionCall %float %d %93
+         %95 = OpFAdd %float %89 %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %96 %95 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.glsl
index 9928c8d..7ab4e8c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.glsl
@@ -41,8 +41,8 @@
     }
   }
   p = v_3;
-  p[1] = mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  p[1][0] = v.inner[0].col1.zxy;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  p[1u][0u] = v.inner[0u].col1.zxy;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index f5e71a0..a0b6b9b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float4x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(128u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(128u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index f5e71a0..a0b6b9b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float4x3 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(128u);
-  p[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(128u);
+  p[1u][0u] = asfloat(u[1u].xyz).zxy;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.msl
index f073403..c769997 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.ir.msl
@@ -51,12 +51,12 @@
   thread tint_array<float4x3, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_19 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_19 = (*tint_module_vars.u)[2u];
   float3 const v_20 = float3(v_19[0u].packed);
   float3 const v_21 = float3(v_19[1u].packed);
   float3 const v_22 = float3(v_19[2u].packed);
-  (*tint_module_vars.p)[1] = float4x3(v_20, v_21, v_22, float3(v_19[3u].packed));
-  (*tint_module_vars.p)[1][0] = float3((*tint_module_vars.u)[0][1].packed).zxy;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1].packed[0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = float4x3(v_20, v_21, v_22, float3(v_19[3u].packed));
+  (*tint_module_vars.p)[1u][0u] = float3((*tint_module_vars.u)[0u][1u].packed).zxy;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.spvasm
index 7ced360..99c212e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 88
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -62,14 +62,10 @@
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat4v3float = OpTypePointer Private %mat4v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -110,32 +106,32 @@
          %34 = OpLabel
          %52 = OpLoad %_arr_mat4v3float_uint_4 %28 None
                OpStore %p %52 None
-         %53 = OpAccessChain %_ptr_Private_mat4v3float %p %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v3float %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_Private_mat4v3float %p %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v3float %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v3float %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v3float %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3float %66 None
-         %69 = OpCompositeConstruct %mat4v3float %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v3float %73 None
-         %75 = OpVectorShuffle %v3float %74 %74 2 0 1
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_float %77 %uint_0
-         %80 = OpLoad %float %78 None
-         %81 = OpAccessChain %_ptr_Private_float %76 %uint_0
-               OpStore %81 %80 None
-         %83 = OpAccessChain %_ptr_Private_v3float %p %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Private_float %83 %uint_0
-         %85 = OpLoad %float %84 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %86 %85 None
+         %66 = OpCompositeConstruct %mat4v3float %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v3float %69 None
+         %71 = OpVectorShuffle %v3float %70 %70 2 0 1
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_float %73 %uint_0
+         %76 = OpLoad %float %74 None
+         %77 = OpAccessChain %_ptr_Private_float %72 %uint_0
+               OpStore %77 %76 None
+         %79 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Private_float %79 %uint_0
+         %81 = OpLoad %float %80 None
+         %82 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %82 %81 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
index 5bfa764..103cfbb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -63,8 +63,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  mat4x3 v_8 = mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[1][0] = v.inner[0].col1.zxy;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  mat4x3 v_8 = mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[1u][0u] = v.inner[0u].col1.zxy;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.ir.msl
index 001068f..adc90bb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* u;
   device tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* s;
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -74,11 +78,11 @@
 kernel void f(const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* u [[buffer(0)]], device tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[2u];
   float3 const v_22 = float3(v_21[0u].packed);
   float3 const v_23 = float3(v_21[1u].packed);
   float3 const v_24 = float3(v_21[2u].packed);
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), float4x3(v_22, v_23, v_24, float3(v_21[3u].packed)));
-  (*tint_module_vars.s)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.s)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), float4x3(v_22, v_23, v_24, float3(v_21[3u].packed)));
+  (*tint_module_vars.s)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.s)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
index 48c654b..cfe02ef 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -38,7 +41,8 @@
 
 void assign_and_preserve_padding(device tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* const dest, tint_array<float4x3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
index a7fd472..daf554c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 117
+; Bound: 112
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -67,18 +67,14 @@
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_1 = OpConstant %int 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %87 = OpTypeFunction %void %_arr_mat4v3float_uint_4
-        %106 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+         %82 = OpTypeFunction %void %_arr_mat4v3float_uint_4
+        %101 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %23 = OpVariable %_ptr_Function__arr_mat4x3_f32_std140_uint_4 Function
@@ -116,77 +112,76 @@
          %32 = OpLabel
          %50 = OpLoad %_arr_mat4v3float_uint_4 %25 None
          %51 = OpFunctionCall %void %tint_store_and_preserve_padding %50
-         %53 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %57 = OpLoad %v3float %53 None
-         %58 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %59 = OpLoad %v3float %58 None
-         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %62 = OpLoad %v3float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %65 = OpLoad %v3float %63 None
-         %66 = OpCompositeConstruct %mat4v3float %57 %59 %62 %65
-         %67 = OpBitcast %uint %int_1
-         %70 = OpCompositeConstruct %_arr_uint_uint_1 %67
-         %71 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %70 %66
-         %73 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %77 = OpLoad %v3float %76 None
-         %78 = OpVectorShuffle %v3float %77 %77 2 0 1
-               OpStore %73 %78 None
-         %79 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %int_1 %int_0
-         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %81 = OpAccessChain %_ptr_Uniform_float %80 %uint_0
-         %83 = OpLoad %float %81 None
-         %84 = OpAccessChain %_ptr_StorageBuffer_float %79 %uint_0
-               OpStore %84 %83 None
+         %53 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %56 = OpLoad %v3float %53 None
+         %57 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %58 = OpLoad %v3float %57 None
+         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %60 = OpLoad %v3float %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %63 = OpLoad %v3float %61 None
+         %64 = OpCompositeConstruct %mat4v3float %56 %58 %60 %63
+         %66 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %67 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %66 %64
+         %69 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %72 = OpLoad %v3float %71 None
+         %73 = OpVectorShuffle %v3float %72 %72 2 0 1
+               OpStore %69 %73 None
+         %74 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %uint_1 %uint_0
+         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_float %75 %uint_0
+         %78 = OpLoad %float %76 None
+         %79 = OpAccessChain %_ptr_StorageBuffer_float %74 %uint_0
+               OpStore %79 %78 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %87
+%tint_store_and_preserve_padding = OpFunction %void None %82
 %value_param = OpFunctionParameter %_arr_mat4v3float_uint_4
+         %83 = OpLabel
+         %84 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function
+               OpStore %84 %value_param
+               OpBranch %85
+         %85 = OpLabel
+               OpBranch %88
          %88 = OpLabel
-         %89 = OpVariable %_ptr_Function__arr_mat4v3float_uint_4 Function
-               OpStore %89 %value_param
-               OpBranch %90
-         %90 = OpLabel
-               OpBranch %93
-         %93 = OpLabel
-         %95 = OpPhi %uint %uint_0 %90 %96 %92
-               OpLoopMerge %94 %92 None
-               OpBranch %91
-         %91 = OpLabel
-         %97 = OpUGreaterThanEqual %bool %95 %uint_4
-               OpSelectionMerge %98 None
-               OpBranchConditional %97 %99 %98
-         %99 = OpLabel
-               OpBranch %94
-         %98 = OpLabel
-        %100 = OpAccessChain %_ptr_Function_mat4v3float %89 %95
-        %101 = OpLoad %mat4v3float %100 None
-        %102 = OpCompositeConstruct %_arr_uint_uint_1 %95
-        %103 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %102 %101
-               OpBranch %92
-         %92 = OpLabel
-         %96 = OpIAdd %uint %95 %uint_1
-               OpBranch %93
+         %90 = OpPhi %uint %uint_0 %85 %91 %87
+               OpLoopMerge %89 %87 None
+               OpBranch %86
+         %86 = OpLabel
+         %92 = OpUGreaterThanEqual %bool %90 %uint_4
+               OpSelectionMerge %93 None
+               OpBranchConditional %92 %94 %93
          %94 = OpLabel
+               OpBranch %89
+         %93 = OpLabel
+         %95 = OpAccessChain %_ptr_Function_mat4v3float %84 %90
+         %96 = OpLoad %mat4v3float %95 None
+         %97 = OpCompositeConstruct %_arr_uint_uint_1 %90
+         %98 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %97 %96
+               OpBranch %87
+         %87 = OpLabel
+         %91 = OpIAdd %uint %90 %uint_1
+               OpBranch %88
+         %89 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %106
+%tint_store_and_preserve_padding_0 = OpFunction %void None %101
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %mat4v3float
-        %107 = OpLabel
-        %108 = OpCompositeExtract %uint %target_indices 0
-        %109 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %108 %uint_0
-        %110 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %109 %110 None
-        %111 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %108 %uint_1
-        %112 = OpCompositeExtract %v3float %value_param_0 1
-               OpStore %111 %112 None
-        %113 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %108 %uint_2
-        %114 = OpCompositeExtract %v3float %value_param_0 2
-               OpStore %113 %114 None
-        %115 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %108 %uint_3
-        %116 = OpCompositeExtract %v3float %value_param_0 3
-               OpStore %115 %116 None
+        %102 = OpLabel
+        %103 = OpCompositeExtract %uint %target_indices 0
+        %104 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %103 %uint_0
+        %105 = OpCompositeExtract %v3float %value_param_0 0
+               OpStore %104 %105 None
+        %106 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %103 %uint_1
+        %107 = OpCompositeExtract %v3float %value_param_0 1
+               OpStore %106 %107 None
+        %108 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %103 %uint_2
+        %109 = OpCompositeExtract %v3float %value_param_0 2
+               OpStore %108 %109 None
+        %110 = OpAccessChain %_ptr_StorageBuffer_v3float %10 %uint_0 %103 %uint_3
+        %111 = OpCompositeExtract %v3float %value_param_0 3
+               OpStore %110 %111 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.glsl
index 2ff249a..ef896e2 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.glsl
@@ -52,9 +52,9 @@
     }
   }
   w = v_4;
-  w[1] = mat4x3(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  w[1][0] = v.inner[0].col1.zxy;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = mat4x3(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  w[1u][0u] = v.inner[0u].col1.zxy;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 18db582..3b547ed 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(128u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(128u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 18db582..3b547ed 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x3 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(128u);
-  w[int(1)][int(0)] = asfloat(u[1u].xyz).zxy;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(128u);
+  w[1u][0u] = asfloat(u[1u].xyz).zxy;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
index 4ba79e3..7b462a0 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -23,6 +23,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4> tint_symbol;
 };
@@ -74,6 +77,7 @@
     uint v_19 = 0u;
     v_19 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_20 = v_19;
       if ((v_20 >= 4u)) {
         break;
@@ -90,17 +94,17 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[2];
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_21 = (*tint_module_vars.u)[2u];
   float3 const v_22 = float3(v_21[0u].packed);
   float3 const v_23 = float3(v_21[1u].packed);
   float3 const v_24 = float3(v_21[2u].packed);
   float4x3 const v_25 = float4x3(v_22, v_23, v_24, float3(v_21[3u].packed));
-  (*tint_module_vars.w)[1][0u].packed = packed_float3(v_25[0u]);
-  (*tint_module_vars.w)[1][1u].packed = packed_float3(v_25[1u]);
-  (*tint_module_vars.w)[1][2u].packed = packed_float3(v_25[2u]);
-  (*tint_module_vars.w)[1][3u].packed = packed_float3(v_25[3u]);
-  (*tint_module_vars.w)[1][0].packed = packed_float3(float3((*tint_module_vars.u)[0][1].packed).zxy);
-  (*tint_module_vars.w)[1][0].packed[0u] = (*tint_module_vars.u)[0][1].packed[0u];
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(v_25[0u]);
+  (*tint_module_vars.w)[1u][1u].packed = packed_float3(v_25[1u]);
+  (*tint_module_vars.w)[1u][2u].packed = packed_float3(v_25[2u]);
+  (*tint_module_vars.w)[1u][3u].packed = packed_float3(v_25[3u]);
+  (*tint_module_vars.w)[1u][0u].packed = packed_float3(float3((*tint_module_vars.u)[0u][1u].packed).zxy);
+  (*tint_module_vars.w)[1u][0u].packed[0u] = (*tint_module_vars.u)[0u][1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_26 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.msl
index 487f4b9..395c940 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 4>, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = tint_pack_vec3_in_composite(float4x3(float3(0.0f), float3(0.0f), float3(0.0f), float3(0.0f)));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
index f57bbf6..db320eb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 102
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -61,16 +61,12 @@
          %47 = OpConstantNull %_arr_mat4v3float_uint_4
 %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
 %_ptr_Function_mat4x3_f32_std140 = OpTypePointer Function %mat4x3_f32_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-      %int_2 = OpConstant %int 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %98 = OpTypeFunction %void
+         %94 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -131,33 +127,33 @@
          %52 = OpLabel
          %68 = OpLoad %_arr_mat4v3float_uint_4 %45 None
                OpStore %w %68 None
-         %69 = OpAccessChain %_ptr_Workgroup_mat4v3float %w %int_1
-         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_0
-         %75 = OpLoad %v3float %72 None
-         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %77 = OpLoad %v3float %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3float %78 None
-         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3float %80 None
-         %83 = OpCompositeConstruct %mat4v3float %75 %77 %79 %82
-               OpStore %69 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %88 = OpLoad %v3float %87 None
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-               OpStore %84 %89 None
-         %90 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %int_0
-         %91 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_1
-         %92 = OpAccessChain %_ptr_Uniform_float %91 %uint_0
-         %94 = OpLoad %float %92 None
-         %95 = OpAccessChain %_ptr_Workgroup_float %90 %uint_0
-               OpStore %95 %94 None
+         %69 = OpAccessChain %_ptr_Workgroup_mat4v3float %w %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_0
+         %72 = OpLoad %v3float %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %74 = OpLoad %v3float %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %76 = OpLoad %v3float %75 None
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %79 = OpLoad %v3float %77 None
+         %80 = OpCompositeConstruct %mat4v3float %72 %74 %76 %79
+               OpStore %69 %80 None
+         %81 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %84 = OpLoad %v3float %83 None
+         %85 = OpVectorShuffle %v3float %84 %84 2 0 1
+               OpStore %81 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_0
+         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_1
+         %88 = OpAccessChain %_ptr_Uniform_float %87 %uint_0
+         %90 = OpLoad %float %88 None
+         %91 = OpAccessChain %_ptr_Workgroup_float %86 %uint_0
+               OpStore %91 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %98
-         %99 = OpLabel
-        %100 = OpLoad %uint %f_local_invocation_index_Input None
-        %101 = OpFunctionCall %void %f_inner %100
+          %f = OpFunction %void None %94
+         %95 = OpLabel
+         %96 = OpLoad %uint %f_local_invocation_index_Input None
+         %97 = OpFunctionCall %void %f_inner %96
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4466335..be0743f 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -49,14 +49,14 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   matrix<float16_t, 4, 4> l_a[4] = a_load(0u);
-  matrix<float16_t, 4, 4> l_a_i = a_load_1((32u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save)))) / 4;
+  matrix<float16_t, 4, 4> l_a_i = a_load_1((32u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u)))) / 4;
   uint4 ubo_load_9 = a[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
   vector<float16_t, 2> ubo_load_8_yw = vector<float16_t, 2>(f16tof32(ubo_load_8 >> 16));
   vector<float16_t, 4> l_a_i_i = vector<float16_t, 4>(ubo_load_8_xz[0], ubo_load_8_yw[0], ubo_load_8_xz[1], ubo_load_8_yw[1]);
-  const uint scalar_offset_bytes = (((32u * uint(p_a_i_save)) + (8u * uint(p_a_i_i_save))));
+  const uint scalar_offset_bytes = (((32u * min(uint(p_a_i_save), 3u)) + (8u * min(uint(p_a_i_i_save), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   s.Store<float16_t>(0u, (((float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF))) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x));
   return;
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index c2ed8fa..8a33796 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -24,9 +24,9 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
+  uint v_2 = min(uint(i()), 3u);
   f16mat4 v_3 = f16mat4(v.inner[v_2].col0, v.inner[v_2].col1, v.inner[v_2].col2, v.inner[v_2].col3);
-  f16vec4 v_4 = v_3[i()];
+  f16vec4 v_4 = v_3[min(uint(i()), 3u)];
   mat4x4_f16_std140 v_5[4] = v.inner;
   f16mat4 v_6[4] = f16mat4[4](f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)));
   {
@@ -47,5 +47,5 @@
   f16mat4 l_a[4] = v_6;
   f16mat4 l_a_i = v_3;
   f16vec4 l_a_i_i = v_4;
-  v_1.inner = (((v_4[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v_4[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index da5c39b..eaaa13e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -56,13 +56,13 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (32u * uint(i()));
-  uint v_17 = (8u * uint(i()));
+  uint v_16 = (32u * uint(min(uint(i()), 3u)));
+  uint v_17 = (8u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 4> l_a[4] = v_12(0u);
   matrix<float16_t, 4, 4> l_a_i = v_4(v_16);
   uint4 v_18 = a[((v_16 + v_17) / 16u)];
   vector<float16_t, 4> l_a_i_i = tint_bitcast_to_f16(((((((v_16 + v_17) % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
   uint v_19 = a[((v_16 + v_17) / 16u)][(((v_16 + v_17) % 16u) / 4u)];
-  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_19 >> (((((v_16 + v_17) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32((v_19 >> (((((v_16 + v_17) % 4u) == 0u)) ? (0u) : (16u))))) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 944b525..2c62805 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<half4x4, 4>* const p_a = tint_module_vars.a;
-  const constant half4x4* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant half4* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant half4x4* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant half4* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<half4x4, 4> const l_a = (*p_a);
   half4x4 const l_a_i = (*p_a_i);
   half4 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 3568e79..55eda24 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<half4x4, 4> const l_a = *(tint_symbol_2);
   half4x4 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   half4 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 43ebbd1..96a20e4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -63,17 +64,17 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4x4_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x4_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
 %_ptr_Function_mat4v4half = OpTypePointer Function %mat4v4half
 %_ptr_Function_v4half = OpTypePointer Function %v4half
 %_ptr_Function__arr_mat4x4_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x4_f16_std140_uint_4
 %_arr_mat4v4half_uint_4 = OpTypeArray %mat4v4half %uint_4
 %_ptr_Function__arr_mat4v4half_uint_4 = OpTypePointer Function %_arr_mat4v4half_uint_4
-         %58 = OpConstantNull %_arr_mat4v4half_uint_4
+         %63 = OpConstantNull %_arr_mat4v4half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4x4_f16_std140 = OpTypePointer Function %mat4x4_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -87,63 +88,67 @@
                OpFunctionEnd
           %f = OpFunction %void None %26
          %27 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat4v4half Function
-         %53 = OpVariable %_ptr_Function__arr_mat4x4_f16_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_mat4v4half_uint_4 Function %58
+         %49 = OpVariable %_ptr_Function_mat4v4half Function
+         %58 = OpVariable %_ptr_Function__arr_mat4x4_f16_std140_uint_4 Function
+         %60 = OpVariable %_ptr_Function__arr_mat4v4half_uint_4 Function %63
          %28 = OpAccessChain %_ptr_Uniform__arr_mat4x4_f16_std140_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-         %32 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_0
-         %34 = OpLoad %v4half %32 None
-         %35 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_1
-         %37 = OpLoad %v4half %35 None
-         %38 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_2
-         %40 = OpLoad %v4half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v4half %28 %31 %uint_3
-         %43 = OpLoad %v4half %41 None
-      %l_a_i = OpCompositeConstruct %mat4v4half %34 %37 %40 %43
-               OpStore %46 %l_a_i
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v4half %46 %48
-    %l_a_i_i = OpLoad %v4half %49 None
-         %52 = OpLoad %_arr_mat4x4_f16_std140_uint_4 %28 None
-               OpStore %53 %52
-               OpBranch %59
-         %59 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-         %64 = OpPhi %uint %uint_0 %59 %65 %61
-               OpLoopMerge %63 %61 None
-               OpBranch %60
-         %60 = OpLabel
-         %66 = OpUGreaterThanEqual %bool %64 %uint_4
-               OpSelectionMerge %68 None
-               OpBranchConditional %66 %69 %68
-         %69 = OpLabel
-               OpBranch %63
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+         %36 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_0
+         %38 = OpLoad %v4half %36 None
+         %39 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_1
+         %41 = OpLoad %v4half %39 None
+         %42 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_2
+         %44 = OpLoad %v4half %42 None
+         %45 = OpAccessChain %_ptr_Uniform_v4half %28 %33 %uint_3
+         %46 = OpLoad %v4half %45 None
+      %l_a_i = OpCompositeConstruct %mat4v4half %38 %41 %44 %46
+               OpStore %49 %l_a_i
+         %51 = OpFunctionCall %int %i
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %34 UMin %52 %uint_3
+         %54 = OpAccessChain %_ptr_Function_v4half %49 %53
+    %l_a_i_i = OpLoad %v4half %54 None
+         %57 = OpLoad %_arr_mat4x4_f16_std140_uint_4 %28 None
+               OpStore %58 %57
+               OpBranch %64
+         %64 = OpLabel
+               OpBranch %67
+         %67 = OpLabel
+         %69 = OpPhi %uint %uint_0 %64 %70 %66
+               OpLoopMerge %68 %66 None
+               OpBranch %65
+         %65 = OpLabel
+         %71 = OpUGreaterThanEqual %bool %69 %uint_4
+               OpSelectionMerge %73 None
+               OpBranchConditional %71 %74 %73
+         %74 = OpLabel
+               OpBranch %68
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Function_mat4v4half %60 %69
+         %76 = OpAccessChain %_ptr_Function_mat4x4_f16_std140 %58 %69
+         %78 = OpLoad %mat4x4_f16_std140 %76 None
+         %79 = OpCompositeExtract %v4half %78 0
+         %80 = OpCompositeExtract %v4half %78 1
+         %81 = OpCompositeExtract %v4half %78 2
+         %82 = OpCompositeExtract %v4half %78 3
+         %83 = OpCompositeConstruct %mat4v4half %79 %80 %81 %82
+               OpStore %75 %83 None
+               OpBranch %66
+         %66 = OpLabel
+         %70 = OpIAdd %uint %69 %uint_1
+               OpBranch %67
          %68 = OpLabel
-         %70 = OpAccessChain %_ptr_Function_mat4v4half %55 %64
-         %71 = OpAccessChain %_ptr_Function_mat4x4_f16_std140 %53 %64
-         %73 = OpLoad %mat4x4_f16_std140 %71 None
-         %74 = OpCompositeExtract %v4half %73 0
-         %75 = OpCompositeExtract %v4half %73 1
-         %76 = OpCompositeExtract %v4half %73 2
-         %77 = OpCompositeExtract %v4half %73 3
-         %78 = OpCompositeConstruct %mat4v4half %74 %75 %76 %77
-               OpStore %70 %78 None
-               OpBranch %61
-         %61 = OpLabel
-         %65 = OpIAdd %uint %64 %uint_1
-               OpBranch %62
-         %63 = OpLabel
-        %l_a = OpLoad %_arr_mat4v4half_uint_4 %55 None
-         %80 = OpCompositeExtract %half %l_a_i_i 0
-         %81 = OpCompositeExtract %half %l_a 0 0 0
-         %82 = OpFAdd %half %80 %81
-         %83 = OpCompositeExtract %half %l_a_i 0 0
-         %84 = OpFAdd %half %82 %83
+        %l_a = OpLoad %_arr_mat4v4half_uint_4 %60 None
          %85 = OpCompositeExtract %half %l_a_i_i 0
-         %86 = OpFAdd %half %84 %85
-         %87 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %87 %86 None
+         %86 = OpCompositeExtract %half %l_a 0 0 0
+         %87 = OpFAdd %half %85 %86
+         %88 = OpCompositeExtract %half %l_a_i 0 0
+         %89 = OpFAdd %half %87 %88
+         %90 = OpCompositeExtract %half %l_a_i_i 0
+         %91 = OpFAdd %half %89 %90
+         %92 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %92 %91 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
index 0ab21c9..d151b36 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -19,7 +19,7 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4 v_2 = f16mat4(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
+  f16mat4 v_2 = f16mat4(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
   mat4x4_f16_std140 v_3[4] = v.inner;
   f16mat4 v_4[4] = f16mat4[4](f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)), f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf)));
   {
@@ -39,6 +39,6 @@
   }
   f16mat4 l_a[4] = v_4;
   f16mat4 l_a_i = v_2;
-  f16vec4 l_a_i_i = v_2[1];
-  v_1.inner = (((v_2[1][0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  f16vec4 l_a_i_i = v_2[1u];
+  v_1.inner = (((v_2[1u][0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 7c66a07..21f80a6 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -53,6 +53,6 @@
   matrix<float16_t, 4, 4> l_a[4] = v_12(0u);
   matrix<float16_t, 4, 4> l_a_i = v_4(64u);
   vector<float16_t, 4> l_a_i_i = tint_bitcast_to_f16(a[4u].zw);
-  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[4u].z)) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x));
+  s.Store<float16_t>(0u, (((float16_t(f16tof32(a[4u].z)) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index fed164b..1a041ea 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<half4x4, 4>* a [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<half4x4, 4>* const p_a = tint_module_vars.a;
-  const constant half4x4* const p_a_2 = (&(*p_a)[2]);
-  const constant half4* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant half4x4* const p_a_2 = (&(*p_a)[2u]);
+  const constant half4* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<half4x4, 4> const l_a = (*p_a);
   half4x4 const l_a_i = (*p_a_2);
   half4 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
index 9d4e6ce..cc04f02 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 75
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -56,74 +56,72 @@
 %_ptr_Uniform__arr_mat4x4_f16_std140_uint_4 = OpTypePointer Uniform %_arr_mat4x4_f16_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
 %_ptr_Function__arr_mat4x4_f16_std140_uint_4 = OpTypePointer Function %_arr_mat4x4_f16_std140_uint_4
 %_arr_mat4v4half_uint_4 = OpTypeArray %mat4v4half %uint_4
 %_ptr_Function__arr_mat4v4half_uint_4 = OpTypePointer Function %_arr_mat4v4half_uint_4
-         %43 = OpConstantNull %_arr_mat4v4half_uint_4
+         %41 = OpConstantNull %_arr_mat4v4half_uint_4
        %bool = OpTypeBool
 %_ptr_Function_mat4v4half = OpTypePointer Function %mat4v4half
 %_ptr_Function_mat4x4_f16_std140 = OpTypePointer Function %mat4x4_f16_std140
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_mat4x4_f16_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_mat4v4half_uint_4 Function %43
+         %36 = OpVariable %_ptr_Function__arr_mat4x4_f16_std140_uint_4 Function
+         %38 = OpVariable %_ptr_Function__arr_mat4v4half_uint_4 Function %41
          %17 = OpAccessChain %_ptr_Uniform__arr_mat4x4_f16_std140_uint_4 %1 %uint_0
-         %20 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_0
-         %24 = OpLoad %v4half %20 None
-         %25 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_1
-         %27 = OpLoad %v4half %25 None
-         %28 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_2
-         %30 = OpLoad %v4half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v4half %17 %int_2 %uint_3
-         %33 = OpLoad %v4half %31 None
-      %l_a_i = OpCompositeConstruct %mat4v4half %24 %27 %30 %33
+         %20 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_0
+         %23 = OpLoad %v4half %20 None
+         %24 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_1
+         %26 = OpLoad %v4half %24 None
+         %27 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_2
+         %28 = OpLoad %v4half %27 None
+         %29 = OpAccessChain %_ptr_Uniform_v4half %17 %uint_2 %uint_3
+         %31 = OpLoad %v4half %29 None
+      %l_a_i = OpCompositeConstruct %mat4v4half %23 %26 %28 %31
     %l_a_i_i = OpCompositeExtract %v4half %l_a_i 1
-         %37 = OpLoad %_arr_mat4x4_f16_std140_uint_4 %17 None
-               OpStore %38 %37
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-         %49 = OpPhi %uint %uint_0 %44 %50 %46
-               OpLoopMerge %48 %46 None
+         %35 = OpLoad %_arr_mat4x4_f16_std140_uint_4 %17 None
+               OpStore %36 %35
+               OpBranch %42
+         %42 = OpLabel
                OpBranch %45
          %45 = OpLabel
-         %51 = OpUGreaterThanEqual %bool %49 %uint_4
-               OpSelectionMerge %53 None
-               OpBranchConditional %51 %54 %53
-         %54 = OpLabel
-               OpBranch %48
-         %53 = OpLabel
-         %55 = OpAccessChain %_ptr_Function_mat4v4half %40 %49
-         %57 = OpAccessChain %_ptr_Function_mat4x4_f16_std140 %38 %49
-         %59 = OpLoad %mat4x4_f16_std140 %57 None
-         %60 = OpCompositeExtract %v4half %59 0
-         %61 = OpCompositeExtract %v4half %59 1
-         %62 = OpCompositeExtract %v4half %59 2
-         %63 = OpCompositeExtract %v4half %59 3
-         %64 = OpCompositeConstruct %mat4v4half %60 %61 %62 %63
-               OpStore %55 %64 None
+         %47 = OpPhi %uint %uint_0 %42 %48 %44
+               OpLoopMerge %46 %44 None
+               OpBranch %43
+         %43 = OpLabel
+         %49 = OpUGreaterThanEqual %bool %47 %uint_4
+               OpSelectionMerge %51 None
+               OpBranchConditional %49 %52 %51
+         %52 = OpLabel
                OpBranch %46
+         %51 = OpLabel
+         %53 = OpAccessChain %_ptr_Function_mat4v4half %38 %47
+         %55 = OpAccessChain %_ptr_Function_mat4x4_f16_std140 %36 %47
+         %57 = OpLoad %mat4x4_f16_std140 %55 None
+         %58 = OpCompositeExtract %v4half %57 0
+         %59 = OpCompositeExtract %v4half %57 1
+         %60 = OpCompositeExtract %v4half %57 2
+         %61 = OpCompositeExtract %v4half %57 3
+         %62 = OpCompositeConstruct %mat4v4half %58 %59 %60 %61
+               OpStore %53 %62 None
+               OpBranch %44
+         %44 = OpLabel
+         %48 = OpIAdd %uint %47 %uint_1
+               OpBranch %45
          %46 = OpLabel
-         %50 = OpIAdd %uint %49 %uint_1
-               OpBranch %47
-         %48 = OpLabel
-        %l_a = OpLoad %_arr_mat4v4half_uint_4 %40 None
-         %66 = OpCompositeExtract %half %l_a_i_i 0
-         %67 = OpCompositeExtract %half %l_a 0 0 0
+        %l_a = OpLoad %_arr_mat4v4half_uint_4 %38 None
+         %64 = OpCompositeExtract %half %l_a_i_i 0
+         %65 = OpCompositeExtract %half %l_a 0 0 0
+         %66 = OpFAdd %half %64 %65
+         %67 = OpCompositeExtract %half %l_a_i 0 0
          %68 = OpFAdd %half %66 %67
-         %69 = OpCompositeExtract %half %l_a_i 0 0
+         %69 = OpCompositeExtract %half %l_a_i_i 0
          %70 = OpFAdd %half %68 %69
-         %71 = OpCompositeExtract %half %l_a_i_i 0
-         %72 = OpFAdd %half %70 %71
-         %73 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %73 %72 None
+         %71 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %71 %70 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.glsl
index 8398637..7de8352 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.glsl
@@ -19,9 +19,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4 t = transpose(f16mat4(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3));
-  float16_t l = length(v.inner[0].col1.ywxz);
-  float16_t a = abs(v.inner[0].col1.ywxz[0u]);
-  float16_t v_2 = (t[0][0u] + float16_t(l));
+  f16mat4 t = transpose(f16mat4(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3));
+  float16_t l = length(v.inner[0u].col1.ywxz);
+  float16_t a = abs(v.inner[0u].col1.ywxz[0u]);
+  float16_t v_2 = (t[0u][0u] + float16_t(l));
   v_1.inner = (v_2 + float16_t(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
index 5c66616..cba4677 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
   matrix<float16_t, 4, 4> t = transpose(v_4(64u));
   float16_t l = length(tint_bitcast_to_f16(u[0u].zw).ywxz);
   float16_t a = abs(tint_bitcast_to_f16(u[0u].zw).ywxz.x);
-  float16_t v_12 = (t[int(0)].x + float16_t(l));
+  float16_t v_12 = (t[0u].x + float16_t(l));
   s.Store<float16_t>(0u, (v_12 + float16_t(a)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
index 7a6b97b..da17af4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<half4x4, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  half4x4 const t = transpose((*tint_module_vars.u)[2]);
-  half const l = length((*tint_module_vars.u)[0][1].ywxz);
-  half const a = abs((*tint_module_vars.u)[0][1].ywxz[0u]);
-  half const v = (t[0][0u] + half(l));
+  half4x4 const t = transpose((*tint_module_vars.u)[2u]);
+  half const l = length((*tint_module_vars.u)[0u][1u].ywxz);
+  half const a = abs((*tint_module_vars.u)[0u][1u].ywxz[0u]);
+  half const v = (t[0u][0u] + half(l));
   (*tint_module_vars.s) = (v + half(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.spvasm
index 3ead19a..ad79406 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %40 = OpExtInstImport "GLSL.std.450"
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,39 +55,36 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %22 = OpLoad %v4half %17 None
-         %23 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %25 = OpLoad %v4half %23 None
-         %26 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %28 = OpLoad %v4half %26 None
-         %29 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %31 = OpLoad %v4half %29 None
-         %33 = OpCompositeConstruct %mat4v4half %22 %25 %28 %31
-          %t = OpTranspose %mat4v4half %33
-         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %37 = OpLoad %v4half %35 None
-         %38 = OpVectorShuffle %v4half %37 %37 1 3 0 2
-          %l = OpExtInst %half %40 Length %38
-         %41 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %42 = OpLoad %v4half %41 None
-         %43 = OpVectorShuffle %v4half %42 %42 1 3 0 2
-         %44 = OpCompositeExtract %half %43 0
-          %a = OpExtInst %half %40 FAbs %44
-         %46 = OpCompositeExtract %half %t 0 0
-         %47 = OpFAdd %half %46 %l
-         %48 = OpFAdd %half %47 %a
-         %49 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %49 %48 None
+         %17 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %21 = OpLoad %v4half %17 None
+         %22 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %24 = OpLoad %v4half %22 None
+         %25 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %26 = OpLoad %v4half %25 None
+         %27 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %29 = OpLoad %v4half %27 None
+         %31 = OpCompositeConstruct %mat4v4half %21 %24 %26 %29
+          %t = OpTranspose %mat4v4half %31
+         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %34 = OpLoad %v4half %33 None
+         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
+          %l = OpExtInst %half %37 Length %35
+         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %39 = OpLoad %v4half %38 None
+         %40 = OpVectorShuffle %v4half %39 %39 1 3 0 2
+         %41 = OpCompositeExtract %half %40 0
+          %a = OpExtInst %half %37 FAbs %41
+         %43 = OpCompositeExtract %half %t 0 0
+         %44 = OpFAdd %half %43 %l
+         %45 = OpFAdd %half %44 %a
+         %46 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.glsl
index 779a8c6..d75c3d8 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.glsl
@@ -18,10 +18,10 @@
   float16_t inner;
 } v_2;
 float16_t a(f16mat4 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float16_t b(f16mat4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float16_t c(f16vec4 v) {
   return v[0u];
@@ -49,7 +49,7 @@
     }
   }
   float16_t v_7 = a(v_4);
-  float16_t v_8 = (v_7 + b(f16mat4(v_1.inner[1].col0, v_1.inner[1].col1, v_1.inner[1].col2, v_1.inner[1].col3)));
-  float16_t v_9 = (v_8 + c(v_1.inner[1].col0.ywxz));
-  v_2.inner = (v_9 + d(v_1.inner[1].col0.ywxz[0u]));
+  float16_t v_8 = (v_7 + b(f16mat4(v_1.inner[1u].col0, v_1.inner[1u].col1, v_1.inner[1u].col2, v_1.inner[1u].col3)));
+  float16_t v_9 = (v_8 + c(v_1.inner[1u].col0.ywxz));
+  v_2.inner = (v_9 + d(v_1.inner[1u].col0.ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
index 69b09c9..2e5348f 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float16_t a(matrix<float16_t, 4, 4> a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float16_t b(matrix<float16_t, 4, 4> m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float16_t c(vector<float16_t, 4> v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.msl
index 8aa0dbf..c3964b3 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 half a(tint_array<half4x4, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 half b(half4x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 half c(half4 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<half4x4, 4>* u [[buffer(0)]], device half* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   half const v_1 = a((*tint_module_vars.u));
-  half const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  half const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].ywxz));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].ywxz[0u]));
+  half const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  half const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].ywxz));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.spvasm
index ca23497..979d33c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 100
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -74,8 +74,6 @@
 %_ptr_Function_mat4x4_f16_std140 = OpTypePointer Function %mat4x4_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -139,29 +137,29 @@
          %51 = OpLabel
          %69 = OpLoad %_arr_mat4v4half_uint_4 %44 None
          %70 = OpFunctionCall %half %a %69
-         %71 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %75 = OpLoad %v4half %71 None
-         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_1
-         %77 = OpLoad %v4half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_2
-         %80 = OpLoad %v4half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_3
-         %83 = OpLoad %v4half %81 None
-         %84 = OpCompositeConstruct %mat4v4half %75 %77 %80 %83
-         %85 = OpFunctionCall %half %b %84
-         %86 = OpFAdd %half %70 %85
-         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %88 = OpLoad %v4half %87 None
-         %89 = OpVectorShuffle %v4half %88 %88 1 3 0 2
-         %90 = OpFunctionCall %half %c %89
-         %91 = OpFAdd %half %86 %90
-         %92 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_1 %uint_0
-         %93 = OpLoad %v4half %92 None
-         %94 = OpVectorShuffle %v4half %93 %93 1 3 0 2
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %half %d %95
-         %97 = OpFAdd %half %91 %96
-         %98 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %98 %97 None
+         %71 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %73 = OpLoad %v4half %71 None
+         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_1
+         %75 = OpLoad %v4half %74 None
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_2
+         %78 = OpLoad %v4half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_3
+         %81 = OpLoad %v4half %79 None
+         %82 = OpCompositeConstruct %mat4v4half %73 %75 %78 %81
+         %83 = OpFunctionCall %half %b %82
+         %84 = OpFAdd %half %70 %83
+         %85 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %86 = OpLoad %v4half %85 None
+         %87 = OpVectorShuffle %v4half %86 %86 1 3 0 2
+         %88 = OpFunctionCall %half %c %87
+         %89 = OpFAdd %half %84 %88
+         %90 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_1 %uint_0
+         %91 = OpLoad %v4half %90 None
+         %92 = OpVectorShuffle %v4half %91 %91 1 3 0 2
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %half %d %93
+         %95 = OpFAdd %half %89 %94
+         %96 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %96 %95 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.glsl
index 27a3261..511ba01 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.glsl
@@ -38,8 +38,8 @@
     }
   }
   p = v_3;
-  p[1] = f16mat4(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  p[1][0] = v.inner[0].col1.ywxz;
-  p[1][0][0u] = v.inner[0].col1.x;
-  v_1.inner = p[1][0].x;
+  p[1u] = f16mat4(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  p[1u][0u] = v.inner[0u].col1.ywxz;
+  p[1u][0u][0u] = v.inner[0u].col1.x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index a83e0ae..e076106 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -53,9 +53,9 @@
 void f() {
   matrix<float16_t, 4, 4> v_16[4] = v_12(0u);
   p = v_16;
-  p[int(1)] = v_4(64u);
-  p[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).ywxz;
-  p[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
-  s.Store<float16_t>(0u, p[int(1)][int(0)].x);
+  p[1u] = v_4(64u);
+  p[1u][0u] = tint_bitcast_to_f16(u[0u].zw).ywxz;
+  p[1u][0u].x = float16_t(f16tof32(u[0u].z));
+  s.Store<float16_t>(0u, p[1u][0u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.msl
index 7ba92fa..ae8ec03 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<half4x4, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.spvasm
index c004076..1fd63d0 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 88
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,14 +65,10 @@
 %_ptr_Function_mat4x4_f16_std140 = OpTypePointer Function %mat4x4_f16_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_mat4v4half = OpTypePointer Private %mat4v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
@@ -113,32 +109,32 @@
          %34 = OpLabel
          %52 = OpLoad %_arr_mat4v4half_uint_4 %28 None
                OpStore %p %52 None
-         %53 = OpAccessChain %_ptr_Private_mat4v4half %p %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v4half %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_Private_mat4v4half %p %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v4half %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v4half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v4half %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v4half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v4half %66 None
-         %69 = OpCompositeConstruct %mat4v4half %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v4half %73 None
-         %75 = OpVectorShuffle %v4half %74 %74 1 3 0 2
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_half %77 %uint_0
-         %80 = OpLoad %half %78 None
-         %81 = OpAccessChain %_ptr_Private_half %76 %uint_0
-               OpStore %81 %80 None
-         %83 = OpAccessChain %_ptr_Private_v4half %p %int_1 %int_0
-         %84 = OpAccessChain %_ptr_Private_half %83 %uint_0
-         %85 = OpLoad %half %84 None
-         %86 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
-               OpStore %86 %85 None
+         %66 = OpCompositeConstruct %mat4v4half %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v4half %69 None
+         %71 = OpVectorShuffle %v4half %70 %70 1 3 0 2
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_half %73 %uint_0
+         %76 = OpLoad %half %74 None
+         %77 = OpAccessChain %_ptr_Private_half %72 %uint_0
+               OpStore %77 %76 None
+         %79 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_0
+         %80 = OpAccessChain %_ptr_Private_half %79 %uint_0
+         %81 = OpLoad %half %80 None
+         %82 = OpAccessChain %_ptr_StorageBuffer_half %10 %uint_0
+               OpStore %82 %81 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.glsl
index 87e6b31..5e90e63 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.glsl
@@ -37,7 +37,7 @@
     }
   }
   v_1.inner = v_3;
-  v_1.inner[1] = f16mat4(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  v_1.inner[1][0] = v.inner[0].col1.ywxz;
-  v_1.inner[1][0][0u] = v.inner[0].col1.x;
+  v_1.inner[1u] = f16mat4(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  v_1.inner[1u][0u] = v.inner[0u].col1.ywxz;
+  v_1.inner[1u][0u][0u] = v.inner[0u].col1.x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.ir.msl
index 8f89af6..3d12139 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<half4x4, 4>* u [[buffer(0)]], device tint_array<half4x4, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.spvasm
index 5348339..c81e243 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,14 +65,10 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer__arr_mat4v4half_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v4half_uint_4
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %17
@@ -113,27 +109,27 @@
          %50 = OpLoad %_arr_mat4v4half_uint_4 %25 None
          %51 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v4half_uint_4 %10 %uint_0
                OpStore %51 %50 None
-         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %10 %uint_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %60 = OpLoad %v4half %57 None
-         %61 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %53 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %10 %uint_0 %uint_1
+         %55 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %58 = OpLoad %v4half %55 None
+         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %60 = OpLoad %v4half %59 None
+         %61 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
          %62 = OpLoad %v4half %61 None
-         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
+         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
          %65 = OpLoad %v4half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v4half %66 None
-         %69 = OpCompositeConstruct %mat4v4half %60 %62 %65 %68
-               OpStore %53 %69 None
-         %70 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %int_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %74 = OpLoad %v4half %73 None
-         %75 = OpVectorShuffle %v4half %74 %74 1 3 0 2
-               OpStore %70 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %int_1 %int_0
-         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_half %77 %uint_0
-         %80 = OpLoad %half %78 None
-         %81 = OpAccessChain %_ptr_StorageBuffer_half %76 %uint_0
-               OpStore %81 %80 None
+         %66 = OpCompositeConstruct %mat4v4half %58 %60 %62 %65
+               OpStore %53 %66 None
+         %67 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %70 = OpLoad %v4half %69 None
+         %71 = OpVectorShuffle %v4half %70 %70 1 3 0 2
+               OpStore %67 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v4half %10 %uint_0 %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_half %73 %uint_0
+         %76 = OpLoad %half %74 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_half %72 %uint_0
+               OpStore %77 %76 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.glsl
index ed144d2..926a014 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.glsl
@@ -49,9 +49,9 @@
     }
   }
   w = v_4;
-  w[1] = f16mat4(v.inner[2].col0, v.inner[2].col1, v.inner[2].col2, v.inner[2].col3);
-  w[1][0] = v.inner[0].col1.ywxz;
-  w[1][0][0u] = v.inner[0].col1.x;
+  w[1u] = f16mat4(v.inner[2u].col0, v.inner[2u].col1, v.inner[2u].col2, v.inner[2u].col3);
+  w[1u][0u] = v.inner[0u].col1.ywxz;
+  w[1u][0u][0u] = v.inner[0u].col1.x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 83fdaa4..7b88583 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -71,9 +71,9 @@
   GroupMemoryBarrierWithGroupSync();
   matrix<float16_t, 4, 4> v_18[4] = v_12(0u);
   w = v_18;
-  w[int(1)] = v_4(64u);
-  w[int(1)][int(0)] = tint_bitcast_to_f16(u[0u].zw).ywxz;
-  w[int(1)][int(0)].x = float16_t(f16tof32(u[0u].z));
+  w[1u] = v_4(64u);
+  w[1u][0u] = tint_bitcast_to_f16(u[0u].zw).ywxz;
+  w[1u][0u].x = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
index 6df1c65..036c6d4 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<half4x4, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<half4x4, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<half4x4, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.msl
index 6767eed..dfbd2b7 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<half4x4, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<half4x4, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = half4x4(half4(0.0h), half4(0.0h), half4(0.0h), half4(0.0h));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
index c57c238..daf1c6e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 102
+; Bound: 98
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -64,16 +64,12 @@
          %47 = OpConstantNull %_arr_mat4v4half_uint_4
 %_ptr_Function_mat4v4half = OpTypePointer Function %mat4v4half
 %_ptr_Function_mat4x4_f16_std140 = OpTypePointer Function %mat4x4_f16_std140
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-      %int_2 = OpConstant %int 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %98 = OpTypeFunction %void
+         %94 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -134,33 +130,33 @@
          %52 = OpLabel
          %68 = OpLoad %_arr_mat4v4half_uint_4 %45 None
                OpStore %w %68 None
-         %69 = OpAccessChain %_ptr_Workgroup_mat4v4half %w %int_1
-         %72 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_0
-         %75 = OpLoad %v4half %72 None
-         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %77 = OpLoad %v4half %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v4half %78 None
-         %80 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v4half %80 None
-         %83 = OpCompositeConstruct %mat4v4half %75 %77 %79 %82
-               OpStore %69 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %88 = OpLoad %v4half %87 None
-         %89 = OpVectorShuffle %v4half %88 %88 1 3 0 2
-               OpStore %84 %89 None
-         %90 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %int_0
-         %91 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_1
-         %92 = OpAccessChain %_ptr_Uniform_half %91 %uint_0
-         %94 = OpLoad %half %92 None
-         %95 = OpAccessChain %_ptr_Workgroup_half %90 %uint_0
-               OpStore %95 %94 None
+         %69 = OpAccessChain %_ptr_Workgroup_mat4v4half %w %uint_1
+         %70 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_0
+         %72 = OpLoad %v4half %70 None
+         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %74 = OpLoad %v4half %73 None
+         %75 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %76 = OpLoad %v4half %75 None
+         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %79 = OpLoad %v4half %77 None
+         %80 = OpCompositeConstruct %mat4v4half %72 %74 %76 %79
+               OpStore %69 %80 None
+         %81 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_0
+         %83 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %84 = OpLoad %v4half %83 None
+         %85 = OpVectorShuffle %v4half %84 %84 1 3 0 2
+               OpStore %81 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_0
+         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_1
+         %88 = OpAccessChain %_ptr_Uniform_half %87 %uint_0
+         %90 = OpLoad %half %88 None
+         %91 = OpAccessChain %_ptr_Workgroup_half %86 %uint_0
+               OpStore %91 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %98
-         %99 = OpLabel
-        %100 = OpLoad %uint %f_local_invocation_index_Input None
-        %101 = OpFunctionCall %void %f_inner %100
+          %f = OpFunction %void None %94
+         %95 = OpLabel
+         %96 = OpLoad %uint %f_local_invocation_index_Input None
+         %97 = OpFunctionCall %void %f_inner %96
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 50400a8..bdd2edf 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -33,10 +33,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x4 l_a[4] = a_load(0u);
-  float4x4 l_a_i = a_load_1((64u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float4x4 l_a_i = a_load_1((64u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_4 / 4]);
-  const uint scalar_offset_5 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 50400a8..bdd2edf 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -33,10 +33,10 @@
   int p_a_i_save = i();
   int p_a_i_i_save = i();
   float4x4 l_a[4] = a_load(0u);
-  float4x4 l_a_i = a_load_1((64u * uint(p_a_i_save)));
-  const uint scalar_offset_4 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  float4x4 l_a_i = a_load_1((64u * min(uint(p_a_i_save), 3u)));
+  const uint scalar_offset_4 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   float4 l_a_i_i = asfloat(a[scalar_offset_4 / 4]);
-  const uint scalar_offset_5 = (((64u * uint(p_a_i_save)) + (16u * uint(p_a_i_i_save)))) / 4;
+  const uint scalar_offset_5 = (((64u * min(uint(p_a_i_save), 3u)) + (16u * min(uint(p_a_i_i_save), 3u)))) / 4;
   s.Store(0u, asuint((((asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]) + l_a[0][0].x) + l_a_i[0].x) + l_a_i_i.x)));
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 185cae3..1a0af4c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,10 +15,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = i();
-  int v_3 = i();
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 3u);
   mat4 l_a[4] = v.inner;
   mat4 l_a_i = v.inner[v_2];
   vec4 l_a_i_i = v.inner[v_2][v_3];
-  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  v_1.inner = (((v.inner[v_2][v_3].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index c0a7a5f..5d6a503 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (64u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (64u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 3u)));
   float4x4 l_a[4] = v_1(0u);
   float4x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index c0a7a5f..5d6a503 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -37,11 +37,11 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (64u * uint(i()));
-  uint v_6 = (16u * uint(i()));
+  uint v_5 = (64u * uint(min(uint(i()), 3u)));
+  uint v_6 = (16u * uint(min(uint(i()), 3u)));
   float4x4 l_a[4] = v_1(0u);
   float4x4 l_a_i = v(v_5);
   float4 l_a_i_i = asfloat(a[((v_5 + v_6) / 16u)]);
-  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[((v_5 + v_6) / 16u)][(((v_5 + v_6) % 16u) / 4u)]) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 7d63cb3..efb6f41 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -28,10 +28,10 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s, .counter=(&counter)};
   const constant tint_array<float4x4, 4>* const p_a = tint_module_vars.a;
-  const constant float4x4* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
-  const constant float4* const p_a_i_i = (&(*p_a_i)[i(tint_module_vars)]);
+  const constant float4x4* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
+  const constant float4* const p_a_i_i = (&(*p_a_i)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<float4x4, 4> const l_a = (*p_a);
   float4x4 const l_a_i = (*p_a_i);
   float4 const l_a_i_i = (*p_a_i_i);
-  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_i_i)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 3a28f70..0b7cafe 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -27,9 +27,9 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_i_save = tint_symbol_1;
+  uint const p_a_i_i_save = min(uint(tint_symbol_1), 3u);
   tint_array<float4x4, 4> const l_a = *(tint_symbol_2);
   float4x4 const l_a_i = (*(tint_symbol_2))[p_a_i_save];
   float4 const l_a_i_i = (*(tint_symbol_2))[p_a_i_save][p_a_i_i_save];
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 75b93c9..c8989b9 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 57
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -55,6 +56,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_mat4v4float_uint_4 = OpTypePointer Uniform %_arr_mat4v4float_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
@@ -71,21 +73,25 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat4v4float_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_mat4v4float %p_a %31
-         %34 = OpFunctionCall %int %i
-    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %34
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_mat4v4float %p_a %33
+         %38 = OpFunctionCall %int %i
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %34 UMin %39 %uint_3
+    %p_a_i_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i %40
         %l_a = OpLoad %_arr_mat4v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat4v4float %p_a_i None
     %l_a_i_i = OpLoad %v4float %p_a_i_i None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpCompositeExtract %float %l_a 0 0 0
-         %44 = OpFAdd %float %42 %43
-         %45 = OpCompositeExtract %float %l_a_i 0 0
-         %46 = OpFAdd %float %44 %45
-         %47 = OpCompositeExtract %float %l_a_i_i 0
-         %48 = OpFAdd %float %46 %47
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %46 = OpAccessChain %_ptr_Uniform_float %p_a_i_i %uint_0
+         %48 = OpLoad %float %46 None
+         %49 = OpCompositeExtract %float %l_a 0 0 0
+         %50 = OpFAdd %float %48 %49
+         %51 = OpCompositeExtract %float %l_a_i 0 0
+         %52 = OpFAdd %float %50 %51
+         %53 = OpCompositeExtract %float %l_a_i_i 0
+         %54 = OpFAdd %float %52 %53
+         %55 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
index 6d0ef12..058dacc 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat4 l_a[4] = v.inner;
-  mat4 l_a_i = v.inner[2];
-  vec4 l_a_i_i = v.inner[2][1];
-  v_1.inner = (((v.inner[2][1].x + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  mat4 l_a_i = v.inner[2u];
+  vec4 l_a_i_i = v.inner[2u][1u];
+  v_1.inner = (((v.inner[2u][1u].x + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index aed05e2..5efc027 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -34,6 +34,6 @@
   float4x4 l_a[4] = v_1(0u);
   float4x4 l_a_i = v(128u);
   float4 l_a_i_i = asfloat(a[9u]);
-  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index aed05e2..5efc027 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -34,6 +34,6 @@
   float4x4 l_a[4] = v_1(0u);
   float4x4 l_a_i = v(128u);
   float4 l_a_i_i = asfloat(a[9u]);
-  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[int(0)][int(0)].x) + l_a_i[int(0)].x) + l_a_i_i.x)));
+  s.Store(0u, asuint((((asfloat(a[9u].x) + l_a[0u][0u].x) + l_a_i[0u].x) + l_a_i_i.x)));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 7ad0dea..0e6ea95 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
 kernel void f(const constant tint_array<float4x4, 4>* a [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .s=s};
   const constant tint_array<float4x4, 4>* const p_a = tint_module_vars.a;
-  const constant float4x4* const p_a_2 = (&(*p_a)[2]);
-  const constant float4* const p_a_2_1 = (&(*p_a_2)[1]);
+  const constant float4x4* const p_a_2 = (&(*p_a)[2u]);
+  const constant float4* const p_a_2_1 = (&(*p_a_2)[1u]);
   tint_array<float4x4, 4> const l_a = (*p_a);
   float4x4 const l_a_i = (*p_a_2);
   float4 const l_a_i_i = (*p_a_2_1);
-  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0][0][0u]) + l_a_i[0][0u]) + l_a_i_i[0u]);
+  (*tint_module_vars.s) = ((((*p_a_2_1)[0u] + l_a[0u][0u][0u]) + l_a_i[0u][0u]) + l_a_i_i[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index ab42cab..7897baa 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -48,29 +48,28 @@
 %_ptr_Uniform__arr_mat4v4float_uint_4 = OpTypePointer Uniform %_arr_mat4v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_mat4v4float_uint_4 %1 %uint_0
-      %p_a_2 = OpAccessChain %_ptr_Uniform_mat4v4float %p_a %int_2
-    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %int_1
+      %p_a_2 = OpAccessChain %_ptr_Uniform_mat4v4float %p_a %uint_2
+    %p_a_2_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_2 %uint_1
         %l_a = OpLoad %_arr_mat4v4float_uint_4 %p_a None
       %l_a_i = OpLoad %mat4v4float %p_a_2 None
     %l_a_i_i = OpLoad %v4float %p_a_2_1 None
-         %30 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
-         %32 = OpLoad %float %30 None
-         %33 = OpCompositeExtract %float %l_a 0 0 0
-         %34 = OpFAdd %float %32 %33
-         %35 = OpCompositeExtract %float %l_a_i 0 0
-         %36 = OpFAdd %float %34 %35
-         %37 = OpCompositeExtract %float %l_a_i_i 0
-         %38 = OpFAdd %float %36 %37
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %39 %38 None
+         %29 = OpAccessChain %_ptr_Uniform_float %p_a_2_1 %uint_0
+         %31 = OpLoad %float %29 None
+         %32 = OpCompositeExtract %float %l_a 0 0 0
+         %33 = OpFAdd %float %31 %32
+         %34 = OpCompositeExtract %float %l_a_i 0 0
+         %35 = OpFAdd %float %33 %34
+         %36 = OpCompositeExtract %float %l_a_i_i 0
+         %37 = OpFAdd %float %35 %36
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.glsl
index bc325de..56e635b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.glsl
@@ -10,9 +10,9 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4 t = transpose(v.inner[2]);
-  float l = length(v.inner[0][1].ywxz);
-  float a = abs(v.inner[0][1].ywxz[0u]);
-  float v_2 = (t[0][0u] + float(l));
+  mat4 t = transpose(v.inner[2u]);
+  float l = length(v.inner[0u][1u].ywxz);
+  float a = abs(v.inner[0u][1u].ywxz[0u]);
+  float v_2 = (t[0u][0u] + float(l));
   v_1.inner = (v_2 + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
index 6bd3603..8af3eaa 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
   float4x4 t = transpose(v(128u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
index 6bd3603..8af3eaa 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
   float4x4 t = transpose(v(128u));
   float l = length(asfloat(u[1u]).ywxz);
   float a = abs(asfloat(u[1u]).ywxz.x);
-  float v_1 = (t[int(0)].x + float(l));
+  float v_1 = (t[0u].x + float(l));
   s.Store(0u, asuint((v_1 + float(a))));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
index 027f3a0..a0fcf2b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 
 kernel void f(const constant tint_array<float4x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
-  float4x4 const t = transpose((*tint_module_vars.u)[2]);
-  float const l = length((*tint_module_vars.u)[0][1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0][1].ywxz[0u]);
-  float const v = (t[0][0u] + float(l));
+  float4x4 const t = transpose((*tint_module_vars.u)[2u]);
+  float const l = length((*tint_module_vars.u)[0u][1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u][1u].ywxz[0u]);
+  float const v = (t[0u][0u] + float(l));
   (*tint_module_vars.s) = (v + float(a));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.spvasm
index 7b231b7..4b14c90 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
-         %31 = OpExtInstImport "GLSL.std.450"
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -45,30 +45,28 @@
          %15 = OpTypeFunction %void
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %15
          %16 = OpLabel
-         %17 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2
-         %22 = OpLoad %mat4v4float %17 None
-          %t = OpTranspose %mat4v4float %22
-         %24 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %28 = OpLoad %v4float %24 None
-         %29 = OpVectorShuffle %v4float %28 %28 1 3 0 2
-          %l = OpExtInst %float %31 Length %29
-         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %33 = OpLoad %v4float %32 None
-         %34 = OpVectorShuffle %v4float %33 %33 1 3 0 2
-         %35 = OpCompositeExtract %float %34 0
-          %a = OpExtInst %float %31 FAbs %35
-         %37 = OpCompositeExtract %float %t 0 0
-         %38 = OpFAdd %float %37 %l
-         %39 = OpFAdd %float %38 %a
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %40 %39 None
+         %17 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2
+         %21 = OpLoad %mat4v4float %17 None
+          %t = OpTranspose %mat4v4float %21
+         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %26 = OpLoad %v4float %23 None
+         %27 = OpVectorShuffle %v4float %26 %26 1 3 0 2
+          %l = OpExtInst %float %29 Length %27
+         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %31 = OpLoad %v4float %30 None
+         %32 = OpVectorShuffle %v4float %31 %31 1 3 0 2
+         %33 = OpCompositeExtract %float %32 0
+          %a = OpExtInst %float %29 FAbs %33
+         %35 = OpCompositeExtract %float %t 0 0
+         %36 = OpFAdd %float %35 %l
+         %37 = OpFAdd %float %36 %a
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.glsl
index f98aa42..9128db8 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.glsl
@@ -9,10 +9,10 @@
   float inner;
 } v_2;
 float a(mat4 a_1[4]) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 float b(mat4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 float c(vec4 v) {
   return v[0u];
@@ -23,7 +23,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   float v_3 = a(v_1.inner);
-  float v_4 = (v_3 + b(v_1.inner[1]));
-  float v_5 = (v_4 + c(v_1.inner[1][0].ywxz));
-  v_2.inner = (v_5 + d(v_1.inner[1][0].ywxz[0u]));
+  float v_4 = (v_3 + b(v_1.inner[1u]));
+  float v_5 = (v_4 + c(v_1.inner[1u][0u].ywxz));
+  v_2.inner = (v_5 + d(v_1.inner[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
index ea983eb..6603a9e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.dxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
index ea983eb..6603a9e 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.fxc.hlsl
@@ -4,11 +4,11 @@
 };
 RWByteAddressBuffer s : register(u1);
 float a(float4x4 a_1[4]) {
-  return a_1[int(0)][int(0)].x;
+  return a_1[0u][0u].x;
 }
 
 float b(float4x4 m) {
-  return m[int(0)].x;
+  return m[0u].x;
 }
 
 float c(float4 v) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.msl
index 3b8cfe9..19f3535 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.ir.msl
@@ -19,11 +19,11 @@
 };
 
 float a(tint_array<float4x4, 4> a_1) {
-  return a_1[0][0][0u];
+  return a_1[0u][0u][0u];
 }
 
 float b(float4x4 m) {
-  return m[0][0u];
+  return m[0u][0u];
 }
 
 float c(float4 v) {
@@ -37,7 +37,7 @@
 kernel void f(const constant tint_array<float4x4, 4>* u [[buffer(0)]], device float* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   float const v_1 = a((*tint_module_vars.u));
-  float const v_2 = (v_1 + b((*tint_module_vars.u)[1]));
-  float const v_3 = (v_2 + c((*tint_module_vars.u)[1][0].ywxz));
-  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1][0].ywxz[0u]));
+  float const v_2 = (v_1 + b((*tint_module_vars.u)[1u]));
+  float const v_3 = (v_2 + c((*tint_module_vars.u)[1u][0u].ywxz));
+  (*tint_module_vars.s) = (v_3 + d((*tint_module_vars.u)[1u][0u].ywxz[0u]));
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.spvasm
index 1dbb9d8..07ae5f7 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -54,10 +54,8 @@
 %_ptr_Uniform__arr_mat4v4float_uint_4 = OpTypePointer Uniform %_arr_mat4v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %a = OpFunction %float None %15
         %a_0 = OpFunctionParameter %_arr_mat4v4float_uint_4
@@ -87,22 +85,22 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_mat4v4float_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_mat4v4float_uint_4 %36 None
          %40 = OpFunctionCall %float %a %39
-         %41 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_1
-         %45 = OpLoad %mat4v4float %41 None
-         %46 = OpFunctionCall %float %b %45
-         %47 = OpFAdd %float %40 %46
-         %48 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %51 = OpLoad %v4float %48 None
-         %52 = OpVectorShuffle %v4float %51 %51 1 3 0 2
-         %53 = OpFunctionCall %float %c %52
-         %54 = OpFAdd %float %47 %53
-         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1 %int_0
-         %56 = OpLoad %v4float %55 None
-         %57 = OpVectorShuffle %v4float %56 %56 1 3 0 2
-         %58 = OpCompositeExtract %float %57 0
-         %59 = OpFunctionCall %float %d %58
-         %60 = OpFAdd %float %54 %59
-         %61 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %61 %60 None
+         %41 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %mat4v4float %41 None
+         %45 = OpFunctionCall %float %b %44
+         %46 = OpFAdd %float %40 %45
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+         %51 = OpFunctionCall %float %c %50
+         %52 = OpFAdd %float %46 %51
+         %53 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1 %uint_0
+         %54 = OpLoad %v4float %53 None
+         %55 = OpVectorShuffle %v4float %54 %54 1 3 0 2
+         %56 = OpCompositeExtract %float %55 0
+         %57 = OpFunctionCall %float %d %56
+         %58 = OpFAdd %float %52 %57
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.glsl
index 9bdb49f..7bf032b 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.glsl
@@ -12,8 +12,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[1][0] = v.inner[0][1].ywxz;
-  p[1][0][0u] = v.inner[0][1].x;
-  v_1.inner = p[1][0].x;
+  p[1u] = v.inner[2u];
+  p[1u][0u] = v.inner[0u][1u].ywxz;
+  p[1u][0u][0u] = v.inner[0u][1u].x;
+  v_1.inner = p[1u][0u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 6af9542..839f9f5 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float4x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(128u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(128u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 6af9542..839f9f5 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -34,9 +34,9 @@
 void f() {
   float4x4 v_5[4] = v_1(0u);
   p = v_5;
-  p[int(1)] = v(128u);
-  p[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  p[int(1)][int(0)].x = asfloat(u[1u].x);
-  s.Store(0u, asuint(p[int(1)][int(0)].x));
+  p[1u] = v(128u);
+  p[1u][0u] = asfloat(u[1u]).ywxz;
+  p[1u][0u].x = asfloat(u[1u].x);
+  s.Store(0u, asuint(p[1u][0u].x));
 }
 
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.msl
index df22e0f..fad6a01 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.ir.msl
@@ -23,8 +23,8 @@
   thread tint_array<float4x4, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.p)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
-  (*tint_module_vars.s) = (*tint_module_vars.p)[1][0][0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.p)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
+  (*tint_module_vars.s) = (*tint_module_vars.p)[1u][0u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.spvasm
index 343621b..34e1fc5 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 51
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,12 +46,10 @@
 %_ptr_Uniform__arr_mat4v4float_uint_4 = OpTypePointer Uniform %_arr_mat4v4float_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_mat4v4float = OpTypePointer Private %mat4v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
@@ -61,25 +59,25 @@
          %20 = OpAccessChain %_ptr_Uniform__arr_mat4v4float_uint_4 %1 %uint_0
          %23 = OpLoad %_arr_mat4v4float_uint_4 %20 None
                OpStore %p %23 None
-         %24 = OpAccessChain %_ptr_Private_mat4v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2
-         %31 = OpLoad %mat4v4float %28 None
-               OpStore %24 %31 None
-         %32 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %37 = OpLoad %v4float %35 None
-         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
-               OpStore %32 %38 None
-         %39 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
-         %43 = OpLoad %float %41 None
-         %44 = OpAccessChain %_ptr_Private_float %39 %uint_0
-               OpStore %44 %43 None
-         %46 = OpAccessChain %_ptr_Private_v4float %p %int_1 %int_0
-         %47 = OpAccessChain %_ptr_Private_float %46 %uint_0
-         %48 = OpLoad %float %47 None
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
-               OpStore %49 %48 None
+         %24 = OpAccessChain %_ptr_Private_mat4v4float %p %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2
+         %30 = OpLoad %mat4v4float %27 None
+               OpStore %24 %30 None
+         %31 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %33 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %35 = OpLoad %v4float %33 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+               OpStore %31 %36 None
+         %37 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpAccessChain %_ptr_Private_float %37 %uint_0
+               OpStore %42 %41 None
+         %44 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_0
+         %45 = OpAccessChain %_ptr_Private_float %44 %uint_0
+         %46 = OpLoad %float %45 None
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %10 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.glsl
index 8663b42..d3117fc 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[2];
-  v_1.inner[1][0] = v.inner[0][1].ywxz;
-  v_1.inner[1][0][0u] = v.inner[0][1].x;
+  v_1.inner[1u] = v.inner[2u];
+  v_1.inner[1u][0u] = v.inner[0u][1u].ywxz;
+  v_1.inner[1u][0u][0u] = v.inner[0u][1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.ir.msl
index bc125fb..0850495 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.ir.msl
@@ -21,7 +21,7 @@
 kernel void f(const constant tint_array<float4x4, 4>* u [[buffer(0)]], device tint_array<float4x4, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.s)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.s)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.s)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.s)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.spvasm
index 1ac9747..28be2fb 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,12 +45,10 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer__arr_mat4v4float_uint_4 = OpTypePointer StorageBuffer %_arr_mat4v4float_uint_4
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
@@ -60,20 +58,20 @@
          %20 = OpLoad %_arr_mat4v4float_uint_4 %17 None
          %21 = OpAccessChain %_ptr_StorageBuffer__arr_mat4v4float_uint_4 %10 %uint_0
                OpStore %21 %20 None
-         %23 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %10 %uint_0 %int_1
-         %27 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2
-         %30 = OpLoad %mat4v4float %27 None
-               OpStore %23 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %36 = OpLoad %v4float %34 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-               OpStore %31 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %int_1 %int_0
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %38 %uint_0
-               OpStore %43 %42 None
+         %23 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %10 %uint_0 %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2
+         %29 = OpLoad %mat4v4float %26 None
+               OpStore %23 %29 None
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %34 = OpLoad %v4float %32 None
+         %35 = OpVectorShuffle %v4float %34 %34 1 3 0 2
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %10 %uint_0 %uint_1 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_float %37 %uint_0
+         %40 = OpLoad %float %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %36 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.glsl
index 2c80cda..1f310c0 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.glsl
@@ -23,9 +23,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[1][0] = v.inner[0][1].ywxz;
-  w[1][0][0u] = v.inner[0][1].x;
+  w[1u] = v.inner[2u];
+  w[1u][0u] = v.inner[0u][1u].ywxz;
+  w[1u][0u][0u] = v.inner[0u][1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 56c416e..e5da51d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(128u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(128u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 56c416e..e5da51d 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -52,9 +52,9 @@
   GroupMemoryBarrierWithGroupSync();
   float4x4 v_7[4] = v_1(0u);
   w = v_7;
-  w[int(1)] = v(128u);
-  w[int(1)][int(0)] = asfloat(u[1u]).ywxz;
-  w[int(1)][int(0)].x = asfloat(u[1u].x);
+  w[1u] = v(128u);
+  w[1u][0u] = asfloat(u[1u]).ywxz;
+  w[1u][0u].x = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
index 3e6728a..2bc2a32 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<float4x4, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<float4x4, 4> tint_symbol;
 };
@@ -27,6 +30,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -40,9 +44,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[1][0] = (*tint_module_vars.u)[0][1].ywxz;
-  (*tint_module_vars.w)[1][0][0u] = (*tint_module_vars.u)[0][1][0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[1u][0u] = (*tint_module_vars.u)[0u][1u].ywxz;
+  (*tint_module_vars.w)[1u][0u][0u] = (*tint_module_vars.u)[0u][1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<float4x4, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.msl
index e1ee04f..0e7c57c 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<float4x4, 4> w;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<float4x4, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i] = float4x4(float4(0.0f), float4(0.0f), float4(0.0f), float4(0.0f));
   }
diff --git a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
index 87e8578..09eb865 100644
--- a/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/array/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,16 +46,12 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_mat4v4float_uint_4 = OpTypePointer Uniform %_arr_mat4v4float_uint_4
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %63 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
     %f_inner = OpFunction %void None %17
 %tint_local_index = OpFunctionParameter %uint
          %18 = OpLabel
@@ -84,26 +80,26 @@
          %37 = OpAccessChain %_ptr_Uniform__arr_mat4v4float_uint_4 %1 %uint_0
          %40 = OpLoad %_arr_mat4v4float_uint_4 %37 None
                OpStore %w %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_mat4v4float %w %int_1
-         %44 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2
-         %47 = OpLoad %mat4v4float %44 None
-               OpStore %41 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %53 = OpLoad %v4float %51 None
-         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
-               OpStore %48 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %int_0
-         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %int_1
-         %57 = OpAccessChain %_ptr_Uniform_float %56 %uint_0
-         %59 = OpLoad %float %57 None
-         %60 = OpAccessChain %_ptr_Workgroup_float %55 %uint_0
-               OpStore %60 %59 None
+         %41 = OpAccessChain %_ptr_Workgroup_mat4v4float %w %uint_1
+         %42 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2
+         %44 = OpLoad %mat4v4float %42 None
+               OpStore %41 %44 None
+         %45 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %49 = OpLoad %v4float %47 None
+         %50 = OpVectorShuffle %v4float %49 %49 1 3 0 2
+               OpStore %45 %50 None
+         %51 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_0
+         %52 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Uniform_float %52 %uint_0
+         %55 = OpLoad %float %53 None
+         %56 = OpAccessChain %_ptr_Workgroup_float %51 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpLoad %uint %f_local_invocation_index_Input None
+         %62 = OpFunctionCall %void %f_inner %61
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 399a552..92b00fe 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -61,18 +61,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 2, 2> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (4u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 2, 2> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (4u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   uint ubo_load_2 = a[scalar_offset_2 / 4][scalar_offset_2 % 4];
   vector<float16_t, 2> l_a_i_a_i_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16)));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (4u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (4u * min(uint(tint_symbol_2), 1u))) + (2u * min(uint(tint_symbol_3), 1u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index e23aa51..ccab01e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -66,10 +66,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat2 v_6 = f16mat2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1);
-  f16vec2 v_7 = v_6[i()];
+  f16vec2 v_7 = v_6[min(uint(i()), 1u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -110,5 +110,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat2 l_a_i_a_i_m = v_6;
   f16vec2 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 1bb394d..4f1a065 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -88,16 +88,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_19 = (256u * uint(i()));
-  uint v_20 = (64u * uint(i()));
-  uint v_21 = (4u * uint(i()));
+  uint v_19 = (256u * uint(min(uint(i()), 3u)));
+  uint v_20 = (64u * uint(min(uint(i()), 3u)));
+  uint v_21 = (4u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_14(0u);
   Outer l_a_i = v_11(v_19);
   Inner l_a_i_a[4] = v_6(v_19);
   Inner l_a_i_a_i = v_4((v_19 + v_20));
   matrix<float16_t, 2, 2> l_a_i_a_i_m = v_2((v_19 + v_20));
   vector<float16_t, 2> l_a_i_a_i_m_i = tint_bitcast_to_f16(a[(((v_19 + v_20) + v_21) / 16u)][((((v_19 + v_20) + v_21) % 16u) / 4u)]);
-  uint v_22 = (((v_19 + v_20) + v_21) + (uint(i()) * 2u));
+  uint v_22 = (((v_19 + v_20) + v_21) + (uint(min(uint(i()), 1u)) * 2u));
   uint v_23 = a[(v_22 / 16u)][((v_22 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_23 >> ((((v_22 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index e2265f9..fad9e1a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half2x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half2x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 17a32f3..597db5b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half2x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 1a16e3c..f7a0240 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 140
+; Bound: 150
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,6 +73,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -86,17 +88,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %61 = OpConstantNull %_arr_Outer_uint_4
+         %69 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %88 = OpConstantNull %_arr_Inner_uint_4
+         %96 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %112 = OpTypeFunction %Inner %Inner_std140
-        %119 = OpTypeFunction %Outer %Outer_std140
+        %122 = OpTypeFunction %Inner %Inner_std140
+        %129 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -107,129 +109,137 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat2v2half Function
-         %53 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %61
-         %84 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %86 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
+         %52 = OpVariable %_ptr_Function_mat2v2half Function
+         %61 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %63 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %69
+         %92 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %94 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_0
-         %40 = OpLoad %v2half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_1
-         %43 = OpLoad %v2half %41 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat2v2half %40 %43
-               OpStore %46 %l_a_i_a_i_m
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v2half %46 %48
-%l_a_i_a_i_m_i = OpLoad %v2half %49 None
-         %52 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %53 %52
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %65
-         %65 = OpLabel
-         %67 = OpPhi %uint %uint_0 %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_4
-               OpSelectionMerge %71 None
-               OpBranchConditional %69 %72 %71
-         %72 = OpLabel
-               OpBranch %66
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_0
+         %46 = OpLoad %v2half %44 None
+         %47 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_1
+         %49 = OpLoad %v2half %47 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat2v2half %46 %49
+               OpStore %52 %l_a_i_a_i_m
+         %54 = OpFunctionCall %int %i
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %33 UMin %55 %uint_1
+         %57 = OpAccessChain %_ptr_Function_v2half %52 %56
+%l_a_i_a_i_m_i = OpLoad %v2half %57 None
+         %60 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %61 %60
+               OpBranch %70
+         %70 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+         %75 = OpPhi %uint %uint_0 %70 %76 %72
+               OpLoopMerge %74 %72 None
+               OpBranch %71
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_Function_Outer %55 %67
-         %75 = OpAccessChain %_ptr_Function_Outer_std140 %53 %67
-         %77 = OpLoad %Outer_std140 %75 None
-         %78 = OpFunctionCall %Outer %tint_convert_Outer %77
-               OpStore %73 %78 None
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
-         %66 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %55 None
-         %81 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %81
-         %83 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %84 %83
-               OpBranch %89
-         %89 = OpLabel
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpPhi %uint %uint_0 %89 %95 %91
-               OpLoopMerge %93 %91 None
-               OpBranch %90
-         %90 = OpLabel
-         %96 = OpUGreaterThanEqual %bool %94 %uint_4
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
-               OpBranch %93
+         %77 = OpUGreaterThanEqual %bool %75 %uint_4
+               OpSelectionMerge %79 None
+               OpBranchConditional %77 %80 %79
+         %80 = OpLabel
+               OpBranch %74
+         %79 = OpLabel
+         %81 = OpAccessChain %_ptr_Function_Outer %63 %75
+         %83 = OpAccessChain %_ptr_Function_Outer_std140 %61 %75
+         %85 = OpLoad %Outer_std140 %83 None
+         %86 = OpFunctionCall %Outer %tint_convert_Outer %85
+               OpStore %81 %86 None
+               OpBranch %72
+         %72 = OpLabel
+         %76 = OpIAdd %uint %75 %uint_1
+               OpBranch %73
+         %74 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %63 None
+         %89 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %89
+         %91 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %92 %91
+               OpBranch %97
          %97 = OpLabel
-         %99 = OpAccessChain %_ptr_Function_Inner %86 %94
-        %101 = OpAccessChain %_ptr_Function_Inner_std140 %84 %94
-        %103 = OpLoad %Inner_std140 %101 None
-        %104 = OpFunctionCall %Inner %tint_convert_Inner %103
-               OpStore %99 %104 None
-               OpBranch %91
-         %91 = OpLabel
-         %95 = OpIAdd %uint %94 %uint_1
-               OpBranch %92
-         %93 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %86 None
-        %107 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %107
-        %109 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %109
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpPhi %uint %uint_0 %97 %103 %99
+               OpLoopMerge %101 %99 None
+               OpBranch %98
+         %98 = OpLabel
+        %104 = OpUGreaterThanEqual %bool %102 %uint_4
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
+               OpBranch %101
+        %105 = OpLabel
+        %107 = OpAccessChain %_ptr_Function_Inner %94 %102
+        %109 = OpAccessChain %_ptr_Function_Inner_std140 %92 %102
+        %111 = OpLoad %Inner_std140 %109 None
+        %112 = OpFunctionCall %Inner %tint_convert_Inner %111
+               OpStore %107 %112 None
+               OpBranch %99
+         %99 = OpLabel
+        %103 = OpIAdd %uint %102 %uint_1
+               OpBranch %100
+        %101 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %94 None
+        %115 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %115
+        %117 = OpFunctionCall %int %i
+        %118 = OpBitcast %uint %117
+        %119 = OpExtInst %uint %33 UMin %118 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %119
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %112
+%tint_convert_Inner = OpFunction %Inner None %122
  %tint_input = OpFunctionParameter %Inner_std140
-        %113 = OpLabel
-        %114 = OpCompositeExtract %v2half %tint_input 0
-        %115 = OpCompositeExtract %v2half %tint_input 1
-        %116 = OpCompositeConstruct %mat2v2half %114 %115
-        %117 = OpCompositeConstruct %Inner %116
-               OpReturnValue %117
+        %123 = OpLabel
+        %124 = OpCompositeExtract %v2half %tint_input 0
+        %125 = OpCompositeExtract %v2half %tint_input 1
+        %126 = OpCompositeConstruct %mat2v2half %124 %125
+        %127 = OpCompositeConstruct %Inner %126
+               OpReturnValue %127
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %119
+%tint_convert_Outer = OpFunction %Outer None %129
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %120 = OpLabel
-        %122 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %123 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
-        %121 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %122 %121
-               OpBranch %124
-        %124 = OpLabel
-               OpBranch %127
-        %127 = OpLabel
-        %129 = OpPhi %uint %uint_0 %124 %130 %126
-               OpLoopMerge %128 %126 None
-               OpBranch %125
-        %125 = OpLabel
-        %131 = OpUGreaterThanEqual %bool %129 %uint_4
-               OpSelectionMerge %132 None
-               OpBranchConditional %131 %133 %132
-        %133 = OpLabel
-               OpBranch %128
-        %132 = OpLabel
-        %134 = OpAccessChain %_ptr_Function_Inner %123 %129
-        %135 = OpAccessChain %_ptr_Function_Inner_std140 %122 %129
-        %136 = OpLoad %Inner_std140 %135 None
-        %137 = OpFunctionCall %Inner %tint_convert_Inner %136
-               OpStore %134 %137 None
-               OpBranch %126
-        %126 = OpLabel
-        %130 = OpIAdd %uint %129 %uint_1
-               OpBranch %127
-        %128 = OpLabel
-        %138 = OpLoad %_arr_Inner_uint_4 %123 None
-        %139 = OpCompositeConstruct %Outer %138
-               OpReturnValue %139
+        %130 = OpLabel
+        %132 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %133 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
+        %131 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %132 %131
+               OpBranch %134
+        %134 = OpLabel
+               OpBranch %137
+        %137 = OpLabel
+        %139 = OpPhi %uint %uint_0 %134 %140 %136
+               OpLoopMerge %138 %136 None
+               OpBranch %135
+        %135 = OpLabel
+        %141 = OpUGreaterThanEqual %bool %139 %uint_4
+               OpSelectionMerge %142 None
+               OpBranchConditional %141 %143 %142
+        %143 = OpLabel
+               OpBranch %138
+        %142 = OpLabel
+        %144 = OpAccessChain %_ptr_Function_Inner %133 %139
+        %145 = OpAccessChain %_ptr_Function_Inner_std140 %132 %139
+        %146 = OpLoad %Inner_std140 %145 None
+        %147 = OpFunctionCall %Inner %tint_convert_Inner %146
+               OpStore %144 %147 None
+               OpBranch %136
+        %136 = OpLabel
+        %140 = OpIAdd %uint %139 %uint_1
+               OpBranch %137
+        %138 = OpLabel
+        %148 = OpLoad %_arr_Inner_uint_4 %133 None
+        %149 = OpCompositeConstruct %Outer %148
+               OpReturnValue %149
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 5f79ac0..c500d6a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -61,7 +61,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2 v_4 = f16mat2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1);
+  f16mat2 v_4 = f16mat2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -80,8 +80,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat2(f16vec2(0.0hf), f16vec2(0.0hf))));
   {
     uint v_11 = 0u;
@@ -99,8 +99,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat2 l_a_3_a_2_m = v_4;
-  f16vec2 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 77214d9..80d232b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half2x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half2x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.spvasm
index 1e7b8a3..6fc0bb5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 124
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,11 +65,10 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_1 = OpConstant %uint 1
  %mat2v2half = OpTypeMatrix %v2half 2
@@ -79,135 +78,135 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %46 = OpConstantNull %_arr_Outer_uint_4
+         %45 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %73 = OpConstantNull %_arr_Inner_uint_4
+         %72 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %96 = OpTypeFunction %Inner %Inner_std140
-        %103 = OpTypeFunction %Outer %Outer_std140
+         %95 = OpTypeFunction %Inner %Inner_std140
+        %102 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %46
-         %69 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %71 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
+         %37 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %39 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %45
+         %68 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %70 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_0
-         %30 = OpLoad %v2half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_1
-         %33 = OpLoad %v2half %31 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat2v2half %30 %33
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_0
+         %29 = OpLoad %v2half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_1
+         %32 = OpLoad %v2half %30 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat2v2half %29 %32
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2half %l_a_3_a_2_m 1
-         %37 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %38 %37
-               OpBranch %47
-         %47 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-         %52 = OpPhi %uint %uint_0 %47 %53 %49
-               OpLoopMerge %51 %49 None
-               OpBranch %48
-         %48 = OpLabel
-         %54 = OpUGreaterThanEqual %bool %52 %uint_4
-               OpSelectionMerge %56 None
-               OpBranchConditional %54 %57 %56
-         %57 = OpLabel
-               OpBranch %51
-         %56 = OpLabel
-         %58 = OpAccessChain %_ptr_Function_Outer %40 %52
-         %60 = OpAccessChain %_ptr_Function_Outer_std140 %38 %52
-         %62 = OpLoad %Outer_std140 %60 None
-         %63 = OpFunctionCall %Outer %tint_convert_Outer %62
-               OpStore %58 %63 None
+         %36 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %37 %36
+               OpBranch %46
+         %46 = OpLabel
                OpBranch %49
          %49 = OpLabel
-         %53 = OpIAdd %uint %52 %uint_1
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
-         %51 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %40 None
-         %66 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %66
-         %68 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %69 %68
-               OpBranch %74
-         %74 = OpLabel
-               OpBranch %77
-         %77 = OpLabel
-         %79 = OpPhi %uint %uint_0 %74 %80 %76
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %81 = OpUGreaterThanEqual %bool %79 %uint_4
-               OpSelectionMerge %82 None
-               OpBranchConditional %81 %83 %82
-         %83 = OpLabel
-               OpBranch %78
-         %82 = OpLabel
-         %84 = OpAccessChain %_ptr_Function_Inner %71 %79
-         %86 = OpAccessChain %_ptr_Function_Inner_std140 %69 %79
-         %88 = OpLoad %Inner_std140 %86 None
-         %89 = OpFunctionCall %Inner %tint_convert_Inner %88
-               OpStore %84 %89 None
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_Outer %39 %51
+         %59 = OpAccessChain %_ptr_Function_Outer_std140 %37 %51
+         %61 = OpLoad %Outer_std140 %59 None
+         %62 = OpFunctionCall %Outer %tint_convert_Outer %61
+               OpStore %57 %62 None
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
+         %50 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %39 None
+         %65 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %65
+         %67 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %68 %67
+               OpBranch %73
+         %73 = OpLabel
                OpBranch %76
          %76 = OpLabel
-         %80 = OpIAdd %uint %79 %uint_1
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
+         %74 = OpLabel
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %81
+         %82 = OpLabel
                OpBranch %77
-         %78 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %71 None
-         %92 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %92
+         %81 = OpLabel
+         %83 = OpAccessChain %_ptr_Function_Inner %70 %78
+         %85 = OpAccessChain %_ptr_Function_Inner_std140 %68 %78
+         %87 = OpLoad %Inner_std140 %85 None
+         %88 = OpFunctionCall %Inner %tint_convert_Inner %87
+               OpStore %83 %88 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %70 None
+         %91 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %91
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %96
+%tint_convert_Inner = OpFunction %Inner None %95
  %tint_input = OpFunctionParameter %Inner_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %v2half %tint_input 0
-         %99 = OpCompositeExtract %v2half %tint_input 1
-        %100 = OpCompositeConstruct %mat2v2half %98 %99
-        %101 = OpCompositeConstruct %Inner %100
-               OpReturnValue %101
+         %96 = OpLabel
+         %97 = OpCompositeExtract %v2half %tint_input 0
+         %98 = OpCompositeExtract %v2half %tint_input 1
+         %99 = OpCompositeConstruct %mat2v2half %97 %98
+        %100 = OpCompositeConstruct %Inner %99
+               OpReturnValue %100
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %103
+%tint_convert_Outer = OpFunction %Outer None %102
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %104 = OpLabel
-        %106 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %107 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
-        %105 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %106 %105
-               OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_4
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_Inner %107 %113
-        %119 = OpAccessChain %_ptr_Function_Inner_std140 %106 %113
-        %120 = OpLoad %Inner_std140 %119 None
-        %121 = OpFunctionCall %Inner %tint_convert_Inner %120
-               OpStore %118 %121 None
+        %103 = OpLabel
+        %105 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %106 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
+        %104 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %105 %104
+               OpBranch %107
+        %107 = OpLabel
                OpBranch %110
         %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
+        %112 = OpPhi %uint %uint_0 %107 %113 %109
+               OpLoopMerge %111 %109 None
+               OpBranch %108
+        %108 = OpLabel
+        %114 = OpUGreaterThanEqual %bool %112 %uint_4
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %115
+        %116 = OpLabel
                OpBranch %111
-        %112 = OpLabel
-        %122 = OpLoad %_arr_Inner_uint_4 %107 None
-        %123 = OpCompositeConstruct %Outer %122
-               OpReturnValue %123
+        %115 = OpLabel
+        %117 = OpAccessChain %_ptr_Function_Inner %106 %112
+        %118 = OpAccessChain %_ptr_Function_Inner_std140 %105 %112
+        %119 = OpLoad %Inner_std140 %118 None
+        %120 = OpFunctionCall %Inner %tint_convert_Inner %119
+               OpStore %117 %120 None
+               OpBranch %109
+        %109 = OpLabel
+        %113 = OpIAdd %uint %112 %uint_1
+               OpBranch %110
+        %111 = OpLabel
+        %121 = OpLoad %_arr_Inner_uint_4 %106 None
+        %122 = OpCompositeConstruct %Outer %121
+               OpReturnValue %122
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.glsl
index 77f2946..778958c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.glsl
@@ -43,7 +43,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2 t = transpose(f16mat2(v.inner[2].m_col0, v.inner[2].m_col1));
-  float16_t l = length(v.inner[0].m_col1.yx);
-  float16_t a = abs(v.inner[0].m_col1.yx[0u]);
+  f16mat2 t = transpose(f16mat2(v.inner[2u].m_col0, v.inner[2u].m_col1));
+  float16_t l = length(v.inner[0u].m_col1.yx);
+  float16_t a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
index 5595ca9..996ea35 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -27,7 +27,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half2x2 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].yx);
-  half const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  half2x2 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.spvasm
index ad53c87..0e9f422 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %32 = OpExtInstImport "GLSL.std.450"
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -46,27 +46,25 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
  %mat2v2half = OpTypeMatrix %v2half 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2half %21 None
-         %25 = OpCompositeConstruct %mat2v2half %20 %23
-          %t = OpTranspose %mat2v2half %25
-         %27 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %29 = OpLoad %v2half %27 None
-         %30 = OpVectorShuffle %v2half %29 %29 1 0
-          %l = OpExtInst %half %32 Length %30
-         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v2half %33 None
-         %35 = OpVectorShuffle %v2half %34 %34 1 0
-         %36 = OpCompositeExtract %half %35 0
-          %a = OpExtInst %half %32 FAbs %36
+         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2half %21 None
+         %24 = OpCompositeConstruct %mat2v2half %20 %22
+          %t = OpTranspose %mat2v2half %24
+         %26 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %27 = OpLoad %v2half %26 None
+         %28 = OpVectorShuffle %v2half %27 %27 1 0
+          %l = OpExtInst %half %30 Length %28
+         %31 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v2half %31 None
+         %33 = OpVectorShuffle %v2half %32 %32 1 0
+         %34 = OpCompositeExtract %half %33 0
+          %a = OpExtInst %half %30 FAbs %34
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.glsl
index 3f21cc6..6347a59 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.glsl
@@ -80,8 +80,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat2(v_1.inner[2].m_col0, v_1.inner[2].m_col1));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.ir.msl
index 82a5fb6..a064c31 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.ir.msl
@@ -43,8 +43,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.spvasm
index 5c0167d..34f30f5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 101
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -80,11 +80,9 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
-      %int_0 = OpConstant %int 0
-         %93 = OpTypeFunction %S %S_std140
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
+         %91 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -143,35 +141,35 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2half %77 None
-         %80 = OpCompositeConstruct %mat2v2half %76 %79
-         %81 = OpFunctionCall %void %c %80
-         %82 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v2half %82 None
-         %85 = OpVectorShuffle %v2half %84 %84 1 0
-         %86 = OpFunctionCall %void %d %85
-         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v2half %87 None
-         %89 = OpVectorShuffle %v2half %88 %88 1 0
-         %90 = OpCompositeExtract %half %89 0
-         %91 = OpFunctionCall %void %e %90
+         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2half %77 None
+         %79 = OpCompositeConstruct %mat2v2half %76 %78
+         %80 = OpFunctionCall %void %c %79
+         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %82 = OpLoad %v2half %81 None
+         %83 = OpVectorShuffle %v2half %82 %82 1 0
+         %84 = OpFunctionCall %void %d %83
+         %85 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %86 = OpLoad %v2half %85 None
+         %87 = OpVectorShuffle %v2half %86 %86 1 0
+         %88 = OpCompositeExtract %half %87 0
+         %89 = OpFunctionCall %void %e %88
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %93
+%tint_convert_S = OpFunction %S None %91
  %tint_input = OpFunctionParameter %S_std140
-         %94 = OpLabel
-         %95 = OpCompositeExtract %int %tint_input 0
-         %96 = OpCompositeExtract %v2half %tint_input 1
-         %97 = OpCompositeExtract %v2half %tint_input 2
-         %98 = OpCompositeConstruct %mat2v2half %96 %97
-         %99 = OpCompositeExtract %int %tint_input 3
-        %100 = OpCompositeConstruct %S %95 %98 %99
-               OpReturnValue %100
+         %92 = OpLabel
+         %93 = OpCompositeExtract %int %tint_input 0
+         %94 = OpCompositeExtract %v2half %tint_input 1
+         %95 = OpCompositeExtract %v2half %tint_input 2
+         %96 = OpCompositeConstruct %mat2v2half %94 %95
+         %97 = OpCompositeExtract %int %tint_input 3
+         %98 = OpCompositeConstruct %S %93 %96 %97
+               OpReturnValue %98
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.glsl
index 2682f8e..854db5e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.glsl
@@ -71,7 +71,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 42a8628..abbfa9e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -57,8 +57,8 @@
   S v_13[4] = v_8(0u);
   p = v_13;
   S v_14 = v_4(256u);
-  p[int(1)] = v_14;
-  p[int(3)].m = v_2(260u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  p[1u] = v_14;
+  p[3u].m = v_2(260u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.msl
index fcdcb3f..55b5dfc 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.spvasm
index b2e86fd..aa83d5e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 82
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -68,16 +68,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v2half = OpTypePointer Private %mat2v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v2half = OpTypePointer Private %mat2v2half
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-      %int_0 = OpConstant %int 0
-         %74 = OpTypeFunction %S %S_std140
+         %71 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -111,33 +108,33 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat2v2half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2half %63 None
-         %66 = OpCompositeConstruct %mat2v2half %62 %65
-               OpStore %57 %66 None
-         %67 = OpAccessChain %_ptr_Private_v2half %p %int_1 %uint_1 %int_0
-         %70 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %71 = OpLoad %v2half %70 None
-         %72 = OpVectorShuffle %v2half %71 %71 1 0
-               OpStore %67 %72 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat2v2half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2half %62 None
+         %64 = OpCompositeConstruct %mat2v2half %61 %63
+               OpStore %56 %64 None
+         %65 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %68 = OpLoad %v2half %67 None
+         %69 = OpVectorShuffle %v2half %68 %68 1 0
+               OpStore %65 %69 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %74
+%tint_convert_S = OpFunction %S None %71
  %tint_input = OpFunctionParameter %S_std140
-         %75 = OpLabel
-         %76 = OpCompositeExtract %int %tint_input 0
-         %77 = OpCompositeExtract %v2half %tint_input 1
-         %78 = OpCompositeExtract %v2half %tint_input 2
-         %79 = OpCompositeConstruct %mat2v2half %77 %78
-         %80 = OpCompositeExtract %int %tint_input 3
-         %81 = OpCompositeConstruct %S %76 %79 %80
-               OpReturnValue %81
+         %72 = OpLabel
+         %73 = OpCompositeExtract %int %tint_input 0
+         %74 = OpCompositeExtract %v2half %tint_input 1
+         %75 = OpCompositeExtract %v2half %tint_input 2
+         %76 = OpCompositeConstruct %mat2v2half %74 %75
+         %77 = OpCompositeExtract %int %tint_input 3
+         %78 = OpCompositeConstruct %S %73 %76 %77
+               OpReturnValue %78
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.glsl
index efdabbf..1d6e379 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.glsl
@@ -124,8 +124,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.ir.msl
index ef86daa..0d61ebe 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -37,6 +40,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -53,7 +57,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.msl
index 1cc33f8..8cac0fe 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half2x2 m;
@@ -30,7 +33,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.spvasm
index 1a83851..4b73b9f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 118
+; Bound: 114
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -81,19 +81,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat2v2half = OpTypePointer StorageBuffer %mat2v2half
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-      %int_0 = OpConstant %int 0
-         %80 = OpTypeFunction %void %_arr_S_uint_4
-         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %76 = OpTypeFunction %void %_arr_S_uint_4
+         %95 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %110 = OpTypeFunction %S %S_std140
+        %106 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -127,80 +124,79 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2half %69 None
-         %72 = OpCompositeConstruct %mat2v2half %68 %71
-               OpStore %63 %72 None
-         %73 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %int_1 %uint_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %77 = OpLoad %v2half %76 None
-         %78 = OpVectorShuffle %v2half %77 %77 1 0
-               OpStore %73 %78 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2half %67 None
+         %69 = OpCompositeConstruct %mat2v2half %66 %68
+               OpStore %61 %69 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %72 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %73 = OpLoad %v2half %72 None
+         %74 = OpVectorShuffle %v2half %73 %73 1 0
+               OpStore %70 %74 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %80
+%tint_store_and_preserve_padding = OpFunction %void None %76
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %81 = OpLabel
-         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %82 %value_param
+         %77 = OpLabel
+         %78 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %78 %value_param
+               OpBranch %79
+         %79 = OpLabel
+               OpBranch %82
+         %82 = OpLabel
+         %84 = OpPhi %uint %uint_0 %79 %85 %81
+               OpLoopMerge %83 %81 None
+               OpBranch %80
+         %80 = OpLabel
+         %86 = OpUGreaterThanEqual %bool %84 %uint_4
+               OpSelectionMerge %87 None
+               OpBranchConditional %86 %88 %87
+         %88 = OpLabel
                OpBranch %83
-         %83 = OpLabel
-               OpBranch %86
-         %86 = OpLabel
-         %88 = OpPhi %uint %uint_0 %83 %89 %85
-               OpLoopMerge %87 %85 None
-               OpBranch %84
-         %84 = OpLabel
-         %90 = OpUGreaterThanEqual %bool %88 %uint_4
-               OpSelectionMerge %91 None
-               OpBranchConditional %90 %92 %91
-         %92 = OpLabel
-               OpBranch %87
-         %91 = OpLabel
-         %93 = OpAccessChain %_ptr_Function_S %82 %88
-         %94 = OpLoad %S %93 None
-         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
-         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
-               OpBranch %85
-         %85 = OpLabel
-         %89 = OpIAdd %uint %88 %uint_1
-               OpBranch %86
          %87 = OpLabel
+         %89 = OpAccessChain %_ptr_Function_S %78 %84
+         %90 = OpLoad %S %89 None
+         %91 = OpCompositeConstruct %_arr_uint_uint_1 %84
+         %92 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %91 %90
+               OpBranch %81
+         %81 = OpLabel
+         %85 = OpIAdd %uint %84 %uint_1
+               OpBranch %82
+         %83 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %99
+%tint_store_and_preserve_padding_0 = OpFunction %void None %95
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %100 = OpLabel
-        %101 = OpCompositeExtract %uint %target_indices 0
-        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
-        %104 = OpCompositeExtract %int %value_param_0 0
-               OpStore %102 %104 None
-        %105 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %11 %uint_0 %101 %uint_1
-        %106 = OpCompositeExtract %mat2v2half %value_param_0 1
-               OpStore %105 %106 None
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
-        %108 = OpCompositeExtract %int %value_param_0 2
-               OpStore %107 %108 None
+         %96 = OpLabel
+         %97 = OpCompositeExtract %uint %target_indices 0
+         %98 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_0
+        %100 = OpCompositeExtract %int %value_param_0 0
+               OpStore %98 %100 None
+        %101 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %11 %uint_0 %97 %uint_1
+        %102 = OpCompositeExtract %mat2v2half %value_param_0 1
+               OpStore %101 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_2
+        %104 = OpCompositeExtract %int %value_param_0 2
+               OpStore %103 %104 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %110
+%tint_convert_S = OpFunction %S None %106
  %tint_input = OpFunctionParameter %S_std140
-        %111 = OpLabel
-        %112 = OpCompositeExtract %int %tint_input 0
-        %113 = OpCompositeExtract %v2half %tint_input 1
-        %114 = OpCompositeExtract %v2half %tint_input 2
-        %115 = OpCompositeConstruct %mat2v2half %113 %114
-        %116 = OpCompositeExtract %int %tint_input 3
-        %117 = OpCompositeConstruct %S %112 %115 %116
-               OpReturnValue %117
+        %107 = OpLabel
+        %108 = OpCompositeExtract %int %tint_input 0
+        %109 = OpCompositeExtract %v2half %tint_input 1
+        %110 = OpCompositeExtract %v2half %tint_input 2
+        %111 = OpCompositeConstruct %mat2v2half %109 %110
+        %112 = OpCompositeExtract %int %tint_input 3
+        %113 = OpCompositeConstruct %S %108 %111 %112
+               OpReturnValue %113
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.glsl
index 6dfe11d..6df85fb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.glsl
@@ -86,9 +86,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index c08096b..06671b6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -77,9 +77,9 @@
   S v_16[4] = v_8(0u);
   w = v_16;
   S v_17 = v_4(256u);
-  w[int(1)] = v_17;
-  w[int(3)].m = v_2(260u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  w[1u] = v_17;
+  w[3u].m = v_2(260u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
index cdb0a34..9e890cd 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -48,9 +52,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.msl
index fc3370f..2da2d6f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half2x2 m;
@@ -28,6 +31,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
index 6f13a4f..dae0dbf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -77,16 +77,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v2half = OpTypePointer Workgroup %mat2v2half
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-      %int_0 = OpConstant %int 0
-         %91 = OpTypeFunction %void
-         %96 = OpTypeFunction %S %S_std140
+         %88 = OpTypeFunction %void
+         %93 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -143,39 +140,39 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat2v2half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %82 = OpLoad %v2half %81 None
-         %83 = OpCompositeConstruct %mat2v2half %80 %82
-               OpStore %75 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1 %uint_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v2half %87 None
-         %89 = OpVectorShuffle %v2half %88 %88 1 0
-               OpStore %84 %89 None
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat2v2half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2half %79 None
+         %81 = OpCompositeConstruct %mat2v2half %78 %80
+               OpStore %73 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1 %uint_1 %uint_0
+         %84 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v2half %84 None
+         %86 = OpVectorShuffle %v2half %85 %85 1 0
+               OpStore %82 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %88
+         %89 = OpLabel
+         %90 = OpLoad %uint %f_local_invocation_index_Input None
+         %91 = OpFunctionCall %void %f_inner %90
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %93
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v2half %tint_input 1
-        %100 = OpCompositeExtract %v2half %tint_input 2
-        %101 = OpCompositeConstruct %mat2v2half %99 %100
-        %102 = OpCompositeExtract %int %tint_input 3
-        %103 = OpCompositeConstruct %S %98 %101 %102
-               OpReturnValue %103
+         %94 = OpLabel
+         %95 = OpCompositeExtract %int %tint_input 0
+         %96 = OpCompositeExtract %v2half %tint_input 1
+         %97 = OpCompositeExtract %v2half %tint_input 2
+         %98 = OpCompositeConstruct %mat2v2half %96 %97
+         %99 = OpCompositeExtract %int %tint_input 3
+        %100 = OpCompositeConstruct %S %95 %98 %99
+               OpReturnValue %100
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 949b1ac..10a4a8a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -61,18 +61,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   uint4 ubo_load_2 = a[scalar_offset_2 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 949b1ac..10a4a8a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -61,18 +61,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   uint4 ubo_load_2 = a[scalar_offset_2 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index db5eee9..9fec8d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -63,10 +63,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat2 v_6 = mat2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1);
-  vec2 v_7 = v_6[i()];
+  vec2 v_7 = v_6[min(uint(i()), 1u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))));
   {
@@ -107,5 +107,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat2 l_a_i_a_i_m = v_6;
   vec2 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 9d27718..0dc9504 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -82,9 +82,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_19 = (256u * uint(i()));
-  uint v_20 = (64u * uint(i()));
-  uint v_21 = (8u * uint(i()));
+  uint v_19 = (256u * uint(min(uint(i()), 3u)));
+  uint v_20 = (64u * uint(min(uint(i()), 3u)));
+  uint v_21 = (8u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_14(0u);
   Outer l_a_i = v_11(v_19);
   Inner l_a_i_a[4] = v_6(v_19);
@@ -92,7 +92,7 @@
   float2x2 l_a_i_a_i_m = v((v_19 + v_20));
   uint4 v_22 = a[(((v_19 + v_20) + v_21) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_19 + v_20) + v_21) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy)));
-  uint v_23 = (((v_19 + v_20) + v_21) + (uint(i()) * 4u));
+  uint v_23 = (((v_19 + v_20) + v_21) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_23 / 16u)][((v_23 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 9d27718..0dc9504 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -82,9 +82,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_19 = (256u * uint(i()));
-  uint v_20 = (64u * uint(i()));
-  uint v_21 = (8u * uint(i()));
+  uint v_19 = (256u * uint(min(uint(i()), 3u)));
+  uint v_20 = (64u * uint(min(uint(i()), 3u)));
+  uint v_21 = (8u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_14(0u);
   Outer l_a_i = v_11(v_19);
   Inner l_a_i_a[4] = v_6(v_19);
@@ -92,7 +92,7 @@
   float2x2 l_a_i_a_i_m = v((v_19 + v_20));
   uint4 v_22 = a[(((v_19 + v_20) + v_21) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_19 + v_20) + v_21) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy)));
-  uint v_23 = (((v_19 + v_20) + v_21) + (uint(i()) * 4u));
+  uint v_23 = (((v_19 + v_20) + v_21) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_23 / 16u)][((v_23 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 9c04bdc..9a55335 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float2x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float2x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index e8a41dd..ddd1c90 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   float2x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index a03e14a..f94511f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 140
+; Bound: 150
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -69,6 +70,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -83,17 +85,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %61 = OpConstantNull %_arr_Outer_uint_4
+         %69 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %88 = OpConstantNull %_arr_Inner_uint_4
+         %96 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %112 = OpTypeFunction %Inner %Inner_std140
-        %119 = OpTypeFunction %Outer %Outer_std140
+        %122 = OpTypeFunction %Inner %Inner_std140
+        %129 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -104,129 +106,137 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat2v2float Function
-         %53 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %61
-         %84 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %86 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
+         %52 = OpVariable %_ptr_Function_mat2v2float Function
+         %61 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %63 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %69
+         %92 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %94 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_0
-         %40 = OpLoad %v2float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_1
-         %43 = OpLoad %v2float %41 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat2v2float %40 %43
-               OpStore %46 %l_a_i_a_i_m
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v2float %46 %48
-%l_a_i_a_i_m_i = OpLoad %v2float %49 None
-         %52 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %53 %52
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %65
-         %65 = OpLabel
-         %67 = OpPhi %uint %uint_0 %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_4
-               OpSelectionMerge %71 None
-               OpBranchConditional %69 %72 %71
-         %72 = OpLabel
-               OpBranch %66
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_0
+         %46 = OpLoad %v2float %44 None
+         %47 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_1
+         %49 = OpLoad %v2float %47 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat2v2float %46 %49
+               OpStore %52 %l_a_i_a_i_m
+         %54 = OpFunctionCall %int %i
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %33 UMin %55 %uint_1
+         %57 = OpAccessChain %_ptr_Function_v2float %52 %56
+%l_a_i_a_i_m_i = OpLoad %v2float %57 None
+         %60 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %61 %60
+               OpBranch %70
+         %70 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+         %75 = OpPhi %uint %uint_0 %70 %76 %72
+               OpLoopMerge %74 %72 None
+               OpBranch %71
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_Function_Outer %55 %67
-         %75 = OpAccessChain %_ptr_Function_Outer_std140 %53 %67
-         %77 = OpLoad %Outer_std140 %75 None
-         %78 = OpFunctionCall %Outer %tint_convert_Outer %77
-               OpStore %73 %78 None
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
-         %66 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %55 None
-         %81 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %81
-         %83 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %84 %83
-               OpBranch %89
-         %89 = OpLabel
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpPhi %uint %uint_0 %89 %95 %91
-               OpLoopMerge %93 %91 None
-               OpBranch %90
-         %90 = OpLabel
-         %96 = OpUGreaterThanEqual %bool %94 %uint_4
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
-               OpBranch %93
+         %77 = OpUGreaterThanEqual %bool %75 %uint_4
+               OpSelectionMerge %79 None
+               OpBranchConditional %77 %80 %79
+         %80 = OpLabel
+               OpBranch %74
+         %79 = OpLabel
+         %81 = OpAccessChain %_ptr_Function_Outer %63 %75
+         %83 = OpAccessChain %_ptr_Function_Outer_std140 %61 %75
+         %85 = OpLoad %Outer_std140 %83 None
+         %86 = OpFunctionCall %Outer %tint_convert_Outer %85
+               OpStore %81 %86 None
+               OpBranch %72
+         %72 = OpLabel
+         %76 = OpIAdd %uint %75 %uint_1
+               OpBranch %73
+         %74 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %63 None
+         %89 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %89
+         %91 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %92 %91
+               OpBranch %97
          %97 = OpLabel
-         %99 = OpAccessChain %_ptr_Function_Inner %86 %94
-        %101 = OpAccessChain %_ptr_Function_Inner_std140 %84 %94
-        %103 = OpLoad %Inner_std140 %101 None
-        %104 = OpFunctionCall %Inner %tint_convert_Inner %103
-               OpStore %99 %104 None
-               OpBranch %91
-         %91 = OpLabel
-         %95 = OpIAdd %uint %94 %uint_1
-               OpBranch %92
-         %93 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %86 None
-        %107 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %107
-        %109 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %109
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpPhi %uint %uint_0 %97 %103 %99
+               OpLoopMerge %101 %99 None
+               OpBranch %98
+         %98 = OpLabel
+        %104 = OpUGreaterThanEqual %bool %102 %uint_4
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
+               OpBranch %101
+        %105 = OpLabel
+        %107 = OpAccessChain %_ptr_Function_Inner %94 %102
+        %109 = OpAccessChain %_ptr_Function_Inner_std140 %92 %102
+        %111 = OpLoad %Inner_std140 %109 None
+        %112 = OpFunctionCall %Inner %tint_convert_Inner %111
+               OpStore %107 %112 None
+               OpBranch %99
+         %99 = OpLabel
+        %103 = OpIAdd %uint %102 %uint_1
+               OpBranch %100
+        %101 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %94 None
+        %115 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %115
+        %117 = OpFunctionCall %int %i
+        %118 = OpBitcast %uint %117
+        %119 = OpExtInst %uint %33 UMin %118 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %119
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %112
+%tint_convert_Inner = OpFunction %Inner None %122
  %tint_input = OpFunctionParameter %Inner_std140
-        %113 = OpLabel
-        %114 = OpCompositeExtract %v2float %tint_input 0
-        %115 = OpCompositeExtract %v2float %tint_input 1
-        %116 = OpCompositeConstruct %mat2v2float %114 %115
-        %117 = OpCompositeConstruct %Inner %116
-               OpReturnValue %117
+        %123 = OpLabel
+        %124 = OpCompositeExtract %v2float %tint_input 0
+        %125 = OpCompositeExtract %v2float %tint_input 1
+        %126 = OpCompositeConstruct %mat2v2float %124 %125
+        %127 = OpCompositeConstruct %Inner %126
+               OpReturnValue %127
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %119
+%tint_convert_Outer = OpFunction %Outer None %129
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %120 = OpLabel
-        %122 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %123 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
-        %121 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %122 %121
-               OpBranch %124
-        %124 = OpLabel
-               OpBranch %127
-        %127 = OpLabel
-        %129 = OpPhi %uint %uint_0 %124 %130 %126
-               OpLoopMerge %128 %126 None
-               OpBranch %125
-        %125 = OpLabel
-        %131 = OpUGreaterThanEqual %bool %129 %uint_4
-               OpSelectionMerge %132 None
-               OpBranchConditional %131 %133 %132
-        %133 = OpLabel
-               OpBranch %128
-        %132 = OpLabel
-        %134 = OpAccessChain %_ptr_Function_Inner %123 %129
-        %135 = OpAccessChain %_ptr_Function_Inner_std140 %122 %129
-        %136 = OpLoad %Inner_std140 %135 None
-        %137 = OpFunctionCall %Inner %tint_convert_Inner %136
-               OpStore %134 %137 None
-               OpBranch %126
-        %126 = OpLabel
-        %130 = OpIAdd %uint %129 %uint_1
-               OpBranch %127
-        %128 = OpLabel
-        %138 = OpLoad %_arr_Inner_uint_4 %123 None
-        %139 = OpCompositeConstruct %Outer %138
-               OpReturnValue %139
+        %130 = OpLabel
+        %132 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %133 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
+        %131 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %132 %131
+               OpBranch %134
+        %134 = OpLabel
+               OpBranch %137
+        %137 = OpLabel
+        %139 = OpPhi %uint %uint_0 %134 %140 %136
+               OpLoopMerge %138 %136 None
+               OpBranch %135
+        %135 = OpLabel
+        %141 = OpUGreaterThanEqual %bool %139 %uint_4
+               OpSelectionMerge %142 None
+               OpBranchConditional %141 %143 %142
+        %143 = OpLabel
+               OpBranch %138
+        %142 = OpLabel
+        %144 = OpAccessChain %_ptr_Function_Inner %133 %139
+        %145 = OpAccessChain %_ptr_Function_Inner_std140 %132 %139
+        %146 = OpLoad %Inner_std140 %145 None
+        %147 = OpFunctionCall %Inner %tint_convert_Inner %146
+               OpStore %144 %147 None
+               OpBranch %136
+        %136 = OpLabel
+        %140 = OpIAdd %uint %139 %uint_1
+               OpBranch %137
+        %138 = OpLabel
+        %148 = OpLoad %_arr_Inner_uint_4 %133 None
+        %149 = OpCompositeConstruct %Outer %148
+               OpReturnValue %149
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
index 4724648..745f13a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -58,7 +58,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2 v_4 = mat2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1);
+  mat2 v_4 = mat2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))))));
   {
@@ -77,8 +77,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))), Inner(mat2(vec2(0.0f), vec2(0.0f))));
   {
     uint v_11 = 0u;
@@ -96,8 +96,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat2 l_a_3_a_2_m = v_4;
-  vec2 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 92805a4..f67415a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float2x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float2x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
index 27bb1ff..be4634e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 124
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -62,11 +62,10 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
 %mat2v2float = OpTypeMatrix %v2float 2
@@ -76,135 +75,135 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %46 = OpConstantNull %_arr_Outer_uint_4
+         %45 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %73 = OpConstantNull %_arr_Inner_uint_4
+         %72 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %96 = OpTypeFunction %Inner %Inner_std140
-        %103 = OpTypeFunction %Outer %Outer_std140
+         %95 = OpTypeFunction %Inner %Inner_std140
+        %102 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %46
-         %69 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %71 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
+         %37 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %39 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %45
+         %68 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %70 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_0
-         %30 = OpLoad %v2float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_1
-         %33 = OpLoad %v2float %31 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat2v2float %30 %33
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_0
+         %29 = OpLoad %v2float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_1
+         %32 = OpLoad %v2float %30 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat2v2float %29 %32
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2float %l_a_3_a_2_m 1
-         %37 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %38 %37
-               OpBranch %47
-         %47 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-         %52 = OpPhi %uint %uint_0 %47 %53 %49
-               OpLoopMerge %51 %49 None
-               OpBranch %48
-         %48 = OpLabel
-         %54 = OpUGreaterThanEqual %bool %52 %uint_4
-               OpSelectionMerge %56 None
-               OpBranchConditional %54 %57 %56
-         %57 = OpLabel
-               OpBranch %51
-         %56 = OpLabel
-         %58 = OpAccessChain %_ptr_Function_Outer %40 %52
-         %60 = OpAccessChain %_ptr_Function_Outer_std140 %38 %52
-         %62 = OpLoad %Outer_std140 %60 None
-         %63 = OpFunctionCall %Outer %tint_convert_Outer %62
-               OpStore %58 %63 None
+         %36 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %37 %36
+               OpBranch %46
+         %46 = OpLabel
                OpBranch %49
          %49 = OpLabel
-         %53 = OpIAdd %uint %52 %uint_1
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
-         %51 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %40 None
-         %66 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %66
-         %68 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %69 %68
-               OpBranch %74
-         %74 = OpLabel
-               OpBranch %77
-         %77 = OpLabel
-         %79 = OpPhi %uint %uint_0 %74 %80 %76
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %81 = OpUGreaterThanEqual %bool %79 %uint_4
-               OpSelectionMerge %82 None
-               OpBranchConditional %81 %83 %82
-         %83 = OpLabel
-               OpBranch %78
-         %82 = OpLabel
-         %84 = OpAccessChain %_ptr_Function_Inner %71 %79
-         %86 = OpAccessChain %_ptr_Function_Inner_std140 %69 %79
-         %88 = OpLoad %Inner_std140 %86 None
-         %89 = OpFunctionCall %Inner %tint_convert_Inner %88
-               OpStore %84 %89 None
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_Outer %39 %51
+         %59 = OpAccessChain %_ptr_Function_Outer_std140 %37 %51
+         %61 = OpLoad %Outer_std140 %59 None
+         %62 = OpFunctionCall %Outer %tint_convert_Outer %61
+               OpStore %57 %62 None
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
+         %50 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %39 None
+         %65 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %65
+         %67 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %68 %67
+               OpBranch %73
+         %73 = OpLabel
                OpBranch %76
          %76 = OpLabel
-         %80 = OpIAdd %uint %79 %uint_1
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
+         %74 = OpLabel
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %81
+         %82 = OpLabel
                OpBranch %77
-         %78 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %71 None
-         %92 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %92
+         %81 = OpLabel
+         %83 = OpAccessChain %_ptr_Function_Inner %70 %78
+         %85 = OpAccessChain %_ptr_Function_Inner_std140 %68 %78
+         %87 = OpLoad %Inner_std140 %85 None
+         %88 = OpFunctionCall %Inner %tint_convert_Inner %87
+               OpStore %83 %88 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %70 None
+         %91 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %91
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %96
+%tint_convert_Inner = OpFunction %Inner None %95
  %tint_input = OpFunctionParameter %Inner_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %v2float %tint_input 0
-         %99 = OpCompositeExtract %v2float %tint_input 1
-        %100 = OpCompositeConstruct %mat2v2float %98 %99
-        %101 = OpCompositeConstruct %Inner %100
-               OpReturnValue %101
+         %96 = OpLabel
+         %97 = OpCompositeExtract %v2float %tint_input 0
+         %98 = OpCompositeExtract %v2float %tint_input 1
+         %99 = OpCompositeConstruct %mat2v2float %97 %98
+        %100 = OpCompositeConstruct %Inner %99
+               OpReturnValue %100
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %103
+%tint_convert_Outer = OpFunction %Outer None %102
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %104 = OpLabel
-        %106 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %107 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
-        %105 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %106 %105
-               OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_4
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_Inner %107 %113
-        %119 = OpAccessChain %_ptr_Function_Inner_std140 %106 %113
-        %120 = OpLoad %Inner_std140 %119 None
-        %121 = OpFunctionCall %Inner %tint_convert_Inner %120
-               OpStore %118 %121 None
+        %103 = OpLabel
+        %105 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %106 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
+        %104 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %105 %104
+               OpBranch %107
+        %107 = OpLabel
                OpBranch %110
         %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
+        %112 = OpPhi %uint %uint_0 %107 %113 %109
+               OpLoopMerge %111 %109 None
+               OpBranch %108
+        %108 = OpLabel
+        %114 = OpUGreaterThanEqual %bool %112 %uint_4
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %115
+        %116 = OpLabel
                OpBranch %111
-        %112 = OpLabel
-        %122 = OpLoad %_arr_Inner_uint_4 %107 None
-        %123 = OpCompositeConstruct %Outer %122
-               OpReturnValue %123
+        %115 = OpLabel
+        %117 = OpAccessChain %_ptr_Function_Inner %106 %112
+        %118 = OpAccessChain %_ptr_Function_Inner_std140 %105 %112
+        %119 = OpLoad %Inner_std140 %118 None
+        %120 = OpFunctionCall %Inner %tint_convert_Inner %119
+               OpStore %117 %120 None
+               OpBranch %109
+        %109 = OpLabel
+        %113 = OpIAdd %uint %112 %uint_1
+               OpBranch %110
+        %111 = OpLabel
+        %121 = OpLoad %_arr_Inner_uint_4 %106 None
+        %122 = OpCompositeConstruct %Outer %121
+               OpReturnValue %122
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.glsl
index 038f2ba2..436a7f3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.glsl
@@ -40,7 +40,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2 t = transpose(mat2(v.inner[2].m_col0, v.inner[2].m_col1));
-  float l = length(v.inner[0].m_col1.yx);
-  float a = abs(v.inner[0].m_col1.yx[0u]);
+  mat2 t = transpose(mat2(v.inner[2u].m_col0, v.inner[2u].m_col1));
+  float l = length(v.inner[0u].m_col1.yx);
+  float a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
index c0f5b1a..1fd602b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float2x2 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].yx);
-  float const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  float2x2 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.spvasm
index 3f08afd..82b0e76 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
-         %32 = OpExtInstImport "GLSL.std.450"
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -43,27 +43,25 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
 %mat2v2float = OpTypeMatrix %v2float 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2float %21 None
-         %25 = OpCompositeConstruct %mat2v2float %20 %23
-          %t = OpTranspose %mat2v2float %25
-         %27 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %29 = OpLoad %v2float %27 None
-         %30 = OpVectorShuffle %v2float %29 %29 1 0
-          %l = OpExtInst %float %32 Length %30
-         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v2float %33 None
-         %35 = OpVectorShuffle %v2float %34 %34 1 0
-         %36 = OpCompositeExtract %float %35 0
-          %a = OpExtInst %float %32 FAbs %36
+         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2float %21 None
+         %24 = OpCompositeConstruct %mat2v2float %20 %22
+          %t = OpTranspose %mat2v2float %24
+         %26 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %27 = OpLoad %v2float %26 None
+         %28 = OpVectorShuffle %v2float %27 %27 1 0
+          %l = OpExtInst %float %30 Length %28
+         %31 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v2float %31 None
+         %33 = OpVectorShuffle %v2float %32 %32 1 0
+         %34 = OpCompositeExtract %float %33 0
+          %a = OpExtInst %float %30 FAbs %34
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.glsl
index 6910b4a..a3411e3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.glsl
@@ -77,8 +77,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat2(v_1.inner[2].m_col0, v_1.inner[2].m_col1));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.ir.msl
index 7a210f2..58cb806 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.spvasm
index 4adb0eb..f566d6e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 101
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -77,11 +77,9 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
-      %int_0 = OpConstant %int 0
-         %93 = OpTypeFunction %S %S_std140
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
+         %91 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -140,35 +138,35 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2float %77 None
-         %80 = OpCompositeConstruct %mat2v2float %76 %79
-         %81 = OpFunctionCall %void %c %80
-         %82 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v2float %82 None
-         %85 = OpVectorShuffle %v2float %84 %84 1 0
-         %86 = OpFunctionCall %void %d %85
-         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v2float %87 None
-         %89 = OpVectorShuffle %v2float %88 %88 1 0
-         %90 = OpCompositeExtract %float %89 0
-         %91 = OpFunctionCall %void %e %90
+         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2float %77 None
+         %79 = OpCompositeConstruct %mat2v2float %76 %78
+         %80 = OpFunctionCall %void %c %79
+         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %82 = OpLoad %v2float %81 None
+         %83 = OpVectorShuffle %v2float %82 %82 1 0
+         %84 = OpFunctionCall %void %d %83
+         %85 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %86 = OpLoad %v2float %85 None
+         %87 = OpVectorShuffle %v2float %86 %86 1 0
+         %88 = OpCompositeExtract %float %87 0
+         %89 = OpFunctionCall %void %e %88
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %93
+%tint_convert_S = OpFunction %S None %91
  %tint_input = OpFunctionParameter %S_std140
-         %94 = OpLabel
-         %95 = OpCompositeExtract %int %tint_input 0
-         %96 = OpCompositeExtract %v2float %tint_input 1
-         %97 = OpCompositeExtract %v2float %tint_input 2
-         %98 = OpCompositeConstruct %mat2v2float %96 %97
-         %99 = OpCompositeExtract %int %tint_input 3
-        %100 = OpCompositeConstruct %S %95 %98 %99
-               OpReturnValue %100
+         %92 = OpLabel
+         %93 = OpCompositeExtract %int %tint_input 0
+         %94 = OpCompositeExtract %v2float %tint_input 1
+         %95 = OpCompositeExtract %v2float %tint_input 2
+         %96 = OpCompositeConstruct %mat2v2float %94 %95
+         %97 = OpCompositeExtract %int %tint_input 3
+         %98 = OpCompositeConstruct %S %93 %96 %97
+               OpReturnValue %98
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.glsl
index afd9eb0..4722e72 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.glsl
@@ -68,7 +68,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index ba60107..e980edf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -51,8 +51,8 @@
   S v_13[4] = v_8(0u);
   p = v_13;
   S v_14 = v_4(256u);
-  p[int(1)] = v_14;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_14;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index ba60107..e980edf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -51,8 +51,8 @@
   S v_13[4] = v_8(0u);
   p = v_13;
   S v_14 = v_4(256u);
-  p[int(1)] = v_14;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_14;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.msl
index be7d908..de9e0a2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.spvasm
index a4ea58f..b62b2e2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 82
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -65,16 +65,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v2float = OpTypePointer Private %mat2v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v2float = OpTypePointer Private %mat2v2float
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-      %int_0 = OpConstant %int 0
-         %74 = OpTypeFunction %S %S_std140
+         %71 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -108,33 +105,33 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat2v2float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2float %63 None
-         %66 = OpCompositeConstruct %mat2v2float %62 %65
-               OpStore %57 %66 None
-         %67 = OpAccessChain %_ptr_Private_v2float %p %int_1 %uint_1 %int_0
-         %70 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %71 = OpLoad %v2float %70 None
-         %72 = OpVectorShuffle %v2float %71 %71 1 0
-               OpStore %67 %72 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat2v2float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2float %62 None
+         %64 = OpCompositeConstruct %mat2v2float %61 %63
+               OpStore %56 %64 None
+         %65 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %68 = OpLoad %v2float %67 None
+         %69 = OpVectorShuffle %v2float %68 %68 1 0
+               OpStore %65 %69 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %74
+%tint_convert_S = OpFunction %S None %71
  %tint_input = OpFunctionParameter %S_std140
-         %75 = OpLabel
-         %76 = OpCompositeExtract %int %tint_input 0
-         %77 = OpCompositeExtract %v2float %tint_input 1
-         %78 = OpCompositeExtract %v2float %tint_input 2
-         %79 = OpCompositeConstruct %mat2v2float %77 %78
-         %80 = OpCompositeExtract %int %tint_input 3
-         %81 = OpCompositeConstruct %S %76 %79 %80
-               OpReturnValue %81
+         %72 = OpLabel
+         %73 = OpCompositeExtract %int %tint_input 0
+         %74 = OpCompositeExtract %v2float %tint_input 1
+         %75 = OpCompositeExtract %v2float %tint_input 2
+         %76 = OpCompositeConstruct %mat2v2float %74 %75
+         %77 = OpCompositeExtract %int %tint_input 3
+         %78 = OpCompositeConstruct %S %73 %76 %77
+               OpReturnValue %78
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.glsl
index 693f200..09adfff 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.glsl
@@ -119,8 +119,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.ir.msl
index e4e4e10..d47aeb9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.msl
index 8165cd0..d8cc8d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.spvasm
index 76c7b7f..2a033fd 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 118
+; Bound: 114
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -78,19 +78,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-      %int_0 = OpConstant %int 0
-         %80 = OpTypeFunction %void %_arr_S_uint_4
-         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %76 = OpTypeFunction %void %_arr_S_uint_4
+         %95 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %110 = OpTypeFunction %S %S_std140
+        %106 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -124,80 +121,79 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2float %69 None
-         %72 = OpCompositeConstruct %mat2v2float %68 %71
-               OpStore %63 %72 None
-         %73 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %int_1 %uint_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %77 = OpLoad %v2float %76 None
-         %78 = OpVectorShuffle %v2float %77 %77 1 0
-               OpStore %73 %78 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2float %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2float %67 None
+         %69 = OpCompositeConstruct %mat2v2float %66 %68
+               OpStore %61 %69 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %72 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %73 = OpLoad %v2float %72 None
+         %74 = OpVectorShuffle %v2float %73 %73 1 0
+               OpStore %70 %74 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %80
+%tint_store_and_preserve_padding = OpFunction %void None %76
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %81 = OpLabel
-         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %82 %value_param
+         %77 = OpLabel
+         %78 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %78 %value_param
+               OpBranch %79
+         %79 = OpLabel
+               OpBranch %82
+         %82 = OpLabel
+         %84 = OpPhi %uint %uint_0 %79 %85 %81
+               OpLoopMerge %83 %81 None
+               OpBranch %80
+         %80 = OpLabel
+         %86 = OpUGreaterThanEqual %bool %84 %uint_4
+               OpSelectionMerge %87 None
+               OpBranchConditional %86 %88 %87
+         %88 = OpLabel
                OpBranch %83
-         %83 = OpLabel
-               OpBranch %86
-         %86 = OpLabel
-         %88 = OpPhi %uint %uint_0 %83 %89 %85
-               OpLoopMerge %87 %85 None
-               OpBranch %84
-         %84 = OpLabel
-         %90 = OpUGreaterThanEqual %bool %88 %uint_4
-               OpSelectionMerge %91 None
-               OpBranchConditional %90 %92 %91
-         %92 = OpLabel
-               OpBranch %87
-         %91 = OpLabel
-         %93 = OpAccessChain %_ptr_Function_S %82 %88
-         %94 = OpLoad %S %93 None
-         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
-         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
-               OpBranch %85
-         %85 = OpLabel
-         %89 = OpIAdd %uint %88 %uint_1
-               OpBranch %86
          %87 = OpLabel
+         %89 = OpAccessChain %_ptr_Function_S %78 %84
+         %90 = OpLoad %S %89 None
+         %91 = OpCompositeConstruct %_arr_uint_uint_1 %84
+         %92 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %91 %90
+               OpBranch %81
+         %81 = OpLabel
+         %85 = OpIAdd %uint %84 %uint_1
+               OpBranch %82
+         %83 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %99
+%tint_store_and_preserve_padding_0 = OpFunction %void None %95
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %100 = OpLabel
-        %101 = OpCompositeExtract %uint %target_indices 0
-        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
-        %104 = OpCompositeExtract %int %value_param_0 0
-               OpStore %102 %104 None
-        %105 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %11 %uint_0 %101 %uint_1
-        %106 = OpCompositeExtract %mat2v2float %value_param_0 1
-               OpStore %105 %106 None
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
-        %108 = OpCompositeExtract %int %value_param_0 2
-               OpStore %107 %108 None
+         %96 = OpLabel
+         %97 = OpCompositeExtract %uint %target_indices 0
+         %98 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_0
+        %100 = OpCompositeExtract %int %value_param_0 0
+               OpStore %98 %100 None
+        %101 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %11 %uint_0 %97 %uint_1
+        %102 = OpCompositeExtract %mat2v2float %value_param_0 1
+               OpStore %101 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_2
+        %104 = OpCompositeExtract %int %value_param_0 2
+               OpStore %103 %104 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %110
+%tint_convert_S = OpFunction %S None %106
  %tint_input = OpFunctionParameter %S_std140
-        %111 = OpLabel
-        %112 = OpCompositeExtract %int %tint_input 0
-        %113 = OpCompositeExtract %v2float %tint_input 1
-        %114 = OpCompositeExtract %v2float %tint_input 2
-        %115 = OpCompositeConstruct %mat2v2float %113 %114
-        %116 = OpCompositeExtract %int %tint_input 3
-        %117 = OpCompositeConstruct %S %112 %115 %116
-               OpReturnValue %117
+        %107 = OpLabel
+        %108 = OpCompositeExtract %int %tint_input 0
+        %109 = OpCompositeExtract %v2float %tint_input 1
+        %110 = OpCompositeExtract %v2float %tint_input 2
+        %111 = OpCompositeConstruct %mat2v2float %109 %110
+        %112 = OpCompositeExtract %int %tint_input 3
+        %113 = OpCompositeConstruct %S %108 %111 %112
+               OpReturnValue %113
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.glsl
index d630c7a..03e84cb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.glsl
@@ -83,9 +83,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat2(v.inner[2].m_col0, v.inner[2].m_col1);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat2(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index b35fe76..225a876 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -71,9 +71,9 @@
   S v_16[4] = v_8(0u);
   w = v_16;
   S v_17 = v_4(256u);
-  w[int(1)] = v_17;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_17;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index b35fe76..225a876 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -71,9 +71,9 @@
   S v_16[4] = v_8(0u);
   w = v_16;
   S v_17 = v_4(256u);
-  w[int(1)] = v_17;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_17;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
index aae5830..6e93929 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.msl
index 4014fae..2f17b98 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
index f4fa9d7..ec15f46 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -74,16 +74,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v2float = OpTypePointer Workgroup %mat2v2float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
-         %91 = OpTypeFunction %void
-         %96 = OpTypeFunction %S %S_std140
+         %88 = OpTypeFunction %void
+         %93 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -140,39 +137,39 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat2v2float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %82 = OpLoad %v2float %81 None
-         %83 = OpCompositeConstruct %mat2v2float %80 %82
-               OpStore %75 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %uint_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v2float %87 None
-         %89 = OpVectorShuffle %v2float %88 %88 1 0
-               OpStore %84 %89 None
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat2v2float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2float %79 None
+         %81 = OpCompositeConstruct %mat2v2float %78 %80
+               OpStore %73 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_1 %uint_0
+         %84 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v2float %84 None
+         %86 = OpVectorShuffle %v2float %85 %85 1 0
+               OpStore %82 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %88
+         %89 = OpLabel
+         %90 = OpLoad %uint %f_local_invocation_index_Input None
+         %91 = OpFunctionCall %void %f_inner %90
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %93
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v2float %tint_input 1
-        %100 = OpCompositeExtract %v2float %tint_input 2
-        %101 = OpCompositeConstruct %mat2v2float %99 %100
-        %102 = OpCompositeExtract %int %tint_input 3
-        %103 = OpCompositeConstruct %S %98 %101 %102
-               OpReturnValue %103
+         %94 = OpLabel
+         %95 = OpCompositeExtract %int %tint_input 0
+         %96 = OpCompositeExtract %v2float %tint_input 1
+         %97 = OpCompositeExtract %v2float %tint_input 2
+         %98 = OpCompositeConstruct %mat2v2float %96 %97
+         %99 = OpCompositeExtract %int %tint_input 3
+        %100 = OpCompositeConstruct %S %95 %98 %99
+               OpReturnValue %100
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 816de20..f3effa3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -67,11 +67,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 2, 3> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 2, 3> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   uint4 ubo_load_5 = a[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
@@ -81,7 +81,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 1u))) + (2u * min(uint(tint_symbol_3), 2u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 20343da..02d1955 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -64,10 +64,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat2x3 v_6 = f16mat2x3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1);
-  f16vec3 v_7 = v_6[i()];
+  f16vec3 v_7 = v_6[min(uint(i()), 1u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -108,5 +108,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat2x3 l_a_i_a_i_m = v_6;
   f16vec3 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 61e9f7e..219aae1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -94,9 +94,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_23 = (256u * uint(i()));
-  uint v_24 = (64u * uint(i()));
-  uint v_25 = (8u * uint(i()));
+  uint v_23 = (256u * uint(min(uint(i()), 3u)));
+  uint v_24 = (64u * uint(min(uint(i()), 3u)));
+  uint v_25 = (8u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_18(0u);
   Outer l_a_i = v_15(v_23);
   Inner l_a_i_a[4] = v_10(v_23);
@@ -104,7 +104,7 @@
   matrix<float16_t, 2, 3> l_a_i_a_i_m = v_4((v_23 + v_24));
   uint4 v_26 = a[(((v_23 + v_24) + v_25) / 16u)];
   vector<float16_t, 3> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_23 + v_24) + v_25) % 16u) / 4u) == 2u)) ? (v_26.zw) : (v_26.xy))).xyz;
-  uint v_27 = (((v_23 + v_24) + v_25) + (uint(i()) * 2u));
+  uint v_27 = (((v_23 + v_24) + v_25) + (uint(min(uint(i()), 2u)) * 2u));
   uint v_28 = a[(v_27 / 16u)][((v_27 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_28 >> ((((v_27 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 7c9dd83..9634fe4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -73,11 +73,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -86,5 +86,5 @@
   half3 const v_9 = half3(v_8[0u].packed);
   half2x3 const l_a_i_a_i_m = half2x3(v_9, half3(v_8[1u].packed));
   half3 const l_a_i_a_i_m_i = half3((*p_a_i_a_i_m_i));
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 49c0c0b..be3cf46 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -76,11 +76,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -88,7 +88,7 @@
   half2x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   half3 const l_a_i_a_i_m_i = half3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 688c479..7661627 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 140
+; Bound: 151
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,6 +73,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -86,17 +88,18 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %61 = OpConstantNull %_arr_Outer_uint_4
+         %69 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %88 = OpConstantNull %_arr_Inner_uint_4
+         %96 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %112 = OpTypeFunction %Inner %Inner_std140
-        %119 = OpTypeFunction %Outer %Outer_std140
+     %uint_2 = OpConstant %uint 2
+        %123 = OpTypeFunction %Inner %Inner_std140
+        %130 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -107,129 +110,137 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat2v3half Function
-         %53 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %61
-         %84 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %86 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
+         %52 = OpVariable %_ptr_Function_mat2v3half Function
+         %61 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %63 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %69
+         %92 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %94 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_0
-         %40 = OpLoad %v3half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_1
-         %43 = OpLoad %v3half %41 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat2v3half %40 %43
-               OpStore %46 %l_a_i_a_i_m
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v3half %46 %48
-%l_a_i_a_i_m_i = OpLoad %v3half %49 None
-         %52 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %53 %52
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %65
-         %65 = OpLabel
-         %67 = OpPhi %uint %uint_0 %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_4
-               OpSelectionMerge %71 None
-               OpBranchConditional %69 %72 %71
-         %72 = OpLabel
-               OpBranch %66
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_0
+         %46 = OpLoad %v3half %44 None
+         %47 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_1
+         %49 = OpLoad %v3half %47 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat2v3half %46 %49
+               OpStore %52 %l_a_i_a_i_m
+         %54 = OpFunctionCall %int %i
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %33 UMin %55 %uint_1
+         %57 = OpAccessChain %_ptr_Function_v3half %52 %56
+%l_a_i_a_i_m_i = OpLoad %v3half %57 None
+         %60 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %61 %60
+               OpBranch %70
+         %70 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+         %75 = OpPhi %uint %uint_0 %70 %76 %72
+               OpLoopMerge %74 %72 None
+               OpBranch %71
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_Function_Outer %55 %67
-         %75 = OpAccessChain %_ptr_Function_Outer_std140 %53 %67
-         %77 = OpLoad %Outer_std140 %75 None
-         %78 = OpFunctionCall %Outer %tint_convert_Outer %77
-               OpStore %73 %78 None
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
-         %66 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %55 None
-         %81 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %81
-         %83 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %84 %83
-               OpBranch %89
-         %89 = OpLabel
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpPhi %uint %uint_0 %89 %95 %91
-               OpLoopMerge %93 %91 None
-               OpBranch %90
-         %90 = OpLabel
-         %96 = OpUGreaterThanEqual %bool %94 %uint_4
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
-               OpBranch %93
+         %77 = OpUGreaterThanEqual %bool %75 %uint_4
+               OpSelectionMerge %79 None
+               OpBranchConditional %77 %80 %79
+         %80 = OpLabel
+               OpBranch %74
+         %79 = OpLabel
+         %81 = OpAccessChain %_ptr_Function_Outer %63 %75
+         %83 = OpAccessChain %_ptr_Function_Outer_std140 %61 %75
+         %85 = OpLoad %Outer_std140 %83 None
+         %86 = OpFunctionCall %Outer %tint_convert_Outer %85
+               OpStore %81 %86 None
+               OpBranch %72
+         %72 = OpLabel
+         %76 = OpIAdd %uint %75 %uint_1
+               OpBranch %73
+         %74 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %63 None
+         %89 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %89
+         %91 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %92 %91
+               OpBranch %97
          %97 = OpLabel
-         %99 = OpAccessChain %_ptr_Function_Inner %86 %94
-        %101 = OpAccessChain %_ptr_Function_Inner_std140 %84 %94
-        %103 = OpLoad %Inner_std140 %101 None
-        %104 = OpFunctionCall %Inner %tint_convert_Inner %103
-               OpStore %99 %104 None
-               OpBranch %91
-         %91 = OpLabel
-         %95 = OpIAdd %uint %94 %uint_1
-               OpBranch %92
-         %93 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %86 None
-        %107 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %107
-        %109 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %109
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpPhi %uint %uint_0 %97 %103 %99
+               OpLoopMerge %101 %99 None
+               OpBranch %98
+         %98 = OpLabel
+        %104 = OpUGreaterThanEqual %bool %102 %uint_4
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
+               OpBranch %101
+        %105 = OpLabel
+        %107 = OpAccessChain %_ptr_Function_Inner %94 %102
+        %109 = OpAccessChain %_ptr_Function_Inner_std140 %92 %102
+        %111 = OpLoad %Inner_std140 %109 None
+        %112 = OpFunctionCall %Inner %tint_convert_Inner %111
+               OpStore %107 %112 None
+               OpBranch %99
+         %99 = OpLabel
+        %103 = OpIAdd %uint %102 %uint_1
+               OpBranch %100
+        %101 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %94 None
+        %115 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %115
+        %117 = OpFunctionCall %int %i
+        %118 = OpBitcast %uint %117
+        %119 = OpExtInst %uint %33 UMin %118 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %119
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %112
+%tint_convert_Inner = OpFunction %Inner None %123
  %tint_input = OpFunctionParameter %Inner_std140
-        %113 = OpLabel
-        %114 = OpCompositeExtract %v3half %tint_input 0
-        %115 = OpCompositeExtract %v3half %tint_input 1
-        %116 = OpCompositeConstruct %mat2v3half %114 %115
-        %117 = OpCompositeConstruct %Inner %116
-               OpReturnValue %117
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %119
-%tint_input_0 = OpFunctionParameter %Outer_std140
-        %120 = OpLabel
-        %122 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %123 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
-        %121 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %122 %121
-               OpBranch %124
         %124 = OpLabel
-               OpBranch %127
-        %127 = OpLabel
-        %129 = OpPhi %uint %uint_0 %124 %130 %126
-               OpLoopMerge %128 %126 None
-               OpBranch %125
-        %125 = OpLabel
-        %131 = OpUGreaterThanEqual %bool %129 %uint_4
-               OpSelectionMerge %132 None
-               OpBranchConditional %131 %133 %132
-        %133 = OpLabel
-               OpBranch %128
-        %132 = OpLabel
-        %134 = OpAccessChain %_ptr_Function_Inner %123 %129
-        %135 = OpAccessChain %_ptr_Function_Inner_std140 %122 %129
-        %136 = OpLoad %Inner_std140 %135 None
-        %137 = OpFunctionCall %Inner %tint_convert_Inner %136
-               OpStore %134 %137 None
-               OpBranch %126
-        %126 = OpLabel
-        %130 = OpIAdd %uint %129 %uint_1
-               OpBranch %127
-        %128 = OpLabel
-        %138 = OpLoad %_arr_Inner_uint_4 %123 None
-        %139 = OpCompositeConstruct %Outer %138
-               OpReturnValue %139
+        %125 = OpCompositeExtract %v3half %tint_input 0
+        %126 = OpCompositeExtract %v3half %tint_input 1
+        %127 = OpCompositeConstruct %mat2v3half %125 %126
+        %128 = OpCompositeConstruct %Inner %127
+               OpReturnValue %128
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %130
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %131 = OpLabel
+        %133 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %134 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
+        %132 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %133 %132
+               OpBranch %135
+        %135 = OpLabel
+               OpBranch %138
+        %138 = OpLabel
+        %140 = OpPhi %uint %uint_0 %135 %141 %137
+               OpLoopMerge %139 %137 None
+               OpBranch %136
+        %136 = OpLabel
+        %142 = OpUGreaterThanEqual %bool %140 %uint_4
+               OpSelectionMerge %143 None
+               OpBranchConditional %142 %144 %143
+        %144 = OpLabel
+               OpBranch %139
+        %143 = OpLabel
+        %145 = OpAccessChain %_ptr_Function_Inner %134 %140
+        %146 = OpAccessChain %_ptr_Function_Inner_std140 %133 %140
+        %147 = OpLoad %Inner_std140 %146 None
+        %148 = OpFunctionCall %Inner %tint_convert_Inner %147
+               OpStore %145 %148 None
+               OpBranch %137
+        %137 = OpLabel
+        %141 = OpIAdd %uint %140 %uint_1
+               OpBranch %138
+        %139 = OpLabel
+        %149 = OpLoad %_arr_Inner_uint_4 %134 None
+        %150 = OpCompositeConstruct %Outer %149
+               OpReturnValue %150
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
index 142ed42..7023733 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -59,7 +59,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x3 v_4 = f16mat2x3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1);
+  f16mat2x3 v_4 = f16mat2x3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -78,8 +78,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat2x3(f16vec3(0.0hf), f16vec3(0.0hf))));
   {
     uint v_11 = 0u;
@@ -97,8 +97,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat2x3 l_a_3_a_2_m = v_4;
-  f16vec3 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 419b975..22ec781 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -66,11 +66,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -79,5 +79,5 @@
   half3 const v_9 = half3(v_8[0u].packed);
   half2x3 const l_a_3_a_2_m = half2x3(v_9, half3(v_8[1u].packed));
   half3 const l_a_3_a_2_m_1 = half3((*p_a_3_a_2_m_1));
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
index c353b82..219ef79 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 124
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,11 +65,10 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
  %mat2v3half = OpTypeMatrix %v3half 2
@@ -79,135 +78,135 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %46 = OpConstantNull %_arr_Outer_uint_4
+         %45 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %73 = OpConstantNull %_arr_Inner_uint_4
+         %72 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %96 = OpTypeFunction %Inner %Inner_std140
-        %103 = OpTypeFunction %Outer %Outer_std140
+         %95 = OpTypeFunction %Inner %Inner_std140
+        %102 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %46
-         %69 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %71 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
+         %37 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %39 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %45
+         %68 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %70 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_0
-         %30 = OpLoad %v3half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_1
-         %33 = OpLoad %v3half %31 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat2v3half %30 %33
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_0
+         %29 = OpLoad %v3half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_1
+         %32 = OpLoad %v3half %30 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat2v3half %29 %32
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3half %l_a_3_a_2_m 1
-         %37 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %38 %37
-               OpBranch %47
-         %47 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-         %52 = OpPhi %uint %uint_0 %47 %53 %49
-               OpLoopMerge %51 %49 None
-               OpBranch %48
-         %48 = OpLabel
-         %54 = OpUGreaterThanEqual %bool %52 %uint_4
-               OpSelectionMerge %56 None
-               OpBranchConditional %54 %57 %56
-         %57 = OpLabel
-               OpBranch %51
-         %56 = OpLabel
-         %58 = OpAccessChain %_ptr_Function_Outer %40 %52
-         %60 = OpAccessChain %_ptr_Function_Outer_std140 %38 %52
-         %62 = OpLoad %Outer_std140 %60 None
-         %63 = OpFunctionCall %Outer %tint_convert_Outer %62
-               OpStore %58 %63 None
+         %36 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %37 %36
+               OpBranch %46
+         %46 = OpLabel
                OpBranch %49
          %49 = OpLabel
-         %53 = OpIAdd %uint %52 %uint_1
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
-         %51 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %40 None
-         %66 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %66
-         %68 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %69 %68
-               OpBranch %74
-         %74 = OpLabel
-               OpBranch %77
-         %77 = OpLabel
-         %79 = OpPhi %uint %uint_0 %74 %80 %76
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %81 = OpUGreaterThanEqual %bool %79 %uint_4
-               OpSelectionMerge %82 None
-               OpBranchConditional %81 %83 %82
-         %83 = OpLabel
-               OpBranch %78
-         %82 = OpLabel
-         %84 = OpAccessChain %_ptr_Function_Inner %71 %79
-         %86 = OpAccessChain %_ptr_Function_Inner_std140 %69 %79
-         %88 = OpLoad %Inner_std140 %86 None
-         %89 = OpFunctionCall %Inner %tint_convert_Inner %88
-               OpStore %84 %89 None
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_Outer %39 %51
+         %59 = OpAccessChain %_ptr_Function_Outer_std140 %37 %51
+         %61 = OpLoad %Outer_std140 %59 None
+         %62 = OpFunctionCall %Outer %tint_convert_Outer %61
+               OpStore %57 %62 None
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
+         %50 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %39 None
+         %65 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %65
+         %67 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %68 %67
+               OpBranch %73
+         %73 = OpLabel
                OpBranch %76
          %76 = OpLabel
-         %80 = OpIAdd %uint %79 %uint_1
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
+         %74 = OpLabel
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %81
+         %82 = OpLabel
                OpBranch %77
-         %78 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %71 None
-         %92 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %92
+         %81 = OpLabel
+         %83 = OpAccessChain %_ptr_Function_Inner %70 %78
+         %85 = OpAccessChain %_ptr_Function_Inner_std140 %68 %78
+         %87 = OpLoad %Inner_std140 %85 None
+         %88 = OpFunctionCall %Inner %tint_convert_Inner %87
+               OpStore %83 %88 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %70 None
+         %91 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %91
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %96
+%tint_convert_Inner = OpFunction %Inner None %95
  %tint_input = OpFunctionParameter %Inner_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %v3half %tint_input 0
-         %99 = OpCompositeExtract %v3half %tint_input 1
-        %100 = OpCompositeConstruct %mat2v3half %98 %99
-        %101 = OpCompositeConstruct %Inner %100
-               OpReturnValue %101
+         %96 = OpLabel
+         %97 = OpCompositeExtract %v3half %tint_input 0
+         %98 = OpCompositeExtract %v3half %tint_input 1
+         %99 = OpCompositeConstruct %mat2v3half %97 %98
+        %100 = OpCompositeConstruct %Inner %99
+               OpReturnValue %100
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %103
+%tint_convert_Outer = OpFunction %Outer None %102
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %104 = OpLabel
-        %106 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %107 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
-        %105 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %106 %105
-               OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_4
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_Inner %107 %113
-        %119 = OpAccessChain %_ptr_Function_Inner_std140 %106 %113
-        %120 = OpLoad %Inner_std140 %119 None
-        %121 = OpFunctionCall %Inner %tint_convert_Inner %120
-               OpStore %118 %121 None
+        %103 = OpLabel
+        %105 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %106 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
+        %104 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %105 %104
+               OpBranch %107
+        %107 = OpLabel
                OpBranch %110
         %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
+        %112 = OpPhi %uint %uint_0 %107 %113 %109
+               OpLoopMerge %111 %109 None
+               OpBranch %108
+        %108 = OpLabel
+        %114 = OpUGreaterThanEqual %bool %112 %uint_4
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %115
+        %116 = OpLabel
                OpBranch %111
-        %112 = OpLabel
-        %122 = OpLoad %_arr_Inner_uint_4 %107 None
-        %123 = OpCompositeConstruct %Outer %122
-               OpReturnValue %123
+        %115 = OpLabel
+        %117 = OpAccessChain %_ptr_Function_Inner %106 %112
+        %118 = OpAccessChain %_ptr_Function_Inner_std140 %105 %112
+        %119 = OpLoad %Inner_std140 %118 None
+        %120 = OpFunctionCall %Inner %tint_convert_Inner %119
+               OpStore %117 %120 None
+               OpBranch %109
+        %109 = OpLabel
+        %113 = OpIAdd %uint %112 %uint_1
+               OpBranch %110
+        %111 = OpLabel
+        %121 = OpLoad %_arr_Inner_uint_4 %106 None
+        %122 = OpCompositeConstruct %Outer %121
+               OpReturnValue %122
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.glsl
index 7e0f999..59c9177 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.glsl
@@ -41,7 +41,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x2 t = transpose(f16mat2x3(v.inner[2].m_col0, v.inner[2].m_col1));
-  float16_t l = length(v.inner[0].m_col1.zxy);
-  float16_t a = abs(v.inner[0].m_col1.zxy[0u]);
+  f16mat3x2 t = transpose(f16mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1));
+  float16_t l = length(v.inner[0u].m_col1.zxy);
+  float16_t a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
index ff3fda9..d227c60 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -33,9 +33,9 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u)[2u].m;
   half3 const v_1 = half3(v[0u].packed);
   half3x2 const t = transpose(half2x3(v_1, half3(v[1u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  half const a = abs(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  half const a = abs(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.spvasm
index 06e91a8..7b0b5e0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %34 = OpExtInstImport "GLSL.std.450"
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -46,29 +46,27 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
  %mat2v3half = OpTypeMatrix %v3half 2
      %v2half = OpTypeVector %half 2
  %mat3v2half = OpTypeMatrix %v2half 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3half %21 None
-         %25 = OpCompositeConstruct %mat2v3half %20 %23
-          %t = OpTranspose %mat3v2half %25
-         %29 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %31 = OpLoad %v3half %29 None
-         %32 = OpVectorShuffle %v3half %31 %31 2 0 1
-          %l = OpExtInst %half %34 Length %32
-         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v3half %35 None
-         %37 = OpVectorShuffle %v3half %36 %36 2 0 1
-         %38 = OpCompositeExtract %half %37 0
-          %a = OpExtInst %half %34 FAbs %38
+         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3half %21 None
+         %24 = OpCompositeConstruct %mat2v3half %20 %22
+          %t = OpTranspose %mat3v2half %24
+         %28 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %29 = OpLoad %v3half %28 None
+         %30 = OpVectorShuffle %v3half %29 %29 2 0 1
+          %l = OpExtInst %half %32 Length %30
+         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v3half %33 None
+         %35 = OpVectorShuffle %v3half %34 %34 2 0 1
+         %36 = OpCompositeExtract %half %35 0
+          %a = OpExtInst %half %32 FAbs %36
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.glsl
index 4b9d0cd..f664622 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.glsl
@@ -78,8 +78,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat2x3(v_1.inner[2].m_col0, v_1.inner[2].m_col1));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat2x3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.ir.msl
index 7927c78..3e642de 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.ir.msl
@@ -70,10 +70,10 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_8 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_8 = (*tint_module_vars.u)[2u].m;
   half3 const v_9 = half3(v_8[0u].packed);
   c(half2x3(v_9, half3(v_8[1u].packed)));
-  d(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.spvasm
index 5dceebb..129f128 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 101
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -80,11 +80,9 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
-      %int_0 = OpConstant %int 0
-         %93 = OpTypeFunction %S %S_std140
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
+         %91 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -143,35 +141,35 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3half %77 None
-         %80 = OpCompositeConstruct %mat2v3half %76 %79
-         %81 = OpFunctionCall %void %c %80
-         %82 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v3half %82 None
-         %85 = OpVectorShuffle %v3half %84 %84 2 0 1
-         %86 = OpFunctionCall %void %d %85
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v3half %87 None
-         %89 = OpVectorShuffle %v3half %88 %88 2 0 1
-         %90 = OpCompositeExtract %half %89 0
-         %91 = OpFunctionCall %void %e %90
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3half %77 None
+         %79 = OpCompositeConstruct %mat2v3half %76 %78
+         %80 = OpFunctionCall %void %c %79
+         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %82 = OpLoad %v3half %81 None
+         %83 = OpVectorShuffle %v3half %82 %82 2 0 1
+         %84 = OpFunctionCall %void %d %83
+         %85 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %86 = OpLoad %v3half %85 None
+         %87 = OpVectorShuffle %v3half %86 %86 2 0 1
+         %88 = OpCompositeExtract %half %87 0
+         %89 = OpFunctionCall %void %e %88
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %93
+%tint_convert_S = OpFunction %S None %91
  %tint_input = OpFunctionParameter %S_std140
-         %94 = OpLabel
-         %95 = OpCompositeExtract %int %tint_input 0
-         %96 = OpCompositeExtract %v3half %tint_input 1
-         %97 = OpCompositeExtract %v3half %tint_input 2
-         %98 = OpCompositeConstruct %mat2v3half %96 %97
-         %99 = OpCompositeExtract %int %tint_input 3
-        %100 = OpCompositeConstruct %S %95 %98 %99
-               OpReturnValue %100
+         %92 = OpLabel
+         %93 = OpCompositeExtract %int %tint_input 0
+         %94 = OpCompositeExtract %v3half %tint_input 1
+         %95 = OpCompositeExtract %v3half %tint_input 2
+         %96 = OpCompositeConstruct %mat2v3half %94 %95
+         %97 = OpCompositeExtract %int %tint_input 3
+         %98 = OpCompositeConstruct %S %93 %96 %97
+               OpReturnValue %98
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.glsl
index b22b5f1..86c5d22 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.glsl
@@ -69,7 +69,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 7550160..2fa551f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -63,8 +63,8 @@
   S v_17[4] = v_12(0u);
   p = v_17;
   S v_18 = v_8(256u);
-  p[int(1)] = v_18;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  p[1u] = v_18;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.msl
index 5f4f483..1970847 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.ir.msl
@@ -57,9 +57,9 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_7 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_7 = (*tint_module_vars.u)[2u].m;
   half3 const v_8 = half3(v_7[0u].packed);
-  (*tint_module_vars.p)[3].m = half2x3(v_8, half3(v_7[1u].packed));
-  (*tint_module_vars.p)[1].m[0] = half3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = half2x3(v_8, half3(v_7[1u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = half3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.spvasm
index c7b5c88..d68df42 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 82
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -68,16 +68,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v3half = OpTypePointer Private %mat2v3half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v3half = OpTypePointer Private %mat2v3half
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-      %int_0 = OpConstant %int 0
-         %74 = OpTypeFunction %S %S_std140
+         %71 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -111,33 +108,33 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat2v3half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3half %63 None
-         %66 = OpCompositeConstruct %mat2v3half %62 %65
-               OpStore %57 %66 None
-         %67 = OpAccessChain %_ptr_Private_v3half %p %int_1 %uint_1 %int_0
-         %70 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %71 = OpLoad %v3half %70 None
-         %72 = OpVectorShuffle %v3half %71 %71 2 0 1
-               OpStore %67 %72 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat2v3half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3half %62 None
+         %64 = OpCompositeConstruct %mat2v3half %61 %63
+               OpStore %56 %64 None
+         %65 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %68 = OpLoad %v3half %67 None
+         %69 = OpVectorShuffle %v3half %68 %68 2 0 1
+               OpStore %65 %69 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %74
+%tint_convert_S = OpFunction %S None %71
  %tint_input = OpFunctionParameter %S_std140
-         %75 = OpLabel
-         %76 = OpCompositeExtract %int %tint_input 0
-         %77 = OpCompositeExtract %v3half %tint_input 1
-         %78 = OpCompositeExtract %v3half %tint_input 2
-         %79 = OpCompositeConstruct %mat2v3half %77 %78
-         %80 = OpCompositeExtract %int %tint_input 3
-         %81 = OpCompositeConstruct %S %76 %79 %80
-               OpReturnValue %81
+         %72 = OpLabel
+         %73 = OpCompositeExtract %int %tint_input 0
+         %74 = OpCompositeExtract %v3half %tint_input 1
+         %75 = OpCompositeExtract %v3half %tint_input 2
+         %76 = OpCompositeConstruct %mat2v3half %74 %75
+         %77 = OpCompositeExtract %int %tint_input 3
+         %78 = OpCompositeConstruct %S %73 %76 %77
+               OpReturnValue %78
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
index 5c13b72..6911b00 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -124,9 +124,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  f16mat2x3 v_9 = f16mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  f16mat2x3 v_9 = f16mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.ir.msl
index 269e006..1e66f4e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.ir.msl
@@ -33,6 +33,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -62,6 +65,7 @@
     uint v_4 = 0u;
     v_4 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_5 = v_4;
       if ((v_5 >= 4u)) {
         break;
@@ -85,9 +89,9 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_9 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_9 = (*tint_module_vars.u)[2u].m;
   half3 const v_10 = half3(v_9[0u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), half2x3(v_10, half3(v_9[1u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), half2x3(v_10, half3(v_9[1u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
index a3b5b98..f05277c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -65,7 +68,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
index 01497108..8941fe0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 130
+; Bound: 125
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -84,19 +84,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_2 = OpConstant %uint 2
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-      %int_0 = OpConstant %int 0
-         %82 = OpTypeFunction %void %_arr_S_uint_4
-        %101 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %77 = OpTypeFunction %void %_arr_S_uint_4
+         %96 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %114 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
-        %122 = OpTypeFunction %S %S_std140
+        %109 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3half
+        %117 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -130,94 +127,92 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %68 = OpLoad %v3half %66 None
-         %69 = OpCompositeConstruct %mat2v3half %65 %68
-         %70 = OpBitcast %uint %int_3
-         %72 = OpCompositeConstruct %_arr_uint_uint_1 %70
-         %73 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %72 %69
-         %75 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %int_1 %uint_1 %int_0
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %79 = OpLoad %v3half %78 None
-         %80 = OpVectorShuffle %v3half %79 %79 2 0 1
-               OpStore %75 %80 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3half %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3half %64 None
+         %66 = OpCompositeConstruct %mat2v3half %63 %65
+         %67 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %69 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %67 %66
+         %71 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %74 = OpLoad %v3half %73 None
+         %75 = OpVectorShuffle %v3half %74 %74 2 0 1
+               OpStore %71 %75 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %82
+%tint_store_and_preserve_padding = OpFunction %void None %77
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %78 = OpLabel
+         %79 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %79 %value_param
+               OpBranch %80
+         %80 = OpLabel
+               OpBranch %83
          %83 = OpLabel
-         %84 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %84 %value_param
-               OpBranch %85
-         %85 = OpLabel
-               OpBranch %88
-         %88 = OpLabel
-         %90 = OpPhi %uint %uint_0 %85 %91 %87
-               OpLoopMerge %89 %87 None
-               OpBranch %86
-         %86 = OpLabel
-         %92 = OpUGreaterThanEqual %bool %90 %uint_4
-               OpSelectionMerge %93 None
-               OpBranchConditional %92 %94 %93
-         %94 = OpLabel
-               OpBranch %89
-         %93 = OpLabel
-         %95 = OpAccessChain %_ptr_Function_S %84 %90
-         %96 = OpLoad %S %95 None
-         %97 = OpCompositeConstruct %_arr_uint_uint_1 %90
-         %98 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %97 %96
-               OpBranch %87
-         %87 = OpLabel
-         %91 = OpIAdd %uint %90 %uint_1
-               OpBranch %88
+         %85 = OpPhi %uint %uint_0 %80 %86 %82
+               OpLoopMerge %84 %82 None
+               OpBranch %81
+         %81 = OpLabel
+         %87 = OpUGreaterThanEqual %bool %85 %uint_4
+               OpSelectionMerge %88 None
+               OpBranchConditional %87 %89 %88
          %89 = OpLabel
+               OpBranch %84
+         %88 = OpLabel
+         %90 = OpAccessChain %_ptr_Function_S %79 %85
+         %91 = OpLoad %S %90 None
+         %92 = OpCompositeConstruct %_arr_uint_uint_1 %85
+         %93 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %92 %91
+               OpBranch %82
+         %82 = OpLabel
+         %86 = OpIAdd %uint %85 %uint_1
+               OpBranch %83
+         %84 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %101
+%tint_store_and_preserve_padding_0 = OpFunction %void None %96
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %102 = OpLabel
-        %103 = OpCompositeExtract %uint %target_indices 0
-        %104 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %103 %uint_0
-        %106 = OpCompositeExtract %int %value_param_0 0
-               OpStore %104 %106 None
-        %107 = OpCompositeExtract %mat2v3half %value_param_0 1
-        %108 = OpCompositeConstruct %_arr_uint_uint_1 %103
-        %109 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %108 %107
-        %110 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %103 %uint_2
-        %111 = OpCompositeExtract %int %value_param_0 2
-               OpStore %110 %111 None
+         %97 = OpLabel
+         %98 = OpCompositeExtract %uint %target_indices 0
+         %99 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %98 %uint_0
+        %101 = OpCompositeExtract %int %value_param_0 0
+               OpStore %99 %101 None
+        %102 = OpCompositeExtract %mat2v3half %value_param_0 1
+        %103 = OpCompositeConstruct %_arr_uint_uint_1 %98
+        %104 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %103 %102
+        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %98 %uint_2
+        %106 = OpCompositeExtract %int %value_param_0 2
+               OpStore %105 %106 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %114
+%tint_store_and_preserve_padding_1 = OpFunction %void None %109
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat2v3half
-        %115 = OpLabel
-        %116 = OpCompositeExtract %uint %target_indices_0 0
-        %117 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %116 %uint_1 %uint_0
-        %118 = OpCompositeExtract %v3half %value_param_1 0
-               OpStore %117 %118 None
-        %119 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %116 %uint_1 %uint_1
-        %120 = OpCompositeExtract %v3half %value_param_1 1
-               OpStore %119 %120 None
+        %110 = OpLabel
+        %111 = OpCompositeExtract %uint %target_indices_0 0
+        %112 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %111 %uint_1 %uint_0
+        %113 = OpCompositeExtract %v3half %value_param_1 0
+               OpStore %112 %113 None
+        %114 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %111 %uint_1 %uint_1
+        %115 = OpCompositeExtract %v3half %value_param_1 1
+               OpStore %114 %115 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %122
+%tint_convert_S = OpFunction %S None %117
  %tint_input = OpFunctionParameter %S_std140
-        %123 = OpLabel
-        %124 = OpCompositeExtract %int %tint_input 0
-        %125 = OpCompositeExtract %v3half %tint_input 1
-        %126 = OpCompositeExtract %v3half %tint_input 2
-        %127 = OpCompositeConstruct %mat2v3half %125 %126
-        %128 = OpCompositeExtract %int %tint_input 3
-        %129 = OpCompositeConstruct %S %124 %127 %128
-               OpReturnValue %129
+        %118 = OpLabel
+        %119 = OpCompositeExtract %int %tint_input 0
+        %120 = OpCompositeExtract %v3half %tint_input 1
+        %121 = OpCompositeExtract %v3half %tint_input 2
+        %122 = OpCompositeConstruct %mat2v3half %120 %121
+        %123 = OpCompositeExtract %int %tint_input 3
+        %124 = OpCompositeConstruct %S %119 %122 %123
+               OpReturnValue %124
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.glsl
index c3cf744..46f3074 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.glsl
@@ -84,9 +84,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index f3c94e9..21366e6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -83,9 +83,9 @@
   S v_20[4] = v_12(0u);
   w = v_20;
   S v_21 = v_8(256u);
-  w[int(1)] = v_21;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  w[1u] = v_21;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
index 5abec55..73f9ec1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -38,6 +38,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -76,6 +79,7 @@
     uint v_7 = 0u;
     v_7 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_8 = v_7;
       if ((v_8 >= 4u)) {
         break;
@@ -89,13 +93,13 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 2> const v_9 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 2> const v_9 = (*tint_module_vars.u)[2u].m;
   half3 const v_10 = half3(v_9[0u].packed);
   half2x3 const v_11 = half2x3(v_10, half3(v_9[1u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_half3(v_11[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_half3(v_11[1u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_half3(v_11[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_half3(v_11[1u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_12 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.msl
index ba781c5..2928013 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -49,6 +52,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
index fb493aa..6d565e4f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -77,16 +77,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v3half = OpTypePointer Workgroup %mat2v3half
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-      %int_0 = OpConstant %int 0
-         %91 = OpTypeFunction %void
-         %96 = OpTypeFunction %S %S_std140
+         %88 = OpTypeFunction %void
+         %93 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -143,39 +140,39 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat2v3half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %82 = OpLoad %v3half %81 None
-         %83 = OpCompositeConstruct %mat2v3half %80 %82
-               OpStore %75 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %uint_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v3half %87 None
-         %89 = OpVectorShuffle %v3half %88 %88 2 0 1
-               OpStore %84 %89 None
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat2v3half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3half %79 None
+         %81 = OpCompositeConstruct %mat2v3half %78 %80
+               OpStore %73 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_1 %uint_0
+         %84 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v3half %84 None
+         %86 = OpVectorShuffle %v3half %85 %85 2 0 1
+               OpStore %82 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %88
+         %89 = OpLabel
+         %90 = OpLoad %uint %f_local_invocation_index_Input None
+         %91 = OpFunctionCall %void %f_inner %90
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %93
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v3half %tint_input 1
-        %100 = OpCompositeExtract %v3half %tint_input 2
-        %101 = OpCompositeConstruct %mat2v3half %99 %100
-        %102 = OpCompositeExtract %int %tint_input 3
-        %103 = OpCompositeConstruct %S %98 %101 %102
-               OpReturnValue %103
+         %94 = OpLabel
+         %95 = OpCompositeExtract %int %tint_input 0
+         %96 = OpCompositeExtract %v3half %tint_input 1
+         %97 = OpCompositeExtract %v3half %tint_input 2
+         %98 = OpCompositeConstruct %mat2v3half %96 %97
+         %99 = OpCompositeExtract %int %tint_input 3
+        %100 = OpCompositeConstruct %S %95 %98 %99
+               OpReturnValue %100
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4beb18f..d4aedad 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -59,17 +59,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_2 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 4beb18f..d4aedad 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -59,17 +59,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_2 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 4d2d2e1..6ea76b1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -61,10 +61,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat2x3 v_6 = mat2x3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1);
-  vec3 v_7 = v_6[i()];
+  vec3 v_7 = v_6[min(uint(i()), 1u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))));
   {
@@ -105,5 +105,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat2x3 l_a_i_a_i_m = v_6;
   vec3 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 4ebb67e..301fab5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float2x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 4ebb67e..301fab5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float2x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index cc87658..1165ddb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -73,11 +73,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -86,5 +86,5 @@
   float3 const v_9 = float3(v_8[0u].packed);
   float2x3 const l_a_i_a_i_m = float2x3(v_9, float3(v_8[1u].packed));
   float3 const l_a_i_a_i_m_i = float3((*p_a_i_a_i_m_i));
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 7d84c9c..2b5b73e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -76,11 +76,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -88,7 +88,7 @@
   float2x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   float3 const l_a_i_a_i_m_i = float3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index c177c43..76d3364 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 140
+; Bound: 151
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -69,6 +70,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -83,17 +85,18 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %61 = OpConstantNull %_arr_Outer_uint_4
+         %69 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %88 = OpConstantNull %_arr_Inner_uint_4
+         %96 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %112 = OpTypeFunction %Inner %Inner_std140
-        %119 = OpTypeFunction %Outer %Outer_std140
+     %uint_2 = OpConstant %uint 2
+        %123 = OpTypeFunction %Inner %Inner_std140
+        %130 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -104,129 +107,137 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat2v3float Function
-         %53 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %61
-         %84 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %86 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
+         %52 = OpVariable %_ptr_Function_mat2v3float Function
+         %61 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %63 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %69
+         %92 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %94 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_0
-         %40 = OpLoad %v3float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_1
-         %43 = OpLoad %v3float %41 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat2v3float %40 %43
-               OpStore %46 %l_a_i_a_i_m
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v3float %46 %48
-%l_a_i_a_i_m_i = OpLoad %v3float %49 None
-         %52 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %53 %52
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %65
-         %65 = OpLabel
-         %67 = OpPhi %uint %uint_0 %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_4
-               OpSelectionMerge %71 None
-               OpBranchConditional %69 %72 %71
-         %72 = OpLabel
-               OpBranch %66
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_0
+         %46 = OpLoad %v3float %44 None
+         %47 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_1
+         %49 = OpLoad %v3float %47 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat2v3float %46 %49
+               OpStore %52 %l_a_i_a_i_m
+         %54 = OpFunctionCall %int %i
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %33 UMin %55 %uint_1
+         %57 = OpAccessChain %_ptr_Function_v3float %52 %56
+%l_a_i_a_i_m_i = OpLoad %v3float %57 None
+         %60 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %61 %60
+               OpBranch %70
+         %70 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+         %75 = OpPhi %uint %uint_0 %70 %76 %72
+               OpLoopMerge %74 %72 None
+               OpBranch %71
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_Function_Outer %55 %67
-         %75 = OpAccessChain %_ptr_Function_Outer_std140 %53 %67
-         %77 = OpLoad %Outer_std140 %75 None
-         %78 = OpFunctionCall %Outer %tint_convert_Outer %77
-               OpStore %73 %78 None
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
-         %66 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %55 None
-         %81 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %81
-         %83 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %84 %83
-               OpBranch %89
-         %89 = OpLabel
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpPhi %uint %uint_0 %89 %95 %91
-               OpLoopMerge %93 %91 None
-               OpBranch %90
-         %90 = OpLabel
-         %96 = OpUGreaterThanEqual %bool %94 %uint_4
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
-               OpBranch %93
+         %77 = OpUGreaterThanEqual %bool %75 %uint_4
+               OpSelectionMerge %79 None
+               OpBranchConditional %77 %80 %79
+         %80 = OpLabel
+               OpBranch %74
+         %79 = OpLabel
+         %81 = OpAccessChain %_ptr_Function_Outer %63 %75
+         %83 = OpAccessChain %_ptr_Function_Outer_std140 %61 %75
+         %85 = OpLoad %Outer_std140 %83 None
+         %86 = OpFunctionCall %Outer %tint_convert_Outer %85
+               OpStore %81 %86 None
+               OpBranch %72
+         %72 = OpLabel
+         %76 = OpIAdd %uint %75 %uint_1
+               OpBranch %73
+         %74 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %63 None
+         %89 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %89
+         %91 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %92 %91
+               OpBranch %97
          %97 = OpLabel
-         %99 = OpAccessChain %_ptr_Function_Inner %86 %94
-        %101 = OpAccessChain %_ptr_Function_Inner_std140 %84 %94
-        %103 = OpLoad %Inner_std140 %101 None
-        %104 = OpFunctionCall %Inner %tint_convert_Inner %103
-               OpStore %99 %104 None
-               OpBranch %91
-         %91 = OpLabel
-         %95 = OpIAdd %uint %94 %uint_1
-               OpBranch %92
-         %93 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %86 None
-        %107 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %107
-        %109 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %109
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpPhi %uint %uint_0 %97 %103 %99
+               OpLoopMerge %101 %99 None
+               OpBranch %98
+         %98 = OpLabel
+        %104 = OpUGreaterThanEqual %bool %102 %uint_4
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
+               OpBranch %101
+        %105 = OpLabel
+        %107 = OpAccessChain %_ptr_Function_Inner %94 %102
+        %109 = OpAccessChain %_ptr_Function_Inner_std140 %92 %102
+        %111 = OpLoad %Inner_std140 %109 None
+        %112 = OpFunctionCall %Inner %tint_convert_Inner %111
+               OpStore %107 %112 None
+               OpBranch %99
+         %99 = OpLabel
+        %103 = OpIAdd %uint %102 %uint_1
+               OpBranch %100
+        %101 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %94 None
+        %115 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %115
+        %117 = OpFunctionCall %int %i
+        %118 = OpBitcast %uint %117
+        %119 = OpExtInst %uint %33 UMin %118 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %119
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %112
+%tint_convert_Inner = OpFunction %Inner None %123
  %tint_input = OpFunctionParameter %Inner_std140
-        %113 = OpLabel
-        %114 = OpCompositeExtract %v3float %tint_input 0
-        %115 = OpCompositeExtract %v3float %tint_input 1
-        %116 = OpCompositeConstruct %mat2v3float %114 %115
-        %117 = OpCompositeConstruct %Inner %116
-               OpReturnValue %117
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %119
-%tint_input_0 = OpFunctionParameter %Outer_std140
-        %120 = OpLabel
-        %122 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %123 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
-        %121 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %122 %121
-               OpBranch %124
         %124 = OpLabel
-               OpBranch %127
-        %127 = OpLabel
-        %129 = OpPhi %uint %uint_0 %124 %130 %126
-               OpLoopMerge %128 %126 None
-               OpBranch %125
-        %125 = OpLabel
-        %131 = OpUGreaterThanEqual %bool %129 %uint_4
-               OpSelectionMerge %132 None
-               OpBranchConditional %131 %133 %132
-        %133 = OpLabel
-               OpBranch %128
-        %132 = OpLabel
-        %134 = OpAccessChain %_ptr_Function_Inner %123 %129
-        %135 = OpAccessChain %_ptr_Function_Inner_std140 %122 %129
-        %136 = OpLoad %Inner_std140 %135 None
-        %137 = OpFunctionCall %Inner %tint_convert_Inner %136
-               OpStore %134 %137 None
-               OpBranch %126
-        %126 = OpLabel
-        %130 = OpIAdd %uint %129 %uint_1
-               OpBranch %127
-        %128 = OpLabel
-        %138 = OpLoad %_arr_Inner_uint_4 %123 None
-        %139 = OpCompositeConstruct %Outer %138
-               OpReturnValue %139
+        %125 = OpCompositeExtract %v3float %tint_input 0
+        %126 = OpCompositeExtract %v3float %tint_input 1
+        %127 = OpCompositeConstruct %mat2v3float %125 %126
+        %128 = OpCompositeConstruct %Inner %127
+               OpReturnValue %128
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %130
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %131 = OpLabel
+        %133 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %134 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
+        %132 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %133 %132
+               OpBranch %135
+        %135 = OpLabel
+               OpBranch %138
+        %138 = OpLabel
+        %140 = OpPhi %uint %uint_0 %135 %141 %137
+               OpLoopMerge %139 %137 None
+               OpBranch %136
+        %136 = OpLabel
+        %142 = OpUGreaterThanEqual %bool %140 %uint_4
+               OpSelectionMerge %143 None
+               OpBranchConditional %142 %144 %143
+        %144 = OpLabel
+               OpBranch %139
+        %143 = OpLabel
+        %145 = OpAccessChain %_ptr_Function_Inner %134 %140
+        %146 = OpAccessChain %_ptr_Function_Inner_std140 %133 %140
+        %147 = OpLoad %Inner_std140 %146 None
+        %148 = OpFunctionCall %Inner %tint_convert_Inner %147
+               OpStore %145 %148 None
+               OpBranch %137
+        %137 = OpLabel
+        %141 = OpIAdd %uint %140 %uint_1
+               OpBranch %138
+        %139 = OpLabel
+        %149 = OpLoad %_arr_Inner_uint_4 %134 None
+        %150 = OpCompositeConstruct %Outer %149
+               OpReturnValue %150
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
index b3e4fc0..5d1b67d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -56,7 +56,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2x3 v_4 = mat2x3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1);
+  mat2x3 v_4 = mat2x3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))))));
   {
@@ -75,8 +75,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))), Inner(mat2x3(vec3(0.0f), vec3(0.0f))));
   {
     uint v_11 = 0u;
@@ -94,8 +94,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat2x3 l_a_3_a_2_m = v_4;
-  vec3 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index badb391..e5814ec 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -66,11 +66,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -79,5 +79,5 @@
   float3 const v_9 = float3(v_8[0u].packed);
   float2x3 const l_a_3_a_2_m = float2x3(v_9, float3(v_8[1u].packed));
   float3 const l_a_3_a_2_m_1 = float3((*p_a_3_a_2_m_1));
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index 9ab2bff..b8523ba 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 124
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -62,11 +62,10 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
 %mat2v3float = OpTypeMatrix %v3float 2
@@ -76,135 +75,135 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %46 = OpConstantNull %_arr_Outer_uint_4
+         %45 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %73 = OpConstantNull %_arr_Inner_uint_4
+         %72 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %96 = OpTypeFunction %Inner %Inner_std140
-        %103 = OpTypeFunction %Outer %Outer_std140
+         %95 = OpTypeFunction %Inner %Inner_std140
+        %102 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %46
-         %69 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %71 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
+         %37 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %39 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %45
+         %68 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %70 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_0
-         %30 = OpLoad %v3float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_1
-         %33 = OpLoad %v3float %31 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat2v3float %30 %33
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_0
+         %29 = OpLoad %v3float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_1
+         %32 = OpLoad %v3float %30 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat2v3float %29 %32
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3float %l_a_3_a_2_m 1
-         %37 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %38 %37
-               OpBranch %47
-         %47 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-         %52 = OpPhi %uint %uint_0 %47 %53 %49
-               OpLoopMerge %51 %49 None
-               OpBranch %48
-         %48 = OpLabel
-         %54 = OpUGreaterThanEqual %bool %52 %uint_4
-               OpSelectionMerge %56 None
-               OpBranchConditional %54 %57 %56
-         %57 = OpLabel
-               OpBranch %51
-         %56 = OpLabel
-         %58 = OpAccessChain %_ptr_Function_Outer %40 %52
-         %60 = OpAccessChain %_ptr_Function_Outer_std140 %38 %52
-         %62 = OpLoad %Outer_std140 %60 None
-         %63 = OpFunctionCall %Outer %tint_convert_Outer %62
-               OpStore %58 %63 None
+         %36 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %37 %36
+               OpBranch %46
+         %46 = OpLabel
                OpBranch %49
          %49 = OpLabel
-         %53 = OpIAdd %uint %52 %uint_1
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
-         %51 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %40 None
-         %66 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %66
-         %68 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %69 %68
-               OpBranch %74
-         %74 = OpLabel
-               OpBranch %77
-         %77 = OpLabel
-         %79 = OpPhi %uint %uint_0 %74 %80 %76
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %81 = OpUGreaterThanEqual %bool %79 %uint_4
-               OpSelectionMerge %82 None
-               OpBranchConditional %81 %83 %82
-         %83 = OpLabel
-               OpBranch %78
-         %82 = OpLabel
-         %84 = OpAccessChain %_ptr_Function_Inner %71 %79
-         %86 = OpAccessChain %_ptr_Function_Inner_std140 %69 %79
-         %88 = OpLoad %Inner_std140 %86 None
-         %89 = OpFunctionCall %Inner %tint_convert_Inner %88
-               OpStore %84 %89 None
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_Outer %39 %51
+         %59 = OpAccessChain %_ptr_Function_Outer_std140 %37 %51
+         %61 = OpLoad %Outer_std140 %59 None
+         %62 = OpFunctionCall %Outer %tint_convert_Outer %61
+               OpStore %57 %62 None
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
+         %50 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %39 None
+         %65 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %65
+         %67 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %68 %67
+               OpBranch %73
+         %73 = OpLabel
                OpBranch %76
          %76 = OpLabel
-         %80 = OpIAdd %uint %79 %uint_1
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
+         %74 = OpLabel
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %81
+         %82 = OpLabel
                OpBranch %77
-         %78 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %71 None
-         %92 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %92
+         %81 = OpLabel
+         %83 = OpAccessChain %_ptr_Function_Inner %70 %78
+         %85 = OpAccessChain %_ptr_Function_Inner_std140 %68 %78
+         %87 = OpLoad %Inner_std140 %85 None
+         %88 = OpFunctionCall %Inner %tint_convert_Inner %87
+               OpStore %83 %88 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %70 None
+         %91 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %91
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %96
+%tint_convert_Inner = OpFunction %Inner None %95
  %tint_input = OpFunctionParameter %Inner_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %v3float %tint_input 0
-         %99 = OpCompositeExtract %v3float %tint_input 1
-        %100 = OpCompositeConstruct %mat2v3float %98 %99
-        %101 = OpCompositeConstruct %Inner %100
-               OpReturnValue %101
+         %96 = OpLabel
+         %97 = OpCompositeExtract %v3float %tint_input 0
+         %98 = OpCompositeExtract %v3float %tint_input 1
+         %99 = OpCompositeConstruct %mat2v3float %97 %98
+        %100 = OpCompositeConstruct %Inner %99
+               OpReturnValue %100
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %103
+%tint_convert_Outer = OpFunction %Outer None %102
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %104 = OpLabel
-        %106 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %107 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
-        %105 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %106 %105
-               OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_4
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_Inner %107 %113
-        %119 = OpAccessChain %_ptr_Function_Inner_std140 %106 %113
-        %120 = OpLoad %Inner_std140 %119 None
-        %121 = OpFunctionCall %Inner %tint_convert_Inner %120
-               OpStore %118 %121 None
+        %103 = OpLabel
+        %105 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %106 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
+        %104 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %105 %104
+               OpBranch %107
+        %107 = OpLabel
                OpBranch %110
         %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
+        %112 = OpPhi %uint %uint_0 %107 %113 %109
+               OpLoopMerge %111 %109 None
+               OpBranch %108
+        %108 = OpLabel
+        %114 = OpUGreaterThanEqual %bool %112 %uint_4
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %115
+        %116 = OpLabel
                OpBranch %111
-        %112 = OpLabel
-        %122 = OpLoad %_arr_Inner_uint_4 %107 None
-        %123 = OpCompositeConstruct %Outer %122
-               OpReturnValue %123
+        %115 = OpLabel
+        %117 = OpAccessChain %_ptr_Function_Inner %106 %112
+        %118 = OpAccessChain %_ptr_Function_Inner_std140 %105 %112
+        %119 = OpLoad %Inner_std140 %118 None
+        %120 = OpFunctionCall %Inner %tint_convert_Inner %119
+               OpStore %117 %120 None
+               OpBranch %109
+        %109 = OpLabel
+        %113 = OpIAdd %uint %112 %uint_1
+               OpBranch %110
+        %111 = OpLabel
+        %121 = OpLoad %_arr_Inner_uint_4 %106 None
+        %122 = OpCompositeConstruct %Outer %121
+               OpReturnValue %122
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.glsl
index 2ecc267..939585a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.glsl
@@ -38,7 +38,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3x2 t = transpose(mat2x3(v.inner[2].m_col0, v.inner[2].m_col1));
-  float l = length(v.inner[0].m_col1.zxy);
-  float a = abs(v.inner[0].m_col1.zxy[0u]);
+  mat3x2 t = transpose(mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1));
+  float l = length(v.inner[0u].m_col1.zxy);
+  float a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
index d94a89d..741fe39 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -33,9 +33,9 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u)[2u].m;
   float3 const v_1 = float3(v[0u].packed);
   float3x2 const t = transpose(float2x3(v_1, float3(v[1u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.spvasm
index 9a91fed..e106453 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
-         %34 = OpExtInstImport "GLSL.std.450"
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -43,29 +43,27 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
 %mat2v3float = OpTypeMatrix %v3float 2
     %v2float = OpTypeVector %float 2
 %mat3v2float = OpTypeMatrix %v2float 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3float %21 None
-         %25 = OpCompositeConstruct %mat2v3float %20 %23
-          %t = OpTranspose %mat3v2float %25
-         %29 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %31 = OpLoad %v3float %29 None
-         %32 = OpVectorShuffle %v3float %31 %31 2 0 1
-          %l = OpExtInst %float %34 Length %32
-         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v3float %35 None
-         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
-         %38 = OpCompositeExtract %float %37 0
-          %a = OpExtInst %float %34 FAbs %38
+         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3float %21 None
+         %24 = OpCompositeConstruct %mat2v3float %20 %22
+          %t = OpTranspose %mat3v2float %24
+         %28 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %29 = OpLoad %v3float %28 None
+         %30 = OpVectorShuffle %v3float %29 %29 2 0 1
+          %l = OpExtInst %float %32 Length %30
+         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v3float %33 None
+         %35 = OpVectorShuffle %v3float %34 %34 2 0 1
+         %36 = OpCompositeExtract %float %35 0
+          %a = OpExtInst %float %32 FAbs %36
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.glsl
index c5139c7..2a002b5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.glsl
@@ -75,8 +75,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat2x3(v_1.inner[2].m_col0, v_1.inner[2].m_col1));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat2x3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.ir.msl
index 00532d1..0d5283b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.ir.msl
@@ -70,10 +70,10 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_8 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_8 = (*tint_module_vars.u)[2u].m;
   float3 const v_9 = float3(v_8[0u].packed);
   c(float2x3(v_9, float3(v_8[1u].packed)));
-  d(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.spvasm
index ac759bf..2a222cf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 101
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -77,11 +77,9 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
-      %int_0 = OpConstant %int 0
-         %93 = OpTypeFunction %S %S_std140
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
+         %91 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -140,35 +138,35 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3float %77 None
-         %80 = OpCompositeConstruct %mat2v3float %76 %79
-         %81 = OpFunctionCall %void %c %80
-         %82 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v3float %82 None
-         %85 = OpVectorShuffle %v3float %84 %84 2 0 1
-         %86 = OpFunctionCall %void %d %85
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v3float %87 None
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-         %90 = OpCompositeExtract %float %89 0
-         %91 = OpFunctionCall %void %e %90
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3float %77 None
+         %79 = OpCompositeConstruct %mat2v3float %76 %78
+         %80 = OpFunctionCall %void %c %79
+         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %82 = OpLoad %v3float %81 None
+         %83 = OpVectorShuffle %v3float %82 %82 2 0 1
+         %84 = OpFunctionCall %void %d %83
+         %85 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %86 = OpLoad %v3float %85 None
+         %87 = OpVectorShuffle %v3float %86 %86 2 0 1
+         %88 = OpCompositeExtract %float %87 0
+         %89 = OpFunctionCall %void %e %88
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %93
+%tint_convert_S = OpFunction %S None %91
  %tint_input = OpFunctionParameter %S_std140
-         %94 = OpLabel
-         %95 = OpCompositeExtract %int %tint_input 0
-         %96 = OpCompositeExtract %v3float %tint_input 1
-         %97 = OpCompositeExtract %v3float %tint_input 2
-         %98 = OpCompositeConstruct %mat2v3float %96 %97
-         %99 = OpCompositeExtract %int %tint_input 3
-        %100 = OpCompositeConstruct %S %95 %98 %99
-               OpReturnValue %100
+         %92 = OpLabel
+         %93 = OpCompositeExtract %int %tint_input 0
+         %94 = OpCompositeExtract %v3float %tint_input 1
+         %95 = OpCompositeExtract %v3float %tint_input 2
+         %96 = OpCompositeConstruct %mat2v3float %94 %95
+         %97 = OpCompositeExtract %int %tint_input 3
+         %98 = OpCompositeConstruct %S %93 %96 %97
+               OpReturnValue %98
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.glsl
index ee21a22..f4abc86 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.glsl
@@ -66,7 +66,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 4d57e7b..bee197d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 4d57e7b..bee197d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.msl
index 25bb9a3..4f51319 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.ir.msl
@@ -57,9 +57,9 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_7 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_7 = (*tint_module_vars.u)[2u].m;
   float3 const v_8 = float3(v_7[0u].packed);
-  (*tint_module_vars.p)[3].m = float2x3(v_8, float3(v_7[1u].packed));
-  (*tint_module_vars.p)[1].m[0] = float3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = float2x3(v_8, float3(v_7[1u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = float3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.spvasm
index eacf311..1587b42 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 82
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -65,16 +65,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v3float = OpTypePointer Private %mat2v3float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v3float = OpTypePointer Private %mat2v3float
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
-         %74 = OpTypeFunction %S %S_std140
+         %71 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -108,33 +105,33 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat2v3float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3float %63 None
-         %66 = OpCompositeConstruct %mat2v3float %62 %65
-               OpStore %57 %66 None
-         %67 = OpAccessChain %_ptr_Private_v3float %p %int_1 %uint_1 %int_0
-         %70 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %71 = OpLoad %v3float %70 None
-         %72 = OpVectorShuffle %v3float %71 %71 2 0 1
-               OpStore %67 %72 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat2v3float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3float %62 None
+         %64 = OpCompositeConstruct %mat2v3float %61 %63
+               OpStore %56 %64 None
+         %65 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %68 = OpLoad %v3float %67 None
+         %69 = OpVectorShuffle %v3float %68 %68 2 0 1
+               OpStore %65 %69 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %74
+%tint_convert_S = OpFunction %S None %71
  %tint_input = OpFunctionParameter %S_std140
-         %75 = OpLabel
-         %76 = OpCompositeExtract %int %tint_input 0
-         %77 = OpCompositeExtract %v3float %tint_input 1
-         %78 = OpCompositeExtract %v3float %tint_input 2
-         %79 = OpCompositeConstruct %mat2v3float %77 %78
-         %80 = OpCompositeExtract %int %tint_input 3
-         %81 = OpCompositeConstruct %S %76 %79 %80
-               OpReturnValue %81
+         %72 = OpLabel
+         %73 = OpCompositeExtract %int %tint_input 0
+         %74 = OpCompositeExtract %v3float %tint_input 1
+         %75 = OpCompositeExtract %v3float %tint_input 2
+         %76 = OpCompositeConstruct %mat2v3float %74 %75
+         %77 = OpCompositeExtract %int %tint_input 3
+         %78 = OpCompositeConstruct %S %73 %76 %77
+               OpReturnValue %78
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
index 485baf4..f8c2b8e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -117,9 +117,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  mat2x3 v_9 = mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  mat2x3 v_9 = mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.ir.msl
index 62fde8f..9af3b40 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.ir.msl
@@ -33,6 +33,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -62,6 +65,7 @@
     uint v_4 = 0u;
     v_4 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_5 = v_4;
       if ((v_5 >= 4u)) {
         break;
@@ -85,9 +89,9 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_9 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_9 = (*tint_module_vars.u)[2u].m;
   float3 const v_10 = float3(v_9[0u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), float2x3(v_10, float3(v_9[1u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), float2x3(v_10, float3(v_9[1u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
index 8bd90cd..b9a9881 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -65,7 +68,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
index ca1dab1..ca2e0d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 130
+; Bound: 125
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -81,19 +81,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-     %uint_2 = OpConstant %uint 2
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
-         %82 = OpTypeFunction %void %_arr_S_uint_4
-        %101 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %77 = OpTypeFunction %void %_arr_S_uint_4
+         %96 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %114 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
-        %122 = OpTypeFunction %S %S_std140
+        %109 = OpTypeFunction %void %_arr_uint_uint_1 %mat2v3float
+        %117 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -127,94 +124,92 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %68 = OpLoad %v3float %66 None
-         %69 = OpCompositeConstruct %mat2v3float %65 %68
-         %70 = OpBitcast %uint %int_3
-         %72 = OpCompositeConstruct %_arr_uint_uint_1 %70
-         %73 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %72 %69
-         %75 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %int_1 %uint_1 %int_0
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %79 = OpLoad %v3float %78 None
-         %80 = OpVectorShuffle %v3float %79 %79 2 0 1
-               OpStore %75 %80 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3float %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3float %64 None
+         %66 = OpCompositeConstruct %mat2v3float %63 %65
+         %67 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %69 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %67 %66
+         %71 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %74 = OpLoad %v3float %73 None
+         %75 = OpVectorShuffle %v3float %74 %74 2 0 1
+               OpStore %71 %75 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %82
+%tint_store_and_preserve_padding = OpFunction %void None %77
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %78 = OpLabel
+         %79 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %79 %value_param
+               OpBranch %80
+         %80 = OpLabel
+               OpBranch %83
          %83 = OpLabel
-         %84 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %84 %value_param
-               OpBranch %85
-         %85 = OpLabel
-               OpBranch %88
-         %88 = OpLabel
-         %90 = OpPhi %uint %uint_0 %85 %91 %87
-               OpLoopMerge %89 %87 None
-               OpBranch %86
-         %86 = OpLabel
-         %92 = OpUGreaterThanEqual %bool %90 %uint_4
-               OpSelectionMerge %93 None
-               OpBranchConditional %92 %94 %93
-         %94 = OpLabel
-               OpBranch %89
-         %93 = OpLabel
-         %95 = OpAccessChain %_ptr_Function_S %84 %90
-         %96 = OpLoad %S %95 None
-         %97 = OpCompositeConstruct %_arr_uint_uint_1 %90
-         %98 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %97 %96
-               OpBranch %87
-         %87 = OpLabel
-         %91 = OpIAdd %uint %90 %uint_1
-               OpBranch %88
+         %85 = OpPhi %uint %uint_0 %80 %86 %82
+               OpLoopMerge %84 %82 None
+               OpBranch %81
+         %81 = OpLabel
+         %87 = OpUGreaterThanEqual %bool %85 %uint_4
+               OpSelectionMerge %88 None
+               OpBranchConditional %87 %89 %88
          %89 = OpLabel
+               OpBranch %84
+         %88 = OpLabel
+         %90 = OpAccessChain %_ptr_Function_S %79 %85
+         %91 = OpLoad %S %90 None
+         %92 = OpCompositeConstruct %_arr_uint_uint_1 %85
+         %93 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %92 %91
+               OpBranch %82
+         %82 = OpLabel
+         %86 = OpIAdd %uint %85 %uint_1
+               OpBranch %83
+         %84 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %101
+%tint_store_and_preserve_padding_0 = OpFunction %void None %96
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %102 = OpLabel
-        %103 = OpCompositeExtract %uint %target_indices 0
-        %104 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %103 %uint_0
-        %106 = OpCompositeExtract %int %value_param_0 0
-               OpStore %104 %106 None
-        %107 = OpCompositeExtract %mat2v3float %value_param_0 1
-        %108 = OpCompositeConstruct %_arr_uint_uint_1 %103
-        %109 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %108 %107
-        %110 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %103 %uint_2
-        %111 = OpCompositeExtract %int %value_param_0 2
-               OpStore %110 %111 None
+         %97 = OpLabel
+         %98 = OpCompositeExtract %uint %target_indices 0
+         %99 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %98 %uint_0
+        %101 = OpCompositeExtract %int %value_param_0 0
+               OpStore %99 %101 None
+        %102 = OpCompositeExtract %mat2v3float %value_param_0 1
+        %103 = OpCompositeConstruct %_arr_uint_uint_1 %98
+        %104 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %103 %102
+        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %98 %uint_2
+        %106 = OpCompositeExtract %int %value_param_0 2
+               OpStore %105 %106 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %114
+%tint_store_and_preserve_padding_1 = OpFunction %void None %109
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat2v3float
-        %115 = OpLabel
-        %116 = OpCompositeExtract %uint %target_indices_0 0
-        %117 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %116 %uint_1 %uint_0
-        %118 = OpCompositeExtract %v3float %value_param_1 0
-               OpStore %117 %118 None
-        %119 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %116 %uint_1 %uint_1
-        %120 = OpCompositeExtract %v3float %value_param_1 1
-               OpStore %119 %120 None
+        %110 = OpLabel
+        %111 = OpCompositeExtract %uint %target_indices_0 0
+        %112 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %111 %uint_1 %uint_0
+        %113 = OpCompositeExtract %v3float %value_param_1 0
+               OpStore %112 %113 None
+        %114 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %111 %uint_1 %uint_1
+        %115 = OpCompositeExtract %v3float %value_param_1 1
+               OpStore %114 %115 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %122
+%tint_convert_S = OpFunction %S None %117
  %tint_input = OpFunctionParameter %S_std140
-        %123 = OpLabel
-        %124 = OpCompositeExtract %int %tint_input 0
-        %125 = OpCompositeExtract %v3float %tint_input 1
-        %126 = OpCompositeExtract %v3float %tint_input 2
-        %127 = OpCompositeConstruct %mat2v3float %125 %126
-        %128 = OpCompositeExtract %int %tint_input 3
-        %129 = OpCompositeConstruct %S %124 %127 %128
-               OpReturnValue %129
+        %118 = OpLabel
+        %119 = OpCompositeExtract %int %tint_input 0
+        %120 = OpCompositeExtract %v3float %tint_input 1
+        %121 = OpCompositeExtract %v3float %tint_input 2
+        %122 = OpCompositeConstruct %mat2v3float %120 %121
+        %123 = OpCompositeExtract %int %tint_input 3
+        %124 = OpCompositeConstruct %S %119 %122 %123
+               OpReturnValue %124
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.glsl
index c0722e7..5956898 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.glsl
@@ -81,9 +81,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat2x3(v.inner[2].m_col0, v.inner[2].m_col1);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat2x3(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index d1cf9c5..d78a265 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index d1cf9c5..d78a265 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
index 5040acc..604a9fc 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -38,6 +38,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -76,6 +79,7 @@
     uint v_7 = 0u;
     v_7 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_8 = v_7;
       if ((v_8 >= 4u)) {
         break;
@@ -89,13 +93,13 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 2> const v_9 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 2> const v_9 = (*tint_module_vars.u)[2u].m;
   float3 const v_10 = float3(v_9[0u].packed);
   float2x3 const v_11 = float2x3(v_10, float3(v_9[1u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_float3(v_11[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_float3(v_11[1u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_float3(v_11[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_float3(v_11[1u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_12 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.msl
index d721957..50e1231 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -49,6 +52,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
index 84fd734..a302a5f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -74,16 +74,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v3float = OpTypePointer Workgroup %mat2v3float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
-         %91 = OpTypeFunction %void
-         %96 = OpTypeFunction %S %S_std140
+         %88 = OpTypeFunction %void
+         %93 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -140,39 +137,39 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat2v3float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %82 = OpLoad %v3float %81 None
-         %83 = OpCompositeConstruct %mat2v3float %80 %82
-               OpStore %75 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %uint_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v3float %87 None
-         %89 = OpVectorShuffle %v3float %88 %88 2 0 1
-               OpStore %84 %89 None
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat2v3float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3float %79 None
+         %81 = OpCompositeConstruct %mat2v3float %78 %80
+               OpStore %73 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_1 %uint_0
+         %84 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v3float %84 None
+         %86 = OpVectorShuffle %v3float %85 %85 2 0 1
+               OpStore %82 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %88
+         %89 = OpLabel
+         %90 = OpLoad %uint %f_local_invocation_index_Input None
+         %91 = OpFunctionCall %void %f_inner %90
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %93
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v3float %tint_input 1
-        %100 = OpCompositeExtract %v3float %tint_input 2
-        %101 = OpCompositeConstruct %mat2v3float %99 %100
-        %102 = OpCompositeExtract %int %tint_input 3
-        %103 = OpCompositeConstruct %S %98 %101 %102
-               OpReturnValue %103
+         %94 = OpLabel
+         %95 = OpCompositeExtract %int %tint_input 0
+         %96 = OpCompositeExtract %v3float %tint_input 1
+         %97 = OpCompositeExtract %v3float %tint_input 2
+         %98 = OpCompositeConstruct %mat2v3float %96 %97
+         %99 = OpCompositeExtract %int %tint_input 3
+        %100 = OpCompositeConstruct %S %95 %98 %99
+               OpReturnValue %100
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 43a6b87..125c8b4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -67,11 +67,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 2, 4> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 2, 4> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   uint4 ubo_load_5 = a[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
@@ -81,7 +81,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 1u))) + (2u * min(uint(tint_symbol_3), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index ed7b9a5..b2d15aa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -64,10 +64,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat2x4 v_6 = f16mat2x4(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1);
-  f16vec4 v_7 = v_6[i()];
+  f16vec4 v_7 = v_6[min(uint(i()), 1u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -108,5 +108,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat2x4 l_a_i_a_i_m = v_6;
   f16vec4 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index f4b8ea3..ddd293f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -94,9 +94,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_23 = (256u * uint(i()));
-  uint v_24 = (64u * uint(i()));
-  uint v_25 = (8u * uint(i()));
+  uint v_23 = (256u * uint(min(uint(i()), 3u)));
+  uint v_24 = (64u * uint(min(uint(i()), 3u)));
+  uint v_25 = (8u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_18(0u);
   Outer l_a_i = v_15(v_23);
   Inner l_a_i_a[4] = v_10(v_23);
@@ -104,7 +104,7 @@
   matrix<float16_t, 2, 4> l_a_i_a_i_m = v_4((v_23 + v_24));
   uint4 v_26 = a[(((v_23 + v_24) + v_25) / 16u)];
   vector<float16_t, 4> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_23 + v_24) + v_25) % 16u) / 4u) == 2u)) ? (v_26.zw) : (v_26.xy)));
-  uint v_27 = (((v_23 + v_24) + v_25) + (uint(i()) * 2u));
+  uint v_27 = (((v_23 + v_24) + v_25) + (uint(min(uint(i()), 3u)) * 2u));
   uint v_28 = a[(v_27 / 16u)][((v_27 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_28 >> ((((v_27 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 665349c..a172c24 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half2x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half2x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index eb79a3c..7bbe246 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half2x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 72693fb..051896b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 140
+; Bound: 150
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,6 +73,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -86,17 +88,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %61 = OpConstantNull %_arr_Outer_uint_4
+         %69 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %88 = OpConstantNull %_arr_Inner_uint_4
+         %96 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %112 = OpTypeFunction %Inner %Inner_std140
-        %119 = OpTypeFunction %Outer %Outer_std140
+        %122 = OpTypeFunction %Inner %Inner_std140
+        %129 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -107,129 +109,137 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %46 = OpVariable %_ptr_Function_mat2v4half Function
-         %53 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %55 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %61
-         %84 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %86 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
+         %52 = OpVariable %_ptr_Function_mat2v4half Function
+         %61 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %63 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %69
+         %92 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %94 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_0
-         %40 = OpLoad %v4half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_1
-         %43 = OpLoad %v4half %41 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat2v4half %40 %43
-               OpStore %46 %l_a_i_a_i_m
-         %48 = OpFunctionCall %int %i
-         %49 = OpAccessChain %_ptr_Function_v4half %46 %48
-%l_a_i_a_i_m_i = OpLoad %v4half %49 None
-         %52 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %53 %52
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %65
-         %65 = OpLabel
-         %67 = OpPhi %uint %uint_0 %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_4
-               OpSelectionMerge %71 None
-               OpBranchConditional %69 %72 %71
-         %72 = OpLabel
-               OpBranch %66
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_0
+         %46 = OpLoad %v4half %44 None
+         %47 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_1
+         %49 = OpLoad %v4half %47 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat2v4half %46 %49
+               OpStore %52 %l_a_i_a_i_m
+         %54 = OpFunctionCall %int %i
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %33 UMin %55 %uint_1
+         %57 = OpAccessChain %_ptr_Function_v4half %52 %56
+%l_a_i_a_i_m_i = OpLoad %v4half %57 None
+         %60 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %61 %60
+               OpBranch %70
+         %70 = OpLabel
+               OpBranch %73
+         %73 = OpLabel
+         %75 = OpPhi %uint %uint_0 %70 %76 %72
+               OpLoopMerge %74 %72 None
+               OpBranch %71
          %71 = OpLabel
-         %73 = OpAccessChain %_ptr_Function_Outer %55 %67
-         %75 = OpAccessChain %_ptr_Function_Outer_std140 %53 %67
-         %77 = OpLoad %Outer_std140 %75 None
-         %78 = OpFunctionCall %Outer %tint_convert_Outer %77
-               OpStore %73 %78 None
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
-         %66 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %55 None
-         %81 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %81
-         %83 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %84 %83
-               OpBranch %89
-         %89 = OpLabel
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpPhi %uint %uint_0 %89 %95 %91
-               OpLoopMerge %93 %91 None
-               OpBranch %90
-         %90 = OpLabel
-         %96 = OpUGreaterThanEqual %bool %94 %uint_4
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
-               OpBranch %93
+         %77 = OpUGreaterThanEqual %bool %75 %uint_4
+               OpSelectionMerge %79 None
+               OpBranchConditional %77 %80 %79
+         %80 = OpLabel
+               OpBranch %74
+         %79 = OpLabel
+         %81 = OpAccessChain %_ptr_Function_Outer %63 %75
+         %83 = OpAccessChain %_ptr_Function_Outer_std140 %61 %75
+         %85 = OpLoad %Outer_std140 %83 None
+         %86 = OpFunctionCall %Outer %tint_convert_Outer %85
+               OpStore %81 %86 None
+               OpBranch %72
+         %72 = OpLabel
+         %76 = OpIAdd %uint %75 %uint_1
+               OpBranch %73
+         %74 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %63 None
+         %89 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %89
+         %91 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %92 %91
+               OpBranch %97
          %97 = OpLabel
-         %99 = OpAccessChain %_ptr_Function_Inner %86 %94
-        %101 = OpAccessChain %_ptr_Function_Inner_std140 %84 %94
-        %103 = OpLoad %Inner_std140 %101 None
-        %104 = OpFunctionCall %Inner %tint_convert_Inner %103
-               OpStore %99 %104 None
-               OpBranch %91
-         %91 = OpLabel
-         %95 = OpIAdd %uint %94 %uint_1
-               OpBranch %92
-         %93 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %86 None
-        %107 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %107
-        %109 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %109
+               OpBranch %100
+        %100 = OpLabel
+        %102 = OpPhi %uint %uint_0 %97 %103 %99
+               OpLoopMerge %101 %99 None
+               OpBranch %98
+         %98 = OpLabel
+        %104 = OpUGreaterThanEqual %bool %102 %uint_4
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
+               OpBranch %101
+        %105 = OpLabel
+        %107 = OpAccessChain %_ptr_Function_Inner %94 %102
+        %109 = OpAccessChain %_ptr_Function_Inner_std140 %92 %102
+        %111 = OpLoad %Inner_std140 %109 None
+        %112 = OpFunctionCall %Inner %tint_convert_Inner %111
+               OpStore %107 %112 None
+               OpBranch %99
+         %99 = OpLabel
+        %103 = OpIAdd %uint %102 %uint_1
+               OpBranch %100
+        %101 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %94 None
+        %115 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %115
+        %117 = OpFunctionCall %int %i
+        %118 = OpBitcast %uint %117
+        %119 = OpExtInst %uint %33 UMin %118 %uint_3
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %119
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %112
+%tint_convert_Inner = OpFunction %Inner None %122
  %tint_input = OpFunctionParameter %Inner_std140
-        %113 = OpLabel
-        %114 = OpCompositeExtract %v4half %tint_input 0
-        %115 = OpCompositeExtract %v4half %tint_input 1
-        %116 = OpCompositeConstruct %mat2v4half %114 %115
-        %117 = OpCompositeConstruct %Inner %116
-               OpReturnValue %117
+        %123 = OpLabel
+        %124 = OpCompositeExtract %v4half %tint_input 0
+        %125 = OpCompositeExtract %v4half %tint_input 1
+        %126 = OpCompositeConstruct %mat2v4half %124 %125
+        %127 = OpCompositeConstruct %Inner %126
+               OpReturnValue %127
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %119
+%tint_convert_Outer = OpFunction %Outer None %129
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %120 = OpLabel
-        %122 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %123 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %88
-        %121 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %122 %121
-               OpBranch %124
-        %124 = OpLabel
-               OpBranch %127
-        %127 = OpLabel
-        %129 = OpPhi %uint %uint_0 %124 %130 %126
-               OpLoopMerge %128 %126 None
-               OpBranch %125
-        %125 = OpLabel
-        %131 = OpUGreaterThanEqual %bool %129 %uint_4
-               OpSelectionMerge %132 None
-               OpBranchConditional %131 %133 %132
-        %133 = OpLabel
-               OpBranch %128
-        %132 = OpLabel
-        %134 = OpAccessChain %_ptr_Function_Inner %123 %129
-        %135 = OpAccessChain %_ptr_Function_Inner_std140 %122 %129
-        %136 = OpLoad %Inner_std140 %135 None
-        %137 = OpFunctionCall %Inner %tint_convert_Inner %136
-               OpStore %134 %137 None
-               OpBranch %126
-        %126 = OpLabel
-        %130 = OpIAdd %uint %129 %uint_1
-               OpBranch %127
-        %128 = OpLabel
-        %138 = OpLoad %_arr_Inner_uint_4 %123 None
-        %139 = OpCompositeConstruct %Outer %138
-               OpReturnValue %139
+        %130 = OpLabel
+        %132 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %133 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %96
+        %131 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %132 %131
+               OpBranch %134
+        %134 = OpLabel
+               OpBranch %137
+        %137 = OpLabel
+        %139 = OpPhi %uint %uint_0 %134 %140 %136
+               OpLoopMerge %138 %136 None
+               OpBranch %135
+        %135 = OpLabel
+        %141 = OpUGreaterThanEqual %bool %139 %uint_4
+               OpSelectionMerge %142 None
+               OpBranchConditional %141 %143 %142
+        %143 = OpLabel
+               OpBranch %138
+        %142 = OpLabel
+        %144 = OpAccessChain %_ptr_Function_Inner %133 %139
+        %145 = OpAccessChain %_ptr_Function_Inner_std140 %132 %139
+        %146 = OpLoad %Inner_std140 %145 None
+        %147 = OpFunctionCall %Inner %tint_convert_Inner %146
+               OpStore %144 %147 None
+               OpBranch %136
+        %136 = OpLabel
+        %140 = OpIAdd %uint %139 %uint_1
+               OpBranch %137
+        %138 = OpLabel
+        %148 = OpLoad %_arr_Inner_uint_4 %133 None
+        %149 = OpCompositeConstruct %Outer %148
+               OpReturnValue %149
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
index 74fbdf7..8609169 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -59,7 +59,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x4 v_4 = f16mat2x4(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1);
+  f16mat2x4 v_4 = f16mat2x4(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -78,8 +78,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat2x4(f16vec4(0.0hf), f16vec4(0.0hf))));
   {
     uint v_11 = 0u;
@@ -97,8 +97,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat2x4 l_a_3_a_2_m = v_4;
-  f16vec4 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec4 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 56d0493..d3f1051 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half2x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half2x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
index 405d3a7..35a088b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 124
+; Bound: 123
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -65,11 +65,10 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
  %mat2v4half = OpTypeMatrix %v4half 2
@@ -79,135 +78,135 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %46 = OpConstantNull %_arr_Outer_uint_4
+         %45 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %73 = OpConstantNull %_arr_Inner_uint_4
+         %72 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %96 = OpTypeFunction %Inner %Inner_std140
-        %103 = OpTypeFunction %Outer %Outer_std140
+         %95 = OpTypeFunction %Inner %Inner_std140
+        %102 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %38 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %40 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %46
-         %69 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %71 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
+         %37 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %39 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %45
+         %68 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %70 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_0
-         %30 = OpLoad %v4half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_1
-         %33 = OpLoad %v4half %31 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat2v4half %30 %33
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_0
+         %29 = OpLoad %v4half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_1
+         %32 = OpLoad %v4half %30 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat2v4half %29 %32
 %l_a_3_a_2_m_1 = OpCompositeExtract %v4half %l_a_3_a_2_m 1
-         %37 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %38 %37
-               OpBranch %47
-         %47 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-         %52 = OpPhi %uint %uint_0 %47 %53 %49
-               OpLoopMerge %51 %49 None
-               OpBranch %48
-         %48 = OpLabel
-         %54 = OpUGreaterThanEqual %bool %52 %uint_4
-               OpSelectionMerge %56 None
-               OpBranchConditional %54 %57 %56
-         %57 = OpLabel
-               OpBranch %51
-         %56 = OpLabel
-         %58 = OpAccessChain %_ptr_Function_Outer %40 %52
-         %60 = OpAccessChain %_ptr_Function_Outer_std140 %38 %52
-         %62 = OpLoad %Outer_std140 %60 None
-         %63 = OpFunctionCall %Outer %tint_convert_Outer %62
-               OpStore %58 %63 None
+         %36 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %37 %36
+               OpBranch %46
+         %46 = OpLabel
                OpBranch %49
          %49 = OpLabel
-         %53 = OpIAdd %uint %52 %uint_1
+         %51 = OpPhi %uint %uint_0 %46 %52 %48
+               OpLoopMerge %50 %48 None
+               OpBranch %47
+         %47 = OpLabel
+         %53 = OpUGreaterThanEqual %bool %51 %uint_4
+               OpSelectionMerge %55 None
+               OpBranchConditional %53 %56 %55
+         %56 = OpLabel
                OpBranch %50
-         %51 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %40 None
-         %66 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %66
-         %68 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %69 %68
-               OpBranch %74
-         %74 = OpLabel
-               OpBranch %77
-         %77 = OpLabel
-         %79 = OpPhi %uint %uint_0 %74 %80 %76
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %81 = OpUGreaterThanEqual %bool %79 %uint_4
-               OpSelectionMerge %82 None
-               OpBranchConditional %81 %83 %82
-         %83 = OpLabel
-               OpBranch %78
-         %82 = OpLabel
-         %84 = OpAccessChain %_ptr_Function_Inner %71 %79
-         %86 = OpAccessChain %_ptr_Function_Inner_std140 %69 %79
-         %88 = OpLoad %Inner_std140 %86 None
-         %89 = OpFunctionCall %Inner %tint_convert_Inner %88
-               OpStore %84 %89 None
+         %55 = OpLabel
+         %57 = OpAccessChain %_ptr_Function_Outer %39 %51
+         %59 = OpAccessChain %_ptr_Function_Outer_std140 %37 %51
+         %61 = OpLoad %Outer_std140 %59 None
+         %62 = OpFunctionCall %Outer %tint_convert_Outer %61
+               OpStore %57 %62 None
+               OpBranch %48
+         %48 = OpLabel
+         %52 = OpIAdd %uint %51 %uint_1
+               OpBranch %49
+         %50 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %39 None
+         %65 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %65
+         %67 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %68 %67
+               OpBranch %73
+         %73 = OpLabel
                OpBranch %76
          %76 = OpLabel
-         %80 = OpIAdd %uint %79 %uint_1
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
+         %74 = OpLabel
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %81
+         %82 = OpLabel
                OpBranch %77
-         %78 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %71 None
-         %92 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %92
+         %81 = OpLabel
+         %83 = OpAccessChain %_ptr_Function_Inner %70 %78
+         %85 = OpAccessChain %_ptr_Function_Inner_std140 %68 %78
+         %87 = OpLoad %Inner_std140 %85 None
+         %88 = OpFunctionCall %Inner %tint_convert_Inner %87
+               OpStore %83 %88 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %70 None
+         %91 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %91
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %96
+%tint_convert_Inner = OpFunction %Inner None %95
  %tint_input = OpFunctionParameter %Inner_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %v4half %tint_input 0
-         %99 = OpCompositeExtract %v4half %tint_input 1
-        %100 = OpCompositeConstruct %mat2v4half %98 %99
-        %101 = OpCompositeConstruct %Inner %100
-               OpReturnValue %101
+         %96 = OpLabel
+         %97 = OpCompositeExtract %v4half %tint_input 0
+         %98 = OpCompositeExtract %v4half %tint_input 1
+         %99 = OpCompositeConstruct %mat2v4half %97 %98
+        %100 = OpCompositeConstruct %Inner %99
+               OpReturnValue %100
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %103
+%tint_convert_Outer = OpFunction %Outer None %102
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %104 = OpLabel
-        %106 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %107 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %73
-        %105 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %106 %105
-               OpBranch %108
-        %108 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %113 = OpPhi %uint %uint_0 %108 %114 %110
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
-        %115 = OpUGreaterThanEqual %bool %113 %uint_4
-               OpSelectionMerge %116 None
-               OpBranchConditional %115 %117 %116
-        %117 = OpLabel
-               OpBranch %112
-        %116 = OpLabel
-        %118 = OpAccessChain %_ptr_Function_Inner %107 %113
-        %119 = OpAccessChain %_ptr_Function_Inner_std140 %106 %113
-        %120 = OpLoad %Inner_std140 %119 None
-        %121 = OpFunctionCall %Inner %tint_convert_Inner %120
-               OpStore %118 %121 None
+        %103 = OpLabel
+        %105 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %106 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %72
+        %104 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %105 %104
+               OpBranch %107
+        %107 = OpLabel
                OpBranch %110
         %110 = OpLabel
-        %114 = OpIAdd %uint %113 %uint_1
+        %112 = OpPhi %uint %uint_0 %107 %113 %109
+               OpLoopMerge %111 %109 None
+               OpBranch %108
+        %108 = OpLabel
+        %114 = OpUGreaterThanEqual %bool %112 %uint_4
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %115
+        %116 = OpLabel
                OpBranch %111
-        %112 = OpLabel
-        %122 = OpLoad %_arr_Inner_uint_4 %107 None
-        %123 = OpCompositeConstruct %Outer %122
-               OpReturnValue %123
+        %115 = OpLabel
+        %117 = OpAccessChain %_ptr_Function_Inner %106 %112
+        %118 = OpAccessChain %_ptr_Function_Inner_std140 %105 %112
+        %119 = OpLoad %Inner_std140 %118 None
+        %120 = OpFunctionCall %Inner %tint_convert_Inner %119
+               OpStore %117 %120 None
+               OpBranch %109
+        %109 = OpLabel
+        %113 = OpIAdd %uint %112 %uint_1
+               OpBranch %110
+        %111 = OpLabel
+        %121 = OpLoad %_arr_Inner_uint_4 %106 None
+        %122 = OpCompositeConstruct %Outer %121
+               OpReturnValue %122
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.glsl
index e1e6e4a..ad7662c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.glsl
@@ -41,7 +41,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x2 t = transpose(f16mat2x4(v.inner[2].m_col0, v.inner[2].m_col1));
-  float16_t l = length(v.inner[0].m_col1.ywxz);
-  float16_t a = abs(v.inner[0].m_col1.ywxz[0u]);
+  f16mat4x2 t = transpose(f16mat2x4(v.inner[2u].m_col0, v.inner[2u].m_col1));
+  float16_t l = length(v.inner[0u].m_col1.ywxz);
+  float16_t a = abs(v.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
index c597a29..73e62af 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half4x2 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  half const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  half4x2 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.spvasm
index 30374cc..886fe0c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %34 = OpExtInstImport "GLSL.std.450"
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -46,29 +46,27 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
  %mat2v4half = OpTypeMatrix %v4half 2
      %v2half = OpTypeVector %half 2
  %mat4v2half = OpTypeMatrix %v2half 4
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v4half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v4half %21 None
-         %25 = OpCompositeConstruct %mat2v4half %20 %23
-          %t = OpTranspose %mat4v2half %25
-         %29 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %31 = OpLoad %v4half %29 None
-         %32 = OpVectorShuffle %v4half %31 %31 1 3 0 2
-          %l = OpExtInst %half %34 Length %32
-         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v4half %35 None
-         %37 = OpVectorShuffle %v4half %36 %36 1 3 0 2
-         %38 = OpCompositeExtract %half %37 0
-          %a = OpExtInst %half %34 FAbs %38
+         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v4half %21 None
+         %24 = OpCompositeConstruct %mat2v4half %20 %22
+          %t = OpTranspose %mat4v2half %24
+         %28 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %29 = OpLoad %v4half %28 None
+         %30 = OpVectorShuffle %v4half %29 %29 1 3 0 2
+          %l = OpExtInst %half %32 Length %30
+         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v4half %33 None
+         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
+         %36 = OpCompositeExtract %half %35 0
+          %a = OpExtInst %half %32 FAbs %36
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.glsl
index 73fbba8..abeaaf9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.glsl
@@ -78,8 +78,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat2x4(v_1.inner[2].m_col0, v_1.inner[2].m_col1));
-  d(v_1.inner[0].m_col1.ywxz);
-  e(v_1.inner[0].m_col1.ywxz[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat2x4(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1));
+  d(v_1.inner[0u].m_col1.ywxz);
+  e(v_1.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.ir.msl
index 5e47561..d94254a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.spvasm
index f8806ee..0776b84 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 101
+; Bound: 99
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -80,11 +80,9 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
-      %int_0 = OpConstant %int 0
-         %93 = OpTypeFunction %S %S_std140
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
+         %91 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -143,35 +141,35 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v4half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v4half %77 None
-         %80 = OpCompositeConstruct %mat2v4half %76 %79
-         %81 = OpFunctionCall %void %c %80
-         %82 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v4half %82 None
-         %85 = OpVectorShuffle %v4half %84 %84 1 3 0 2
-         %86 = OpFunctionCall %void %d %85
-         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v4half %87 None
-         %89 = OpVectorShuffle %v4half %88 %88 1 3 0 2
-         %90 = OpCompositeExtract %half %89 0
-         %91 = OpFunctionCall %void %e %90
+         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v4half %77 None
+         %79 = OpCompositeConstruct %mat2v4half %76 %78
+         %80 = OpFunctionCall %void %c %79
+         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %82 = OpLoad %v4half %81 None
+         %83 = OpVectorShuffle %v4half %82 %82 1 3 0 2
+         %84 = OpFunctionCall %void %d %83
+         %85 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %86 = OpLoad %v4half %85 None
+         %87 = OpVectorShuffle %v4half %86 %86 1 3 0 2
+         %88 = OpCompositeExtract %half %87 0
+         %89 = OpFunctionCall %void %e %88
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %93
+%tint_convert_S = OpFunction %S None %91
  %tint_input = OpFunctionParameter %S_std140
-         %94 = OpLabel
-         %95 = OpCompositeExtract %int %tint_input 0
-         %96 = OpCompositeExtract %v4half %tint_input 1
-         %97 = OpCompositeExtract %v4half %tint_input 2
-         %98 = OpCompositeConstruct %mat2v4half %96 %97
-         %99 = OpCompositeExtract %int %tint_input 3
-        %100 = OpCompositeConstruct %S %95 %98 %99
-               OpReturnValue %100
+         %92 = OpLabel
+         %93 = OpCompositeExtract %int %tint_input 0
+         %94 = OpCompositeExtract %v4half %tint_input 1
+         %95 = OpCompositeExtract %v4half %tint_input 2
+         %96 = OpCompositeConstruct %mat2v4half %94 %95
+         %97 = OpCompositeExtract %int %tint_input 3
+         %98 = OpCompositeConstruct %S %93 %96 %97
+               OpReturnValue %98
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.glsl
index f97899b..2e1112e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.glsl
@@ -69,7 +69,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat2x4(v.inner[2].m_col0, v.inner[2].m_col1);
-  p[1].m[0] = v.inner[0].m_col1.ywxz;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat2x4(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  p[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index b022f37..e9fcaf5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -63,8 +63,8 @@
   S v_17[4] = v_12(0u);
   p = v_17;
   S v_18 = v_8(256u);
-  p[int(1)] = v_18;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  p[1u] = v_18;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.msl
index 5a67939..0e1c2ab 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.spvasm
index 847bace..4e3865e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 82
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -68,16 +68,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v4half = OpTypePointer Private %mat2v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v4half = OpTypePointer Private %mat2v4half
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-      %int_0 = OpConstant %int 0
-         %74 = OpTypeFunction %S %S_std140
+         %71 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -111,33 +108,33 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat2v4half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v4half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v4half %63 None
-         %66 = OpCompositeConstruct %mat2v4half %62 %65
-               OpStore %57 %66 None
-         %67 = OpAccessChain %_ptr_Private_v4half %p %int_1 %uint_1 %int_0
-         %70 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %71 = OpLoad %v4half %70 None
-         %72 = OpVectorShuffle %v4half %71 %71 1 3 0 2
-               OpStore %67 %72 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat2v4half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v4half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v4half %62 None
+         %64 = OpCompositeConstruct %mat2v4half %61 %63
+               OpStore %56 %64 None
+         %65 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_1 %uint_0
+         %67 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %68 = OpLoad %v4half %67 None
+         %69 = OpVectorShuffle %v4half %68 %68 1 3 0 2
+               OpStore %65 %69 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %74
+%tint_convert_S = OpFunction %S None %71
  %tint_input = OpFunctionParameter %S_std140
-         %75 = OpLabel
-         %76 = OpCompositeExtract %int %tint_input 0
-         %77 = OpCompositeExtract %v4half %tint_input 1
-         %78 = OpCompositeExtract %v4half %tint_input 2
-         %79 = OpCompositeConstruct %mat2v4half %77 %78
-         %80 = OpCompositeExtract %int %tint_input 3
-         %81 = OpCompositeConstruct %S %76 %79 %80
-               OpReturnValue %81
+         %72 = OpLabel
+         %73 = OpCompositeExtract %int %tint_input 0
+         %74 = OpCompositeExtract %v4half %tint_input 1
+         %75 = OpCompositeExtract %v4half %tint_input 2
+         %76 = OpCompositeConstruct %mat2v4half %74 %75
+         %77 = OpCompositeExtract %int %tint_input 3
+         %78 = OpCompositeConstruct %S %73 %76 %77
+               OpReturnValue %78
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.glsl
index a2c696e..a879546 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.glsl
@@ -120,8 +120,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat2x4(v.inner[2].m_col0, v.inner[2].m_col1);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.ywxz;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat2x4(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.ir.msl
index 4ae220e..6e0f92b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.msl
index 719237a..19d3045 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.spvasm
index 183fa84..0bc007a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 118
+; Bound: 114
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -81,19 +81,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-      %int_0 = OpConstant %int 0
-         %80 = OpTypeFunction %void %_arr_S_uint_4
-         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %76 = OpTypeFunction %void %_arr_S_uint_4
+         %95 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %110 = OpTypeFunction %S %S_std140
+        %106 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -127,80 +124,79 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v4half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v4half %69 None
-         %72 = OpCompositeConstruct %mat2v4half %68 %71
-               OpStore %63 %72 None
-         %73 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %int_1 %uint_1 %int_0
-         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %77 = OpLoad %v4half %76 None
-         %78 = OpVectorShuffle %v4half %77 %77 1 3 0 2
-               OpStore %73 %78 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v4half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v4half %67 None
+         %69 = OpCompositeConstruct %mat2v4half %66 %68
+               OpStore %61 %69 None
+         %70 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %72 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %73 = OpLoad %v4half %72 None
+         %74 = OpVectorShuffle %v4half %73 %73 1 3 0 2
+               OpStore %70 %74 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %80
+%tint_store_and_preserve_padding = OpFunction %void None %76
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %81 = OpLabel
-         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %82 %value_param
+         %77 = OpLabel
+         %78 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %78 %value_param
+               OpBranch %79
+         %79 = OpLabel
+               OpBranch %82
+         %82 = OpLabel
+         %84 = OpPhi %uint %uint_0 %79 %85 %81
+               OpLoopMerge %83 %81 None
+               OpBranch %80
+         %80 = OpLabel
+         %86 = OpUGreaterThanEqual %bool %84 %uint_4
+               OpSelectionMerge %87 None
+               OpBranchConditional %86 %88 %87
+         %88 = OpLabel
                OpBranch %83
-         %83 = OpLabel
-               OpBranch %86
-         %86 = OpLabel
-         %88 = OpPhi %uint %uint_0 %83 %89 %85
-               OpLoopMerge %87 %85 None
-               OpBranch %84
-         %84 = OpLabel
-         %90 = OpUGreaterThanEqual %bool %88 %uint_4
-               OpSelectionMerge %91 None
-               OpBranchConditional %90 %92 %91
-         %92 = OpLabel
-               OpBranch %87
-         %91 = OpLabel
-         %93 = OpAccessChain %_ptr_Function_S %82 %88
-         %94 = OpLoad %S %93 None
-         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
-         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
-               OpBranch %85
-         %85 = OpLabel
-         %89 = OpIAdd %uint %88 %uint_1
-               OpBranch %86
          %87 = OpLabel
+         %89 = OpAccessChain %_ptr_Function_S %78 %84
+         %90 = OpLoad %S %89 None
+         %91 = OpCompositeConstruct %_arr_uint_uint_1 %84
+         %92 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %91 %90
+               OpBranch %81
+         %81 = OpLabel
+         %85 = OpIAdd %uint %84 %uint_1
+               OpBranch %82
+         %83 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %99
+%tint_store_and_preserve_padding_0 = OpFunction %void None %95
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %100 = OpLabel
-        %101 = OpCompositeExtract %uint %target_indices 0
-        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
-        %104 = OpCompositeExtract %int %value_param_0 0
-               OpStore %102 %104 None
-        %105 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %11 %uint_0 %101 %uint_1
-        %106 = OpCompositeExtract %mat2v4half %value_param_0 1
-               OpStore %105 %106 None
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
-        %108 = OpCompositeExtract %int %value_param_0 2
-               OpStore %107 %108 None
+         %96 = OpLabel
+         %97 = OpCompositeExtract %uint %target_indices 0
+         %98 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_0
+        %100 = OpCompositeExtract %int %value_param_0 0
+               OpStore %98 %100 None
+        %101 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %11 %uint_0 %97 %uint_1
+        %102 = OpCompositeExtract %mat2v4half %value_param_0 1
+               OpStore %101 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %97 %uint_2
+        %104 = OpCompositeExtract %int %value_param_0 2
+               OpStore %103 %104 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %110
+%tint_convert_S = OpFunction %S None %106
  %tint_input = OpFunctionParameter %S_std140
-        %111 = OpLabel
-        %112 = OpCompositeExtract %int %tint_input 0
-        %113 = OpCompositeExtract %v4half %tint_input 1
-        %114 = OpCompositeExtract %v4half %tint_input 2
-        %115 = OpCompositeConstruct %mat2v4half %113 %114
-        %116 = OpCompositeExtract %int %tint_input 3
-        %117 = OpCompositeConstruct %S %112 %115 %116
-               OpReturnValue %117
+        %107 = OpLabel
+        %108 = OpCompositeExtract %int %tint_input 0
+        %109 = OpCompositeExtract %v4half %tint_input 1
+        %110 = OpCompositeExtract %v4half %tint_input 2
+        %111 = OpCompositeConstruct %mat2v4half %109 %110
+        %112 = OpCompositeExtract %int %tint_input 3
+        %113 = OpCompositeConstruct %S %108 %111 %112
+               OpReturnValue %113
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.glsl
index 33934c7..442738f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.glsl
@@ -84,9 +84,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat2x4(v.inner[2].m_col0, v.inner[2].m_col1);
-  w[1].m[0] = v.inner[0].m_col1.ywxz;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat2x4(v.inner[2u].m_col0, v.inner[2u].m_col1);
+  w[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 5fc23dd..614fbf1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -83,9 +83,9 @@
   S v_20[4] = v_12(0u);
   w = v_20;
   S v_21 = v_8(256u);
-  w[int(1)] = v_21;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  w[1u] = v_21;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
index 2af3623..22c10fe 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.msl
index 5ec10a2..a342e45 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
index 4d39b69..784069e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 101
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -77,16 +77,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v4half = OpTypePointer Workgroup %mat2v4half
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-      %int_0 = OpConstant %int 0
-         %91 = OpTypeFunction %void
-         %96 = OpTypeFunction %S %S_std140
+         %88 = OpTypeFunction %void
+         %93 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -143,39 +140,39 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat2v4half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v4half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %82 = OpLoad %v4half %81 None
-         %83 = OpCompositeConstruct %mat2v4half %80 %82
-               OpStore %75 %83 None
-         %84 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %uint_1 %int_0
-         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %88 = OpLoad %v4half %87 None
-         %89 = OpVectorShuffle %v4half %88 %88 1 3 0 2
-               OpStore %84 %89 None
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat2v4half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v4half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v4half %79 None
+         %81 = OpCompositeConstruct %mat2v4half %78 %80
+               OpStore %73 %81 None
+         %82 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_1 %uint_0
+         %84 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v4half %84 None
+         %86 = OpVectorShuffle %v4half %85 %85 1 3 0 2
+               OpStore %82 %86 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %91
-         %92 = OpLabel
-         %93 = OpLoad %uint %f_local_invocation_index_Input None
-         %94 = OpFunctionCall %void %f_inner %93
+          %f = OpFunction %void None %88
+         %89 = OpLabel
+         %90 = OpLoad %uint %f_local_invocation_index_Input None
+         %91 = OpFunctionCall %void %f_inner %90
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %93
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v4half %tint_input 1
-        %100 = OpCompositeExtract %v4half %tint_input 2
-        %101 = OpCompositeConstruct %mat2v4half %99 %100
-        %102 = OpCompositeExtract %int %tint_input 3
-        %103 = OpCompositeConstruct %S %98 %101 %102
-               OpReturnValue %103
+         %94 = OpLabel
+         %95 = OpCompositeExtract %int %tint_input 0
+         %96 = OpCompositeExtract %v4half %tint_input 1
+         %97 = OpCompositeExtract %v4half %tint_input 2
+         %98 = OpCompositeConstruct %mat2v4half %96 %97
+         %99 = OpCompositeExtract %int %tint_input 3
+        %100 = OpCompositeConstruct %S %95 %98 %99
+               OpReturnValue %100
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 935a5f9..4db8d20 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -59,17 +59,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_2 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 935a5f9..4db8d20 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -59,17 +59,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float2x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_2 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float2x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_2 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 1u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_2 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_3 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_3 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 1u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_3 / 4][scalar_offset_3 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index c114c20..8d38e28 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -28,14 +28,14 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
-  int v_2 = i();
-  int v_3 = i();
+  uint v_1 = min(uint(i()), 3u);
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 1u);
   Outer l_a[4] = v.inner;
   Outer l_a_i = v.inner[v_1];
   Inner l_a_i_a[4] = v.inner[v_1].a;
   Inner l_a_i_a_i = v.inner[v_1].a[v_2];
   mat2x4 l_a_i_a_i_m = v.inner[v_1].a[v_2].m;
   vec4 l_a_i_a_i_m_i = v.inner[v_1].a[v_2].m[v_3];
-  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][i()];
+  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 010532c..e6acc57 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float2x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 010532c..e6acc57 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 1u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float2x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 8fd4f70..69060ba 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float2x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 1u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float2x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index c34b3ef..989613c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 1u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   float2x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index d379a31..0c2651a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,10 +63,12 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
           %i = OpFunction %int None %18
@@ -80,21 +83,29 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %31
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %33
     %p_a_i_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_i %uint_0
-         %36 = OpFunctionCall %int %i
-  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %36
+         %40 = OpFunctionCall %int %i
+         %41 = OpBitcast %uint %40
+         %42 = OpExtInst %uint %34 UMin %41 %uint_3
+  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %42
 %p_a_i_a_i_m = OpAccessChain %_ptr_Uniform_mat2v4float %p_a_i_a_i %uint_0
-         %41 = OpFunctionCall %int %i
-%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %41
+         %47 = OpFunctionCall %int %i
+         %48 = OpBitcast %uint %47
+         %49 = OpExtInst %uint %34 UMin %48 %uint_1
+%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %49
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_i = OpLoad %Outer %p_a_i None
     %l_a_i_a = OpLoad %_arr_Inner_uint_4 %p_a_i_a None
   %l_a_i_a_i = OpLoad %Inner %p_a_i_a_i None
 %l_a_i_a_i_m = OpLoad %mat2v4float %p_a_i_a_i_m None
 %l_a_i_a_i_m_i = OpLoad %v4float %p_a_i_a_i_m_i None
-         %50 = OpFunctionCall %int %i
-         %51 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %50
-%l_a_i_a_i_m_i_i = OpLoad %float %51 None
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %34 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %61
+%l_a_i_a_i_m_i_i = OpLoad %float %62 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
index 3988ac7..3d4264f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -24,10 +24,10 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   Outer l_a[4] = v.inner;
-  Outer l_a_3 = v.inner[3];
-  Inner l_a_3_a[4] = v.inner[3].a;
-  Inner l_a_3_a_2 = v.inner[3].a[2];
-  mat2x4 l_a_3_a_2_m = v.inner[3].a[2].m;
-  vec4 l_a_3_a_2_m_1 = v.inner[3].a[2].m[1];
-  float l_a_3_a_2_m_1_0 = v.inner[3].a[2].m[1].x;
+  Outer l_a_3 = v.inner[3u];
+  Inner l_a_3_a[4] = v.inner[3u].a;
+  Inner l_a_3_a_2 = v.inner[3u].a[2u];
+  mat2x4 l_a_3_a_2_m = v.inner[3u].a[2u].m;
+  vec4 l_a_3_a_2_m_1 = v.inner[3u].a[2u].m[1u];
+  float l_a_3_a_2_m_1_0 = v.inner[3u].a[2u].m[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index b54f1c4..a70a451 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float2x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float2x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index ba9cd3c..65ba30d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,31 +55,29 @@
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
-      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %int_3
+      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %uint_3
     %p_a_3_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_3 %uint_0
-  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %int_2
+  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %uint_2
 %p_a_3_a_2_m = OpAccessChain %_ptr_Uniform_mat2v4float %p_a_3_a_2 %uint_0
-%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %int_1
+%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %uint_1
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_3 = OpLoad %Outer %p_a_3 None
     %l_a_3_a = OpLoad %_arr_Inner_uint_4 %p_a_3_a None
   %l_a_3_a_2 = OpLoad %Inner %p_a_3_a_2 None
 %l_a_3_a_2_m = OpLoad %mat2v4float %p_a_3_a_2_m None
 %l_a_3_a_2_m_1 = OpLoad %v4float %p_a_3_a_2_m_1 None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %int_0
-%l_a_3_a_2_m_1_0 = OpLoad %float %40 None
+         %39 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %uint_0
+%l_a_3_a_2_m_1_0 = OpLoad %float %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.glsl
index 71ff87a..d7e9b7e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.glsl
@@ -35,7 +35,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x2 t = transpose(v.inner[2].m);
-  float l = length(v.inner[0].m[1].ywxz);
-  float a = abs(v.inner[0].m[1].ywxz[0u]);
+  mat4x2 t = transpose(v.inner[2u].m);
+  float l = length(v.inner[0u].m[1u].ywxz);
+  float a = abs(v.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
index e769daa..b608020 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float4x2 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  float4x2 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.spvasm
index e043008..a97ddf4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
-         %32 = OpExtInstImport "GLSL.std.450"
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -44,26 +44,24 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
     %v2float = OpTypeVector %float 2
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2 %uint_1
+         %16 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2 %uint_1
          %21 = OpLoad %mat2v4float %16 None
           %t = OpTranspose %mat4v2float %21
-         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %29 = OpLoad %v4float %25 None
-         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
-          %l = OpExtInst %float %32 Length %30
-         %33 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %34 = OpLoad %v4float %33 None
-         %35 = OpVectorShuffle %v4float %34 %34 1 3 0 2
-         %36 = OpCompositeExtract %float %35 0
-          %a = OpExtInst %float %32 FAbs %36
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %27 = OpLoad %v4float %25 None
+         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
+          %l = OpExtInst %float %30 Length %28
+         %31 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %32 = OpLoad %v4float %31 None
+         %33 = OpVectorShuffle %v4float %32 %32 1 3 0 2
+         %34 = OpCompositeExtract %float %33 0
+          %a = OpExtInst %float %30 FAbs %34
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.glsl
index a12b5fc..f32af1c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.glsl
@@ -46,8 +46,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[2]);
-  c(v_1.inner[2].m);
-  d(v_1.inner[0].m[1].ywxz);
-  e(v_1.inner[0].m[1].ywxz[0u]);
+  b(v_1.inner[2u]);
+  c(v_1.inner[2u].m);
+  d(v_1.inner[0u].m[1u].ywxz);
+  e(v_1.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.ir.msl
index a872ae8..af2f037 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.spvasm
index a530203..ccb4dda 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -56,12 +56,10 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %a = OpFunction %void None %15
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %16 = OpLabel
@@ -92,20 +90,20 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_S_uint_4 %36 None
          %40 = OpFunctionCall %void %a %39
-         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %44 = OpLoad %S %41 None
          %45 = OpFunctionCall %void %b %44
-         %46 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2 %uint_1
+         %46 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2 %uint_1
          %49 = OpLoad %mat2v4float %46 None
          %50 = OpFunctionCall %void %c %49
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %55 = OpLoad %v4float %51 None
-         %56 = OpVectorShuffle %v4float %55 %55 1 3 0 2
-         %57 = OpFunctionCall %void %d %56
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %59 = OpLoad %v4float %58 None
-         %60 = OpVectorShuffle %v4float %59 %59 1 3 0 2
-         %61 = OpCompositeExtract %float %60 0
-         %62 = OpFunctionCall %void %e %61
+         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %53 = OpLoad %v4float %51 None
+         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
+         %55 = OpFunctionCall %void %d %54
+         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %56 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+         %59 = OpCompositeExtract %float %58 0
+         %60 = OpFunctionCall %void %e %59
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.glsl
index 80bc319..4561002 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.glsl
@@ -37,7 +37,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[3].m = v.inner[2].m;
-  p[1].m[0] = v.inner[0].m[1].ywxz;
+  p[1u] = v.inner[2u];
+  p[3u].m = v.inner[2u].m;
+  p[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index cf77f35..97cca24 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index cf77f35..97cca24 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.msl
index dc401fb..950e7f0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.spvasm
index d324083..1f717de 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,33 +45,31 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
-%_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat2v4float = OpTypePointer Private %mat2v4float
-      %int_3 = OpConstant %int 3
      %uint_1 = OpConstant %uint 1
+%_ptr_Uniform_S = OpTypePointer Uniform %S
+     %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat2v4float = OpTypePointer Private %mat2v4float
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_S %p %int_1
-         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %23 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %29 = OpLoad %S %26 None
                OpStore %23 %29 None
-         %30 = OpAccessChain %_ptr_Private_mat2v4float %p %int_3 %uint_1
-         %34 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2 %uint_1
-         %36 = OpLoad %mat2v4float %34 None
-               OpStore %30 %36 None
-         %37 = OpAccessChain %_ptr_Private_v4float %p %int_1 %uint_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %42 = OpLoad %v4float %40 None
-         %43 = OpVectorShuffle %v4float %42 %42 1 3 0 2
-               OpStore %37 %43 None
+         %30 = OpAccessChain %_ptr_Private_mat2v4float %p %uint_3 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2 %uint_1
+         %35 = OpLoad %mat2v4float %33 None
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %40 = OpLoad %v4float %38 None
+         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
+               OpStore %36 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.glsl
index 409c768..0ed5977 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.glsl
@@ -62,8 +62,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(v.inner);
-  S v_4 = v.inner[2];
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_4);
-  v_1.inner[3].m = v.inner[2].m;
-  v_1.inner[1].m[0] = v.inner[0].m[1].ywxz;
+  S v_4 = v.inner[2u];
+  tint_store_and_preserve_padding_1(uint[1](1u), v_4);
+  v_1.inner[3u].m = v.inner[2u].m;
+  v_1.inner[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.ir.msl
index 64214a6..0dcf5fe 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.msl
index 52d9404..ba651a5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.spvasm
index 52a2bd2..af47523 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -57,87 +57,83 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %50 = OpTypeFunction %void %_arr_S_uint_4
+         %47 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
        %bool = OpTypeBool
 %_ptr_Function_S = OpTypePointer Function %S
-         %72 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %69 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-     %uint_2 = OpConstant %uint 2
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
          %23 = OpFunctionCall %void %tint_store_and_preserve_padding %22
-         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %28 = OpLoad %S %25 None
-         %29 = OpBitcast %uint %int_1
-         %33 = OpCompositeConstruct %_arr_uint_uint_1 %29
-         %34 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %33 %28
-         %36 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %12 %uint_0 %int_3 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2 %uint_1
-         %41 = OpLoad %mat2v4float %39 None
-               OpStore %36 %41 None
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %int_1 %uint_1 %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %47 = OpLoad %v4float %45 None
-         %48 = OpVectorShuffle %v4float %47 %47 1 3 0 2
-               OpStore %42 %48 None
+         %31 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %32 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %31 %28
+         %34 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %12 %uint_0 %uint_3 %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2 %uint_1
+         %39 = OpLoad %mat2v4float %37 None
+               OpStore %34 %39 None
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %uint_1 %uint_1 %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %44 = OpLoad %v4float %42 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+               OpStore %40 %45 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %50
+%tint_store_and_preserve_padding = OpFunction %void None %47
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %48 = OpLabel
+         %49 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %49 %value_param
+               OpBranch %51
          %51 = OpLabel
-         %52 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %52 %value_param
                OpBranch %54
          %54 = OpLabel
-               OpBranch %57
-         %57 = OpLabel
-         %59 = OpPhi %uint %uint_0 %54 %60 %56
-               OpLoopMerge %58 %56 None
+         %56 = OpPhi %uint %uint_0 %51 %57 %53
+               OpLoopMerge %55 %53 None
+               OpBranch %52
+         %52 = OpLabel
+         %58 = OpUGreaterThanEqual %bool %56 %uint_4
+               OpSelectionMerge %60 None
+               OpBranchConditional %58 %61 %60
+         %61 = OpLabel
                OpBranch %55
+         %60 = OpLabel
+         %62 = OpAccessChain %_ptr_Function_S %49 %56
+         %64 = OpLoad %S %62 None
+         %65 = OpCompositeConstruct %_arr_uint_uint_1 %56
+         %66 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %65 %64
+               OpBranch %53
+         %53 = OpLabel
+         %57 = OpIAdd %uint %56 %uint_1
+               OpBranch %54
          %55 = OpLabel
-         %61 = OpUGreaterThanEqual %bool %59 %uint_4
-               OpSelectionMerge %63 None
-               OpBranchConditional %61 %64 %63
-         %64 = OpLabel
-               OpBranch %58
-         %63 = OpLabel
-         %65 = OpAccessChain %_ptr_Function_S %52 %59
-         %67 = OpLoad %S %65 None
-         %68 = OpCompositeConstruct %_arr_uint_uint_1 %59
-         %69 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %68 %67
-               OpBranch %56
-         %56 = OpLabel
-         %60 = OpIAdd %uint %59 %uint_1
-               OpBranch %57
-         %58 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %72
+%tint_store_and_preserve_padding_0 = OpFunction %void None %69
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-         %73 = OpLabel
-         %74 = OpCompositeExtract %uint %target_indices 0
-         %75 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_0
-         %77 = OpCompositeExtract %int %value_param_0 0
-               OpStore %75 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %12 %uint_0 %74 %uint_1
-         %79 = OpCompositeExtract %mat2v4float %value_param_0 1
-               OpStore %78 %79 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_2
-         %82 = OpCompositeExtract %int %value_param_0 2
-               OpStore %80 %82 None
+         %70 = OpLabel
+         %71 = OpCompositeExtract %uint %target_indices 0
+         %72 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_0
+         %74 = OpCompositeExtract %int %value_param_0 0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %12 %uint_0 %71 %uint_1
+         %76 = OpCompositeExtract %mat2v4float %value_param_0 1
+               OpStore %75 %76 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_2
+         %78 = OpCompositeExtract %int %value_param_0 2
+               OpStore %77 %78 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.glsl
index 1213a03..abb342b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.glsl
@@ -52,9 +52,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[3].m = v.inner[2].m;
-  w[1].m[0] = v.inner[0].m[1].ywxz;
+  w[1u] = v.inner[2u];
+  w[3u].m = v.inner[2u].m;
+  w[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 85949a0..2594a4f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 85949a0..2594a4f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
index 21c7386..e3e8b78 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.msl
index ec95a36..cb2a119 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
index 6366b66..80035e4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,16 +55,13 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat2v4float = OpTypePointer Workgroup %mat2v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %63 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -93,24 +90,24 @@
          %39 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %42 = OpLoad %_arr_S_uint_4 %39 None
                OpStore %w %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
-         %48 = OpLoad %S %45 None
-               OpStore %43 %48 None
-         %49 = OpAccessChain %_ptr_Workgroup_mat2v4float %w %int_3 %uint_1
-         %52 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %int_2 %uint_1
-         %54 = OpLoad %mat2v4float %52 None
-               OpStore %49 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %uint_1 %int_0
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %60 = OpLoad %v4float %58 None
-         %61 = OpVectorShuffle %v4float %60 %60 1 3 0 2
-               OpStore %55 %61 None
+         %43 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %44 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
+         %46 = OpLoad %S %44 None
+               OpStore %43 %46 None
+         %47 = OpAccessChain %_ptr_Workgroup_mat2v4float %w %uint_3 %uint_1
+         %50 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0 %uint_2 %uint_1
+         %52 = OpLoad %mat2v4float %50 None
+               OpStore %47 %52 None
+         %53 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_1 %uint_0
+         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %55 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+               OpStore %53 %58 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpLoad %uint %f_local_invocation_index_Input None
+         %63 = OpFunctionCall %void %f_inner %62
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 29a7ac9..5733ef1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -63,18 +63,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 3, 2> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (4u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 3, 2> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (4u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   uint ubo_load_3 = a[scalar_offset_3 / 4][scalar_offset_3 % 4];
   vector<float16_t, 2> l_a_i_a_i_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_3 & 0xFFFF)), float16_t(f16tof32(ubo_load_3 >> 16)));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (4u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (4u * min(uint(tint_symbol_2), 2u))) + (2u * min(uint(tint_symbol_3), 1u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 1c3c492..6d0584e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -66,10 +66,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat3x2 v_6 = f16mat3x2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2);
-  f16vec2 v_7 = v_6[i()];
+  f16vec2 v_7 = v_6[min(uint(i()), 2u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -110,5 +110,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat3x2 l_a_i_a_i_m = v_6;
   f16vec2 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index e71db93..e596103 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -89,16 +89,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_20 = (256u * uint(i()));
-  uint v_21 = (64u * uint(i()));
-  uint v_22 = (4u * uint(i()));
+  uint v_20 = (256u * uint(min(uint(i()), 3u)));
+  uint v_21 = (64u * uint(min(uint(i()), 3u)));
+  uint v_22 = (4u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_15(0u);
   Outer l_a_i = v_12(v_20);
   Inner l_a_i_a[4] = v_7(v_20);
   Inner l_a_i_a_i = v_5((v_20 + v_21));
   matrix<float16_t, 3, 2> l_a_i_a_i_m = v_2((v_20 + v_21));
   vector<float16_t, 2> l_a_i_a_i_m_i = tint_bitcast_to_f16(a[(((v_20 + v_21) + v_22) / 16u)][((((v_20 + v_21) + v_22) % 16u) / 4u)]);
-  uint v_23 = (((v_20 + v_21) + v_22) + (uint(i()) * 2u));
+  uint v_23 = (((v_20 + v_21) + v_22) + (uint(min(uint(i()), 1u)) * 2u));
   uint v_24 = a[(v_23 / 16u)][((v_23 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_24 >> ((((v_23 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index f228d84..46abd0e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half3x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half3x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 0cf5a40..d4cd358 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half3x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 3155f53..c3a9f48 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 144
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -74,6 +75,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -89,17 +91,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %64 = OpConstantNull %_arr_Outer_uint_4
+         %72 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %91 = OpConstantNull %_arr_Inner_uint_4
+         %99 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %115 = OpTypeFunction %Inner %Inner_std140
-        %123 = OpTypeFunction %Outer %Outer_std140
+        %125 = OpTypeFunction %Inner %Inner_std140
+        %133 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -110,132 +112,140 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %49 = OpVariable %_ptr_Function_mat3v2half Function
-         %56 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %58 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %64
-         %87 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %89 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
+         %55 = OpVariable %_ptr_Function_mat3v2half Function
+         %64 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %72
+         %95 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %97 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_0
-         %40 = OpLoad %v2half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_1
-         %43 = OpLoad %v2half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_0
          %46 = OpLoad %v2half %44 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat3v2half %40 %43 %46
-               OpStore %49 %l_a_i_a_i_m
-         %51 = OpFunctionCall %int %i
-         %52 = OpAccessChain %_ptr_Function_v2half %49 %51
-%l_a_i_a_i_m_i = OpLoad %v2half %52 None
-         %55 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %56 %55
-               OpBranch %65
-         %65 = OpLabel
-               OpBranch %68
-         %68 = OpLabel
-         %70 = OpPhi %uint %uint_0 %65 %71 %67
-               OpLoopMerge %69 %67 None
-               OpBranch %66
-         %66 = OpLabel
-         %72 = OpUGreaterThanEqual %bool %70 %uint_4
-               OpSelectionMerge %74 None
-               OpBranchConditional %72 %75 %74
-         %75 = OpLabel
-               OpBranch %69
+         %47 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_1
+         %49 = OpLoad %v2half %47 None
+         %50 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_2
+         %52 = OpLoad %v2half %50 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat3v2half %46 %49 %52
+               OpStore %55 %l_a_i_a_i_m
+         %57 = OpFunctionCall %int %i
+         %58 = OpBitcast %uint %57
+         %59 = OpExtInst %uint %33 UMin %58 %uint_2
+         %60 = OpAccessChain %_ptr_Function_v2half %55 %59
+%l_a_i_a_i_m_i = OpLoad %v2half %60 None
+         %63 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %64 %63
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %76
+         %76 = OpLabel
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
          %74 = OpLabel
-         %76 = OpAccessChain %_ptr_Function_Outer %58 %70
-         %78 = OpAccessChain %_ptr_Function_Outer_std140 %56 %70
-         %80 = OpLoad %Outer_std140 %78 None
-         %81 = OpFunctionCall %Outer %tint_convert_Outer %80
-               OpStore %76 %81 None
-               OpBranch %67
-         %67 = OpLabel
-         %71 = OpIAdd %uint %70 %uint_1
-               OpBranch %68
-         %69 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %58 None
-         %84 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %84
-         %86 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %87 %86
-               OpBranch %92
-         %92 = OpLabel
-               OpBranch %95
-         %95 = OpLabel
-         %97 = OpPhi %uint %uint_0 %92 %98 %94
-               OpLoopMerge %96 %94 None
-               OpBranch %93
-         %93 = OpLabel
-         %99 = OpUGreaterThanEqual %bool %97 %uint_4
-               OpSelectionMerge %100 None
-               OpBranchConditional %99 %101 %100
-        %101 = OpLabel
-               OpBranch %96
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %82 None
+               OpBranchConditional %80 %83 %82
+         %83 = OpLabel
+               OpBranch %77
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Function_Outer %66 %78
+         %86 = OpAccessChain %_ptr_Function_Outer_std140 %64 %78
+         %88 = OpLoad %Outer_std140 %86 None
+         %89 = OpFunctionCall %Outer %tint_convert_Outer %88
+               OpStore %84 %89 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %66 None
+         %92 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %92
+         %94 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %95 %94
+               OpBranch %100
         %100 = OpLabel
-        %102 = OpAccessChain %_ptr_Function_Inner %89 %97
-        %104 = OpAccessChain %_ptr_Function_Inner_std140 %87 %97
-        %106 = OpLoad %Inner_std140 %104 None
-        %107 = OpFunctionCall %Inner %tint_convert_Inner %106
-               OpStore %102 %107 None
-               OpBranch %94
-         %94 = OpLabel
-         %98 = OpIAdd %uint %97 %uint_1
-               OpBranch %95
-         %96 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %89 None
-        %110 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %110
-        %112 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %112
+               OpBranch %103
+        %103 = OpLabel
+        %105 = OpPhi %uint %uint_0 %100 %106 %102
+               OpLoopMerge %104 %102 None
+               OpBranch %101
+        %101 = OpLabel
+        %107 = OpUGreaterThanEqual %bool %105 %uint_4
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %108
+        %109 = OpLabel
+               OpBranch %104
+        %108 = OpLabel
+        %110 = OpAccessChain %_ptr_Function_Inner %97 %105
+        %112 = OpAccessChain %_ptr_Function_Inner_std140 %95 %105
+        %114 = OpLoad %Inner_std140 %112 None
+        %115 = OpFunctionCall %Inner %tint_convert_Inner %114
+               OpStore %110 %115 None
+               OpBranch %102
+        %102 = OpLabel
+        %106 = OpIAdd %uint %105 %uint_1
+               OpBranch %103
+        %104 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %97 None
+        %118 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %118
+        %120 = OpFunctionCall %int %i
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %33 UMin %121 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %122
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %115
+%tint_convert_Inner = OpFunction %Inner None %125
  %tint_input = OpFunctionParameter %Inner_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %v2half %tint_input 0
-        %118 = OpCompositeExtract %v2half %tint_input 1
-        %119 = OpCompositeExtract %v2half %tint_input 2
-        %120 = OpCompositeConstruct %mat3v2half %117 %118 %119
-        %121 = OpCompositeConstruct %Inner %120
-               OpReturnValue %121
+        %126 = OpLabel
+        %127 = OpCompositeExtract %v2half %tint_input 0
+        %128 = OpCompositeExtract %v2half %tint_input 1
+        %129 = OpCompositeExtract %v2half %tint_input 2
+        %130 = OpCompositeConstruct %mat3v2half %127 %128 %129
+        %131 = OpCompositeConstruct %Inner %130
+               OpReturnValue %131
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %123
+%tint_convert_Outer = OpFunction %Outer None %133
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %124 = OpLabel
-        %126 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %127 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
-        %125 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %126 %125
-               OpBranch %128
-        %128 = OpLabel
-               OpBranch %131
-        %131 = OpLabel
-        %133 = OpPhi %uint %uint_0 %128 %134 %130
-               OpLoopMerge %132 %130 None
-               OpBranch %129
-        %129 = OpLabel
-        %135 = OpUGreaterThanEqual %bool %133 %uint_4
-               OpSelectionMerge %136 None
-               OpBranchConditional %135 %137 %136
-        %137 = OpLabel
-               OpBranch %132
-        %136 = OpLabel
-        %138 = OpAccessChain %_ptr_Function_Inner %127 %133
-        %139 = OpAccessChain %_ptr_Function_Inner_std140 %126 %133
-        %140 = OpLoad %Inner_std140 %139 None
-        %141 = OpFunctionCall %Inner %tint_convert_Inner %140
-               OpStore %138 %141 None
-               OpBranch %130
-        %130 = OpLabel
-        %134 = OpIAdd %uint %133 %uint_1
-               OpBranch %131
-        %132 = OpLabel
-        %142 = OpLoad %_arr_Inner_uint_4 %127 None
-        %143 = OpCompositeConstruct %Outer %142
-               OpReturnValue %143
+        %134 = OpLabel
+        %136 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %137 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
+        %135 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %136 %135
+               OpBranch %138
+        %138 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+        %143 = OpPhi %uint %uint_0 %138 %144 %140
+               OpLoopMerge %142 %140 None
+               OpBranch %139
+        %139 = OpLabel
+        %145 = OpUGreaterThanEqual %bool %143 %uint_4
+               OpSelectionMerge %146 None
+               OpBranchConditional %145 %147 %146
+        %147 = OpLabel
+               OpBranch %142
+        %146 = OpLabel
+        %148 = OpAccessChain %_ptr_Function_Inner %137 %143
+        %149 = OpAccessChain %_ptr_Function_Inner_std140 %136 %143
+        %150 = OpLoad %Inner_std140 %149 None
+        %151 = OpFunctionCall %Inner %tint_convert_Inner %150
+               OpStore %148 %151 None
+               OpBranch %140
+        %140 = OpLabel
+        %144 = OpIAdd %uint %143 %uint_1
+               OpBranch %141
+        %142 = OpLabel
+        %152 = OpLoad %_arr_Inner_uint_4 %137 None
+        %153 = OpCompositeConstruct %Outer %152
+               OpReturnValue %153
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 5b755fe..4e93b67 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -61,7 +61,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x2 v_4 = f16mat3x2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2);
+  f16mat3x2 v_4 = f16mat3x2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -80,8 +80,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat3x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))));
   {
     uint v_11 = 0u;
@@ -99,8 +99,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat3x2 l_a_3_a_2_m = v_4;
-  f16vec2 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index c45a971..24ac192 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half3x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half3x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.spvasm
index 36c6005..cc26f92 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 128
+; Bound: 126
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -67,14 +67,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
  %mat3v2half = OpTypeMatrix %v2half 3
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat3v2half
@@ -82,138 +80,138 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %49 = OpConstantNull %_arr_Outer_uint_4
+         %47 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %76 = OpConstantNull %_arr_Inner_uint_4
+         %74 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %99 = OpTypeFunction %Inner %Inner_std140
-        %107 = OpTypeFunction %Outer %Outer_std140
+         %97 = OpTypeFunction %Inner %Inner_std140
+        %105 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
-         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+         %39 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %41 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %47
+         %70 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %72 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_0
-         %30 = OpLoad %v2half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_1
-         %33 = OpLoad %v2half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_2
-         %36 = OpLoad %v2half %34 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat3v2half %30 %33 %36
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_0
+         %29 = OpLoad %v2half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_1
+         %32 = OpLoad %v2half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_2
+         %34 = OpLoad %v2half %33 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat3v2half %29 %32 %34
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2half %l_a_3_a_2_m 1
-         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %41 %40
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %53
-         %53 = OpLabel
-         %55 = OpPhi %uint %uint_0 %50 %56 %52
-               OpLoopMerge %54 %52 None
+         %38 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %39 %38
+               OpBranch %48
+         %48 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %57 = OpUGreaterThanEqual %bool %55 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %60 %59
-         %60 = OpLabel
-               OpBranch %54
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
-         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
-         %65 = OpLoad %Outer_std140 %63 None
-         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
-               OpStore %61 %66 None
+         %53 = OpPhi %uint %uint_0 %48 %54 %50
+               OpLoopMerge %52 %50 None
+               OpBranch %49
+         %49 = OpLabel
+         %55 = OpUGreaterThanEqual %bool %53 %uint_4
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %58 %57
+         %58 = OpLabel
                OpBranch %52
+         %57 = OpLabel
+         %59 = OpAccessChain %_ptr_Function_Outer %41 %53
+         %61 = OpAccessChain %_ptr_Function_Outer_std140 %39 %53
+         %63 = OpLoad %Outer_std140 %61 None
+         %64 = OpFunctionCall %Outer %tint_convert_Outer %63
+               OpStore %59 %64 None
+               OpBranch %50
+         %50 = OpLabel
+         %54 = OpIAdd %uint %53 %uint_1
+               OpBranch %51
          %52 = OpLabel
-         %56 = OpIAdd %uint %55 %uint_1
-               OpBranch %53
-         %54 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
-         %69 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
-         %71 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %72 %71
-               OpBranch %77
-         %77 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %82 = OpPhi %uint %uint_0 %77 %83 %79
-               OpLoopMerge %81 %79 None
+        %l_a = OpLoad %_arr_Outer_uint_4 %41 None
+         %67 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %67
+         %69 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %70 %69
+               OpBranch %75
+         %75 = OpLabel
                OpBranch %78
          %78 = OpLabel
-         %84 = OpUGreaterThanEqual %bool %82 %uint_4
-               OpSelectionMerge %85 None
-               OpBranchConditional %84 %86 %85
-         %86 = OpLabel
-               OpBranch %81
-         %85 = OpLabel
-         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
-         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
-         %91 = OpLoad %Inner_std140 %89 None
-         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
-               OpStore %87 %92 None
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %83 None
+               OpBranchConditional %82 %84 %83
+         %84 = OpLabel
                OpBranch %79
+         %83 = OpLabel
+         %85 = OpAccessChain %_ptr_Function_Inner %72 %80
+         %87 = OpAccessChain %_ptr_Function_Inner_std140 %70 %80
+         %89 = OpLoad %Inner_std140 %87 None
+         %90 = OpFunctionCall %Inner %tint_convert_Inner %89
+               OpStore %85 %90 None
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
          %79 = OpLabel
-         %83 = OpIAdd %uint %82 %uint_1
-               OpBranch %80
-         %81 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
-         %95 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %72 None
+         %93 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %93
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %99
+%tint_convert_Inner = OpFunction %Inner None %97
  %tint_input = OpFunctionParameter %Inner_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %v2half %tint_input 0
-        %102 = OpCompositeExtract %v2half %tint_input 1
-        %103 = OpCompositeExtract %v2half %tint_input 2
-        %104 = OpCompositeConstruct %mat3v2half %101 %102 %103
-        %105 = OpCompositeConstruct %Inner %104
-               OpReturnValue %105
+         %98 = OpLabel
+         %99 = OpCompositeExtract %v2half %tint_input 0
+        %100 = OpCompositeExtract %v2half %tint_input 1
+        %101 = OpCompositeExtract %v2half %tint_input 2
+        %102 = OpCompositeConstruct %mat3v2half %99 %100 %101
+        %103 = OpCompositeConstruct %Inner %102
+               OpReturnValue %103
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %107
+%tint_convert_Outer = OpFunction %Outer None %105
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %108 = OpLabel
-        %110 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %111 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
-        %109 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %110 %109
-               OpBranch %112
-        %112 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %117 = OpPhi %uint %uint_0 %112 %118 %114
-               OpLoopMerge %116 %114 None
+        %106 = OpLabel
+        %108 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %109 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
+        %107 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %108 %107
+               OpBranch %110
+        %110 = OpLabel
                OpBranch %113
         %113 = OpLabel
-        %119 = OpUGreaterThanEqual %bool %117 %uint_4
-               OpSelectionMerge %120 None
-               OpBranchConditional %119 %121 %120
-        %121 = OpLabel
-               OpBranch %116
-        %120 = OpLabel
-        %122 = OpAccessChain %_ptr_Function_Inner %111 %117
-        %123 = OpAccessChain %_ptr_Function_Inner_std140 %110 %117
-        %124 = OpLoad %Inner_std140 %123 None
-        %125 = OpFunctionCall %Inner %tint_convert_Inner %124
-               OpStore %122 %125 None
+        %115 = OpPhi %uint %uint_0 %110 %116 %112
+               OpLoopMerge %114 %112 None
+               OpBranch %111
+        %111 = OpLabel
+        %117 = OpUGreaterThanEqual %bool %115 %uint_4
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpBranch %114
+        %118 = OpLabel
+        %120 = OpAccessChain %_ptr_Function_Inner %109 %115
+        %121 = OpAccessChain %_ptr_Function_Inner_std140 %108 %115
+        %122 = OpLoad %Inner_std140 %121 None
+        %123 = OpFunctionCall %Inner %tint_convert_Inner %122
+               OpStore %120 %123 None
+               OpBranch %112
+        %112 = OpLabel
+        %116 = OpIAdd %uint %115 %uint_1
+               OpBranch %113
         %114 = OpLabel
-        %118 = OpIAdd %uint %117 %uint_1
-               OpBranch %115
-        %116 = OpLabel
-        %126 = OpLoad %_arr_Inner_uint_4 %111 None
-        %127 = OpCompositeConstruct %Outer %126
-               OpReturnValue %127
+        %124 = OpLoad %_arr_Inner_uint_4 %109 None
+        %125 = OpCompositeConstruct %Outer %124
+               OpReturnValue %125
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.glsl
index 797df5f..79c4378 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.glsl
@@ -43,7 +43,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x3 t = transpose(f16mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2));
-  float16_t l = length(v.inner[0].m_col1.yx);
-  float16_t a = abs(v.inner[0].m_col1.yx[0u]);
+  f16mat2x3 t = transpose(f16mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2));
+  float16_t l = length(v.inner[0u].m_col1.yx);
+  float16_t a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
index 72493af..ea294b9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -27,7 +27,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half2x3 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].yx);
-  half const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  half2x3 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.spvasm
index 4510614..cc24717 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %37 = OpExtInstImport "GLSL.std.450"
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -48,32 +48,30 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat3v2half = OpTypeMatrix %v2half 3
      %v3half = OpTypeVector %half 3
  %mat2v3half = OpTypeMatrix %v3half 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v2half %24 None
-         %28 = OpCompositeConstruct %mat3v2half %20 %23 %26
-          %t = OpTranspose %mat2v3half %28
-         %32 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v2half %32 None
-         %35 = OpVectorShuffle %v2half %34 %34 1 0
-          %l = OpExtInst %half %37 Length %35
-         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %39 = OpLoad %v2half %38 None
-         %40 = OpVectorShuffle %v2half %39 %39 1 0
-         %41 = OpCompositeExtract %half %40 0
-          %a = OpExtInst %half %37 FAbs %41
+         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v2half %23 None
+         %27 = OpCompositeConstruct %mat3v2half %20 %22 %25
+          %t = OpTranspose %mat2v3half %27
+         %31 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v2half %31 None
+         %33 = OpVectorShuffle %v2half %32 %32 1 0
+          %l = OpExtInst %half %35 Length %33
+         %36 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %37 = OpLoad %v2half %36 None
+         %38 = OpVectorShuffle %v2half %37 %37 1 0
+         %39 = OpCompositeExtract %half %38 0
+          %a = OpExtInst %half %35 FAbs %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.glsl
index 73fee1c..8c70031 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.glsl
@@ -80,8 +80,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat3x2(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat3x2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.ir.msl
index 93c9bdf..45c5061 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.ir.msl
@@ -43,8 +43,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.spvasm
index 709ffe88734..cdb3332 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 103
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -82,12 +82,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %S %S_std140
+         %94 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -146,38 +144,38 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2half %80 None
-         %83 = OpCompositeConstruct %mat3v2half %76 %79 %82
-         %84 = OpFunctionCall %void %c %83
-         %85 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %87 = OpLoad %v2half %85 None
-         %88 = OpVectorShuffle %v2half %87 %87 1 0
-         %89 = OpFunctionCall %void %d %88
-         %90 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v2half %90 None
-         %92 = OpVectorShuffle %v2half %91 %91 1 0
-         %93 = OpCompositeExtract %half %92 0
-         %94 = OpFunctionCall %void %e %93
+         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v2half %79 None
+         %82 = OpCompositeConstruct %mat3v2half %76 %78 %81
+         %83 = OpFunctionCall %void %c %82
+         %84 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v2half %84 None
+         %86 = OpVectorShuffle %v2half %85 %85 1 0
+         %87 = OpFunctionCall %void %d %86
+         %88 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v2half %88 None
+         %90 = OpVectorShuffle %v2half %89 %89 1 0
+         %91 = OpCompositeExtract %half %90 0
+         %92 = OpFunctionCall %void %e %91
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %94
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v2half %tint_input 1
-        %100 = OpCompositeExtract %v2half %tint_input 2
-        %101 = OpCompositeExtract %v2half %tint_input 3
-        %102 = OpCompositeConstruct %mat3v2half %99 %100 %101
-        %103 = OpCompositeExtract %int %tint_input 4
-        %104 = OpCompositeConstruct %S %98 %102 %103
-               OpReturnValue %104
+         %95 = OpLabel
+         %96 = OpCompositeExtract %int %tint_input 0
+         %97 = OpCompositeExtract %v2half %tint_input 1
+         %98 = OpCompositeExtract %v2half %tint_input 2
+         %99 = OpCompositeExtract %v2half %tint_input 3
+        %100 = OpCompositeConstruct %mat3v2half %97 %98 %99
+        %101 = OpCompositeExtract %int %tint_input 4
+        %102 = OpCompositeConstruct %S %96 %100 %101
+               OpReturnValue %102
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.glsl
index 3cb6992..84d5de7 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.glsl
@@ -71,7 +71,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 5717624..8f7ae27 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -58,8 +58,8 @@
   S v_14[4] = v_9(0u);
   p = v_14;
   S v_15 = v_5(256u);
-  p[int(1)] = v_15;
-  p[int(3)].m = v_2(260u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  p[1u] = v_15;
+  p[3u].m = v_2(260u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.msl
index 778c53d..49ded46 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.spvasm
index 0a92d27..1ec095f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 86
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,17 +70,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v2half = OpTypePointer Private %mat3v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v2half = OpTypePointer Private %mat3v2half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-      %int_0 = OpConstant %int 0
-         %77 = OpTypeFunction %S %S_std140
+         %73 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -114,36 +110,36 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat3v2half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2half %66 None
-         %69 = OpCompositeConstruct %mat3v2half %62 %65 %68
-               OpStore %57 %69 None
-         %70 = OpAccessChain %_ptr_Private_v2half %p %int_1 %uint_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %74 = OpLoad %v2half %73 None
-         %75 = OpVectorShuffle %v2half %74 %74 1 0
-               OpStore %70 %75 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat3v2half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v2half %64 None
+         %66 = OpCompositeConstruct %mat3v2half %61 %63 %65
+               OpStore %56 %66 None
+         %67 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %70 = OpLoad %v2half %69 None
+         %71 = OpVectorShuffle %v2half %70 %70 1 0
+               OpStore %67 %71 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %77
+%tint_convert_S = OpFunction %S None %73
  %tint_input = OpFunctionParameter %S_std140
-         %78 = OpLabel
-         %79 = OpCompositeExtract %int %tint_input 0
-         %80 = OpCompositeExtract %v2half %tint_input 1
-         %81 = OpCompositeExtract %v2half %tint_input 2
-         %82 = OpCompositeExtract %v2half %tint_input 3
-         %83 = OpCompositeConstruct %mat3v2half %80 %81 %82
-         %84 = OpCompositeExtract %int %tint_input 4
-         %85 = OpCompositeConstruct %S %79 %83 %84
-               OpReturnValue %85
+         %74 = OpLabel
+         %75 = OpCompositeExtract %int %tint_input 0
+         %76 = OpCompositeExtract %v2half %tint_input 1
+         %77 = OpCompositeExtract %v2half %tint_input 2
+         %78 = OpCompositeExtract %v2half %tint_input 3
+         %79 = OpCompositeConstruct %mat3v2half %76 %77 %78
+         %80 = OpCompositeExtract %int %tint_input 4
+         %81 = OpCompositeConstruct %S %75 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.glsl
index 4662e1e..a890bad 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.glsl
@@ -123,8 +123,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.ir.msl
index c1ce431..3f065ae 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -37,6 +40,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -53,7 +57,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.msl
index 369c335..f35974e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half3x2 m;
@@ -30,7 +33,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.spvasm
index ff9f35d..aa7619f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 122
+; Bound: 117
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -83,20 +83,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat3v2half = OpTypePointer StorageBuffer %mat3v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-      %int_0 = OpConstant %int 0
-         %83 = OpTypeFunction %void %_arr_S_uint_4
-        %102 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %78 = OpTypeFunction %void %_arr_S_uint_4
+         %97 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %113 = OpTypeFunction %S %S_std140
+        %108 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -130,83 +126,82 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2half %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v2half %72 None
-         %75 = OpCompositeConstruct %mat3v2half %68 %71 %74
-               OpStore %63 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %int_1 %uint_1 %int_0
-         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %80 = OpLoad %v2half %79 None
-         %81 = OpVectorShuffle %v2half %80 %80 1 0
-               OpStore %76 %81 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2half %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v2half %69 None
+         %71 = OpCompositeConstruct %mat3v2half %66 %68 %70
+               OpStore %61 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %75 = OpLoad %v2half %74 None
+         %76 = OpVectorShuffle %v2half %75 %75 1 0
+               OpStore %72 %76 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %83
+%tint_store_and_preserve_padding = OpFunction %void None %78
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %79 = OpLabel
+         %80 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %80 %value_param
+               OpBranch %81
+         %81 = OpLabel
+               OpBranch %84
          %84 = OpLabel
-         %85 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %85 %value_param
-               OpBranch %86
-         %86 = OpLabel
-               OpBranch %89
-         %89 = OpLabel
-         %91 = OpPhi %uint %uint_0 %86 %92 %88
-               OpLoopMerge %90 %88 None
-               OpBranch %87
-         %87 = OpLabel
-         %93 = OpUGreaterThanEqual %bool %91 %uint_4
-               OpSelectionMerge %94 None
-               OpBranchConditional %93 %95 %94
-         %95 = OpLabel
-               OpBranch %90
-         %94 = OpLabel
-         %96 = OpAccessChain %_ptr_Function_S %85 %91
-         %97 = OpLoad %S %96 None
-         %98 = OpCompositeConstruct %_arr_uint_uint_1 %91
-         %99 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %98 %97
-               OpBranch %88
-         %88 = OpLabel
-         %92 = OpIAdd %uint %91 %uint_1
-               OpBranch %89
+         %86 = OpPhi %uint %uint_0 %81 %87 %83
+               OpLoopMerge %85 %83 None
+               OpBranch %82
+         %82 = OpLabel
+         %88 = OpUGreaterThanEqual %bool %86 %uint_4
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
          %90 = OpLabel
+               OpBranch %85
+         %89 = OpLabel
+         %91 = OpAccessChain %_ptr_Function_S %80 %86
+         %92 = OpLoad %S %91 None
+         %93 = OpCompositeConstruct %_arr_uint_uint_1 %86
+         %94 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %93 %92
+               OpBranch %83
+         %83 = OpLabel
+         %87 = OpIAdd %uint %86 %uint_1
+               OpBranch %84
+         %85 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %102
+%tint_store_and_preserve_padding_0 = OpFunction %void None %97
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %103 = OpLabel
-        %104 = OpCompositeExtract %uint %target_indices 0
-        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_0
-        %107 = OpCompositeExtract %int %value_param_0 0
-               OpStore %105 %107 None
-        %108 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %11 %uint_0 %104 %uint_1
-        %109 = OpCompositeExtract %mat3v2half %value_param_0 1
-               OpStore %108 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_2
-        %111 = OpCompositeExtract %int %value_param_0 2
-               OpStore %110 %111 None
+         %98 = OpLabel
+         %99 = OpCompositeExtract %uint %target_indices 0
+        %100 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_0
+        %102 = OpCompositeExtract %int %value_param_0 0
+               OpStore %100 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %11 %uint_0 %99 %uint_1
+        %104 = OpCompositeExtract %mat3v2half %value_param_0 1
+               OpStore %103 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_2
+        %106 = OpCompositeExtract %int %value_param_0 2
+               OpStore %105 %106 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %113
+%tint_convert_S = OpFunction %S None %108
  %tint_input = OpFunctionParameter %S_std140
-        %114 = OpLabel
-        %115 = OpCompositeExtract %int %tint_input 0
-        %116 = OpCompositeExtract %v2half %tint_input 1
-        %117 = OpCompositeExtract %v2half %tint_input 2
-        %118 = OpCompositeExtract %v2half %tint_input 3
-        %119 = OpCompositeConstruct %mat3v2half %116 %117 %118
-        %120 = OpCompositeExtract %int %tint_input 4
-        %121 = OpCompositeConstruct %S %115 %119 %120
-               OpReturnValue %121
+        %109 = OpLabel
+        %110 = OpCompositeExtract %int %tint_input 0
+        %111 = OpCompositeExtract %v2half %tint_input 1
+        %112 = OpCompositeExtract %v2half %tint_input 2
+        %113 = OpCompositeExtract %v2half %tint_input 3
+        %114 = OpCompositeConstruct %mat3v2half %111 %112 %113
+        %115 = OpCompositeExtract %int %tint_input 4
+        %116 = OpCompositeConstruct %S %110 %114 %115
+               OpReturnValue %116
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.glsl
index 450d9df..a72d910 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.glsl
@@ -86,9 +86,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index fbd82fb..8a3a917 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -78,9 +78,9 @@
   S v_17[4] = v_9(0u);
   w = v_17;
   S v_18 = v_5(256u);
-  w[int(1)] = v_18;
-  w[int(3)].m = v_2(260u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  w[1u] = v_18;
+  w[3u].m = v_2(260u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
index 3e4e0ec..3c163f0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -48,9 +52,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.msl
index f3ccbec..1176487 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half3x2 m;
@@ -28,6 +31,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
index 6e28f61..e488f1c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 104
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -79,17 +79,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v2half = OpTypePointer Workgroup %mat3v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-      %int_0 = OpConstant %int 0
-         %94 = OpTypeFunction %void
-         %99 = OpTypeFunction %S %S_std140
+         %90 = OpTypeFunction %void
+         %95 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -146,42 +142,42 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat3v2half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat3v2half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v2half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v2half %83 None
-         %86 = OpCompositeConstruct %mat3v2half %80 %82 %85
-               OpStore %75 %86 None
-         %87 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1 %uint_1 %int_0
-         %90 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v2half %90 None
-         %92 = OpVectorShuffle %v2half %91 %91 1 0
-               OpStore %87 %92 None
+         %83 = OpCompositeConstruct %mat3v2half %78 %80 %82
+               OpStore %73 %83 None
+         %84 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1 %uint_1 %uint_0
+         %86 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v2half %86 None
+         %88 = OpVectorShuffle %v2half %87 %87 1 0
+               OpStore %84 %88 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %99
+%tint_convert_S = OpFunction %S None %95
  %tint_input = OpFunctionParameter %S_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %int %tint_input 0
-        %102 = OpCompositeExtract %v2half %tint_input 1
-        %103 = OpCompositeExtract %v2half %tint_input 2
-        %104 = OpCompositeExtract %v2half %tint_input 3
-        %105 = OpCompositeConstruct %mat3v2half %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 4
-        %107 = OpCompositeConstruct %S %101 %105 %106
-               OpReturnValue %107
+         %96 = OpLabel
+         %97 = OpCompositeExtract %int %tint_input 0
+         %98 = OpCompositeExtract %v2half %tint_input 1
+         %99 = OpCompositeExtract %v2half %tint_input 2
+        %100 = OpCompositeExtract %v2half %tint_input 3
+        %101 = OpCompositeConstruct %mat3v2half %98 %99 %100
+        %102 = OpCompositeExtract %int %tint_input 4
+        %103 = OpCompositeConstruct %S %97 %101 %102
+               OpReturnValue %103
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4f2b9e0..096c933 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -63,18 +63,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   uint4 ubo_load_3 = a[scalar_offset_3 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 4f2b9e0..096c933 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -63,18 +63,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   uint4 ubo_load_3 = a[scalar_offset_3 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 3aee2c4..c8e2253 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -62,10 +62,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat3x2 v_6 = mat3x2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2);
-  vec2 v_7 = v_6[i()];
+  vec2 v_7 = v_6[min(uint(i()), 2u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))));
   {
@@ -106,5 +106,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat3x2 l_a_i_a_i_m = v_6;
   vec2 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 1890eac..5f288f5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -84,9 +84,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_21 = (256u * uint(i()));
-  uint v_22 = (64u * uint(i()));
-  uint v_23 = (8u * uint(i()));
+  uint v_21 = (256u * uint(min(uint(i()), 3u)));
+  uint v_22 = (64u * uint(min(uint(i()), 3u)));
+  uint v_23 = (8u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_16(0u);
   Outer l_a_i = v_13(v_21);
   Inner l_a_i_a[4] = v_8(v_21);
@@ -94,7 +94,7 @@
   float3x2 l_a_i_a_i_m = v((v_21 + v_22));
   uint4 v_24 = a[(((v_21 + v_22) + v_23) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_21 + v_22) + v_23) % 16u) / 4u) == 2u)) ? (v_24.zw) : (v_24.xy)));
-  uint v_25 = (((v_21 + v_22) + v_23) + (uint(i()) * 4u));
+  uint v_25 = (((v_21 + v_22) + v_23) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_25 / 16u)][((v_25 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 1890eac..5f288f5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -84,9 +84,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_21 = (256u * uint(i()));
-  uint v_22 = (64u * uint(i()));
-  uint v_23 = (8u * uint(i()));
+  uint v_21 = (256u * uint(min(uint(i()), 3u)));
+  uint v_22 = (64u * uint(min(uint(i()), 3u)));
+  uint v_23 = (8u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_16(0u);
   Outer l_a_i = v_13(v_21);
   Inner l_a_i_a[4] = v_8(v_21);
@@ -94,7 +94,7 @@
   float3x2 l_a_i_a_i_m = v((v_21 + v_22));
   uint4 v_24 = a[(((v_21 + v_22) + v_23) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_21 + v_22) + v_23) % 16u) / 4u) == 2u)) ? (v_24.zw) : (v_24.xy)));
-  uint v_25 = (((v_21 + v_22) + v_23) + (uint(i()) * 4u));
+  uint v_25 = (((v_21 + v_22) + v_23) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_25 / 16u)][((v_25 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 66ab5d2..3b2ec53 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float3x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float3x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index e26ceae..1d2b74e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   float3x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index ee99c78..fe95e46 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 144
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -71,6 +72,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -86,17 +88,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %64 = OpConstantNull %_arr_Outer_uint_4
+         %72 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %91 = OpConstantNull %_arr_Inner_uint_4
+         %99 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %115 = OpTypeFunction %Inner %Inner_std140
-        %123 = OpTypeFunction %Outer %Outer_std140
+        %125 = OpTypeFunction %Inner %Inner_std140
+        %133 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -107,132 +109,140 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %49 = OpVariable %_ptr_Function_mat3v2float Function
-         %56 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %58 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %64
-         %87 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %89 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
+         %55 = OpVariable %_ptr_Function_mat3v2float Function
+         %64 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %72
+         %95 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %97 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_0
-         %40 = OpLoad %v2float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_1
-         %43 = OpLoad %v2float %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_0
          %46 = OpLoad %v2float %44 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat3v2float %40 %43 %46
-               OpStore %49 %l_a_i_a_i_m
-         %51 = OpFunctionCall %int %i
-         %52 = OpAccessChain %_ptr_Function_v2float %49 %51
-%l_a_i_a_i_m_i = OpLoad %v2float %52 None
-         %55 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %56 %55
-               OpBranch %65
-         %65 = OpLabel
-               OpBranch %68
-         %68 = OpLabel
-         %70 = OpPhi %uint %uint_0 %65 %71 %67
-               OpLoopMerge %69 %67 None
-               OpBranch %66
-         %66 = OpLabel
-         %72 = OpUGreaterThanEqual %bool %70 %uint_4
-               OpSelectionMerge %74 None
-               OpBranchConditional %72 %75 %74
-         %75 = OpLabel
-               OpBranch %69
+         %47 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_1
+         %49 = OpLoad %v2float %47 None
+         %50 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_2
+         %52 = OpLoad %v2float %50 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat3v2float %46 %49 %52
+               OpStore %55 %l_a_i_a_i_m
+         %57 = OpFunctionCall %int %i
+         %58 = OpBitcast %uint %57
+         %59 = OpExtInst %uint %33 UMin %58 %uint_2
+         %60 = OpAccessChain %_ptr_Function_v2float %55 %59
+%l_a_i_a_i_m_i = OpLoad %v2float %60 None
+         %63 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %64 %63
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %76
+         %76 = OpLabel
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
          %74 = OpLabel
-         %76 = OpAccessChain %_ptr_Function_Outer %58 %70
-         %78 = OpAccessChain %_ptr_Function_Outer_std140 %56 %70
-         %80 = OpLoad %Outer_std140 %78 None
-         %81 = OpFunctionCall %Outer %tint_convert_Outer %80
-               OpStore %76 %81 None
-               OpBranch %67
-         %67 = OpLabel
-         %71 = OpIAdd %uint %70 %uint_1
-               OpBranch %68
-         %69 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %58 None
-         %84 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %84
-         %86 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %87 %86
-               OpBranch %92
-         %92 = OpLabel
-               OpBranch %95
-         %95 = OpLabel
-         %97 = OpPhi %uint %uint_0 %92 %98 %94
-               OpLoopMerge %96 %94 None
-               OpBranch %93
-         %93 = OpLabel
-         %99 = OpUGreaterThanEqual %bool %97 %uint_4
-               OpSelectionMerge %100 None
-               OpBranchConditional %99 %101 %100
-        %101 = OpLabel
-               OpBranch %96
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %82 None
+               OpBranchConditional %80 %83 %82
+         %83 = OpLabel
+               OpBranch %77
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Function_Outer %66 %78
+         %86 = OpAccessChain %_ptr_Function_Outer_std140 %64 %78
+         %88 = OpLoad %Outer_std140 %86 None
+         %89 = OpFunctionCall %Outer %tint_convert_Outer %88
+               OpStore %84 %89 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %66 None
+         %92 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %92
+         %94 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %95 %94
+               OpBranch %100
         %100 = OpLabel
-        %102 = OpAccessChain %_ptr_Function_Inner %89 %97
-        %104 = OpAccessChain %_ptr_Function_Inner_std140 %87 %97
-        %106 = OpLoad %Inner_std140 %104 None
-        %107 = OpFunctionCall %Inner %tint_convert_Inner %106
-               OpStore %102 %107 None
-               OpBranch %94
-         %94 = OpLabel
-         %98 = OpIAdd %uint %97 %uint_1
-               OpBranch %95
-         %96 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %89 None
-        %110 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %110
-        %112 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %112
+               OpBranch %103
+        %103 = OpLabel
+        %105 = OpPhi %uint %uint_0 %100 %106 %102
+               OpLoopMerge %104 %102 None
+               OpBranch %101
+        %101 = OpLabel
+        %107 = OpUGreaterThanEqual %bool %105 %uint_4
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %108
+        %109 = OpLabel
+               OpBranch %104
+        %108 = OpLabel
+        %110 = OpAccessChain %_ptr_Function_Inner %97 %105
+        %112 = OpAccessChain %_ptr_Function_Inner_std140 %95 %105
+        %114 = OpLoad %Inner_std140 %112 None
+        %115 = OpFunctionCall %Inner %tint_convert_Inner %114
+               OpStore %110 %115 None
+               OpBranch %102
+        %102 = OpLabel
+        %106 = OpIAdd %uint %105 %uint_1
+               OpBranch %103
+        %104 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %97 None
+        %118 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %118
+        %120 = OpFunctionCall %int %i
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %33 UMin %121 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %122
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %115
+%tint_convert_Inner = OpFunction %Inner None %125
  %tint_input = OpFunctionParameter %Inner_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %v2float %tint_input 0
-        %118 = OpCompositeExtract %v2float %tint_input 1
-        %119 = OpCompositeExtract %v2float %tint_input 2
-        %120 = OpCompositeConstruct %mat3v2float %117 %118 %119
-        %121 = OpCompositeConstruct %Inner %120
-               OpReturnValue %121
+        %126 = OpLabel
+        %127 = OpCompositeExtract %v2float %tint_input 0
+        %128 = OpCompositeExtract %v2float %tint_input 1
+        %129 = OpCompositeExtract %v2float %tint_input 2
+        %130 = OpCompositeConstruct %mat3v2float %127 %128 %129
+        %131 = OpCompositeConstruct %Inner %130
+               OpReturnValue %131
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %123
+%tint_convert_Outer = OpFunction %Outer None %133
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %124 = OpLabel
-        %126 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %127 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
-        %125 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %126 %125
-               OpBranch %128
-        %128 = OpLabel
-               OpBranch %131
-        %131 = OpLabel
-        %133 = OpPhi %uint %uint_0 %128 %134 %130
-               OpLoopMerge %132 %130 None
-               OpBranch %129
-        %129 = OpLabel
-        %135 = OpUGreaterThanEqual %bool %133 %uint_4
-               OpSelectionMerge %136 None
-               OpBranchConditional %135 %137 %136
-        %137 = OpLabel
-               OpBranch %132
-        %136 = OpLabel
-        %138 = OpAccessChain %_ptr_Function_Inner %127 %133
-        %139 = OpAccessChain %_ptr_Function_Inner_std140 %126 %133
-        %140 = OpLoad %Inner_std140 %139 None
-        %141 = OpFunctionCall %Inner %tint_convert_Inner %140
-               OpStore %138 %141 None
-               OpBranch %130
-        %130 = OpLabel
-        %134 = OpIAdd %uint %133 %uint_1
-               OpBranch %131
-        %132 = OpLabel
-        %142 = OpLoad %_arr_Inner_uint_4 %127 None
-        %143 = OpCompositeConstruct %Outer %142
-               OpReturnValue %143
+        %134 = OpLabel
+        %136 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %137 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
+        %135 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %136 %135
+               OpBranch %138
+        %138 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+        %143 = OpPhi %uint %uint_0 %138 %144 %140
+               OpLoopMerge %142 %140 None
+               OpBranch %139
+        %139 = OpLabel
+        %145 = OpUGreaterThanEqual %bool %143 %uint_4
+               OpSelectionMerge %146 None
+               OpBranchConditional %145 %147 %146
+        %147 = OpLabel
+               OpBranch %142
+        %146 = OpLabel
+        %148 = OpAccessChain %_ptr_Function_Inner %137 %143
+        %149 = OpAccessChain %_ptr_Function_Inner_std140 %136 %143
+        %150 = OpLoad %Inner_std140 %149 None
+        %151 = OpFunctionCall %Inner %tint_convert_Inner %150
+               OpStore %148 %151 None
+               OpBranch %140
+        %140 = OpLabel
+        %144 = OpIAdd %uint %143 %uint_1
+               OpBranch %141
+        %142 = OpLabel
+        %152 = OpLoad %_arr_Inner_uint_4 %137 None
+        %153 = OpCompositeConstruct %Outer %152
+               OpReturnValue %153
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
index 47b928b..5ad2217 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -57,7 +57,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3x2 v_4 = mat3x2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2);
+  mat3x2 v_4 = mat3x2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))))));
   {
@@ -76,8 +76,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f))));
   {
     uint v_11 = 0u;
@@ -95,8 +95,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat3x2 l_a_3_a_2_m = v_4;
-  vec2 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 883a557..45fafb5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float3x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float3x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.spvasm
index 45c92ba..ee30805 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 128
+; Bound: 126
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -64,14 +64,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
 %mat3v2float = OpTypeMatrix %v2float 3
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat3v2float
@@ -79,138 +77,138 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %49 = OpConstantNull %_arr_Outer_uint_4
+         %47 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %76 = OpConstantNull %_arr_Inner_uint_4
+         %74 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %99 = OpTypeFunction %Inner %Inner_std140
-        %107 = OpTypeFunction %Outer %Outer_std140
+         %97 = OpTypeFunction %Inner %Inner_std140
+        %105 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
-         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+         %39 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %41 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %47
+         %70 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %72 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_0
-         %30 = OpLoad %v2float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_1
-         %33 = OpLoad %v2float %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_2
-         %36 = OpLoad %v2float %34 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat3v2float %30 %33 %36
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_0
+         %29 = OpLoad %v2float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_1
+         %32 = OpLoad %v2float %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_2
+         %34 = OpLoad %v2float %33 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat3v2float %29 %32 %34
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2float %l_a_3_a_2_m 1
-         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %41 %40
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %53
-         %53 = OpLabel
-         %55 = OpPhi %uint %uint_0 %50 %56 %52
-               OpLoopMerge %54 %52 None
+         %38 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %39 %38
+               OpBranch %48
+         %48 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %57 = OpUGreaterThanEqual %bool %55 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %60 %59
-         %60 = OpLabel
-               OpBranch %54
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
-         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
-         %65 = OpLoad %Outer_std140 %63 None
-         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
-               OpStore %61 %66 None
+         %53 = OpPhi %uint %uint_0 %48 %54 %50
+               OpLoopMerge %52 %50 None
+               OpBranch %49
+         %49 = OpLabel
+         %55 = OpUGreaterThanEqual %bool %53 %uint_4
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %58 %57
+         %58 = OpLabel
                OpBranch %52
+         %57 = OpLabel
+         %59 = OpAccessChain %_ptr_Function_Outer %41 %53
+         %61 = OpAccessChain %_ptr_Function_Outer_std140 %39 %53
+         %63 = OpLoad %Outer_std140 %61 None
+         %64 = OpFunctionCall %Outer %tint_convert_Outer %63
+               OpStore %59 %64 None
+               OpBranch %50
+         %50 = OpLabel
+         %54 = OpIAdd %uint %53 %uint_1
+               OpBranch %51
          %52 = OpLabel
-         %56 = OpIAdd %uint %55 %uint_1
-               OpBranch %53
-         %54 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
-         %69 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
-         %71 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %72 %71
-               OpBranch %77
-         %77 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %82 = OpPhi %uint %uint_0 %77 %83 %79
-               OpLoopMerge %81 %79 None
+        %l_a = OpLoad %_arr_Outer_uint_4 %41 None
+         %67 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %67
+         %69 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %70 %69
+               OpBranch %75
+         %75 = OpLabel
                OpBranch %78
          %78 = OpLabel
-         %84 = OpUGreaterThanEqual %bool %82 %uint_4
-               OpSelectionMerge %85 None
-               OpBranchConditional %84 %86 %85
-         %86 = OpLabel
-               OpBranch %81
-         %85 = OpLabel
-         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
-         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
-         %91 = OpLoad %Inner_std140 %89 None
-         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
-               OpStore %87 %92 None
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %83 None
+               OpBranchConditional %82 %84 %83
+         %84 = OpLabel
                OpBranch %79
+         %83 = OpLabel
+         %85 = OpAccessChain %_ptr_Function_Inner %72 %80
+         %87 = OpAccessChain %_ptr_Function_Inner_std140 %70 %80
+         %89 = OpLoad %Inner_std140 %87 None
+         %90 = OpFunctionCall %Inner %tint_convert_Inner %89
+               OpStore %85 %90 None
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
          %79 = OpLabel
-         %83 = OpIAdd %uint %82 %uint_1
-               OpBranch %80
-         %81 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
-         %95 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %72 None
+         %93 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %93
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %99
+%tint_convert_Inner = OpFunction %Inner None %97
  %tint_input = OpFunctionParameter %Inner_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %v2float %tint_input 0
-        %102 = OpCompositeExtract %v2float %tint_input 1
-        %103 = OpCompositeExtract %v2float %tint_input 2
-        %104 = OpCompositeConstruct %mat3v2float %101 %102 %103
-        %105 = OpCompositeConstruct %Inner %104
-               OpReturnValue %105
+         %98 = OpLabel
+         %99 = OpCompositeExtract %v2float %tint_input 0
+        %100 = OpCompositeExtract %v2float %tint_input 1
+        %101 = OpCompositeExtract %v2float %tint_input 2
+        %102 = OpCompositeConstruct %mat3v2float %99 %100 %101
+        %103 = OpCompositeConstruct %Inner %102
+               OpReturnValue %103
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %107
+%tint_convert_Outer = OpFunction %Outer None %105
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %108 = OpLabel
-        %110 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %111 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
-        %109 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %110 %109
-               OpBranch %112
-        %112 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %117 = OpPhi %uint %uint_0 %112 %118 %114
-               OpLoopMerge %116 %114 None
+        %106 = OpLabel
+        %108 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %109 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
+        %107 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %108 %107
+               OpBranch %110
+        %110 = OpLabel
                OpBranch %113
         %113 = OpLabel
-        %119 = OpUGreaterThanEqual %bool %117 %uint_4
-               OpSelectionMerge %120 None
-               OpBranchConditional %119 %121 %120
-        %121 = OpLabel
-               OpBranch %116
-        %120 = OpLabel
-        %122 = OpAccessChain %_ptr_Function_Inner %111 %117
-        %123 = OpAccessChain %_ptr_Function_Inner_std140 %110 %117
-        %124 = OpLoad %Inner_std140 %123 None
-        %125 = OpFunctionCall %Inner %tint_convert_Inner %124
-               OpStore %122 %125 None
+        %115 = OpPhi %uint %uint_0 %110 %116 %112
+               OpLoopMerge %114 %112 None
+               OpBranch %111
+        %111 = OpLabel
+        %117 = OpUGreaterThanEqual %bool %115 %uint_4
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpBranch %114
+        %118 = OpLabel
+        %120 = OpAccessChain %_ptr_Function_Inner %109 %115
+        %121 = OpAccessChain %_ptr_Function_Inner_std140 %108 %115
+        %122 = OpLoad %Inner_std140 %121 None
+        %123 = OpFunctionCall %Inner %tint_convert_Inner %122
+               OpStore %120 %123 None
+               OpBranch %112
+        %112 = OpLabel
+        %116 = OpIAdd %uint %115 %uint_1
+               OpBranch %113
         %114 = OpLabel
-        %118 = OpIAdd %uint %117 %uint_1
-               OpBranch %115
-        %116 = OpLabel
-        %126 = OpLoad %_arr_Inner_uint_4 %111 None
-        %127 = OpCompositeConstruct %Outer %126
-               OpReturnValue %127
+        %124 = OpLoad %_arr_Inner_uint_4 %109 None
+        %125 = OpCompositeConstruct %Outer %124
+               OpReturnValue %125
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.glsl
index a851187..76cec94 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.glsl
@@ -39,7 +39,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2x3 t = transpose(mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2));
-  float l = length(v.inner[0].m_col1.yx);
-  float a = abs(v.inner[0].m_col1.yx[0u]);
+  mat2x3 t = transpose(mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2));
+  float l = length(v.inner[0u].m_col1.yx);
+  float a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
index 88216b7..953217e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float2x3 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].yx);
-  float const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  float2x3 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.spvasm
index f8d9d1c4..add66ce 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
-         %37 = OpExtInstImport "GLSL.std.450"
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -45,32 +45,30 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat3v2float = OpTypeMatrix %v2float 3
     %v3float = OpTypeVector %float 3
 %mat2v3float = OpTypeMatrix %v3float 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2float %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v2float %24 None
-         %28 = OpCompositeConstruct %mat3v2float %20 %23 %26
-          %t = OpTranspose %mat2v3float %28
-         %32 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v2float %32 None
-         %35 = OpVectorShuffle %v2float %34 %34 1 0
-          %l = OpExtInst %float %37 Length %35
-         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %39 = OpLoad %v2float %38 None
-         %40 = OpVectorShuffle %v2float %39 %39 1 0
-         %41 = OpCompositeExtract %float %40 0
-          %a = OpExtInst %float %37 FAbs %41
+         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2float %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v2float %23 None
+         %27 = OpCompositeConstruct %mat3v2float %20 %22 %25
+          %t = OpTranspose %mat2v3float %27
+         %31 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v2float %31 None
+         %33 = OpVectorShuffle %v2float %32 %32 1 0
+          %l = OpExtInst %float %35 Length %33
+         %36 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %37 = OpLoad %v2float %36 None
+         %38 = OpVectorShuffle %v2float %37 %37 1 0
+         %39 = OpCompositeExtract %float %38 0
+          %a = OpExtInst %float %35 FAbs %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.glsl
index 7916ded..94c2e8b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.glsl
@@ -76,8 +76,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat3x2(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat3x2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.ir.msl
index 6320e4b..f28f303 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.spvasm
index da7e31c..abb8473 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 103
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -79,12 +79,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %S %S_std140
+         %94 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -143,38 +141,38 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2float %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2float %80 None
-         %83 = OpCompositeConstruct %mat3v2float %76 %79 %82
-         %84 = OpFunctionCall %void %c %83
-         %85 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %87 = OpLoad %v2float %85 None
-         %88 = OpVectorShuffle %v2float %87 %87 1 0
-         %89 = OpFunctionCall %void %d %88
-         %90 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v2float %90 None
-         %92 = OpVectorShuffle %v2float %91 %91 1 0
-         %93 = OpCompositeExtract %float %92 0
-         %94 = OpFunctionCall %void %e %93
+         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2float %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v2float %79 None
+         %82 = OpCompositeConstruct %mat3v2float %76 %78 %81
+         %83 = OpFunctionCall %void %c %82
+         %84 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v2float %84 None
+         %86 = OpVectorShuffle %v2float %85 %85 1 0
+         %87 = OpFunctionCall %void %d %86
+         %88 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v2float %88 None
+         %90 = OpVectorShuffle %v2float %89 %89 1 0
+         %91 = OpCompositeExtract %float %90 0
+         %92 = OpFunctionCall %void %e %91
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %94
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v2float %tint_input 1
-        %100 = OpCompositeExtract %v2float %tint_input 2
-        %101 = OpCompositeExtract %v2float %tint_input 3
-        %102 = OpCompositeConstruct %mat3v2float %99 %100 %101
-        %103 = OpCompositeExtract %int %tint_input 4
-        %104 = OpCompositeConstruct %S %98 %102 %103
-               OpReturnValue %104
+         %95 = OpLabel
+         %96 = OpCompositeExtract %int %tint_input 0
+         %97 = OpCompositeExtract %v2float %tint_input 1
+         %98 = OpCompositeExtract %v2float %tint_input 2
+         %99 = OpCompositeExtract %v2float %tint_input 3
+        %100 = OpCompositeConstruct %mat3v2float %97 %98 %99
+        %101 = OpCompositeExtract %int %tint_input 4
+        %102 = OpCompositeConstruct %S %96 %100 %101
+               OpReturnValue %102
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.glsl
index 1c0643d..926a8c6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.glsl
@@ -67,7 +67,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 3abd953..ca25b65 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -53,8 +53,8 @@
   S v_15[4] = v_10(0u);
   p = v_15;
   S v_16 = v_6(256u);
-  p[int(1)] = v_16;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_16;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 3abd953..ca25b65 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -53,8 +53,8 @@
   S v_15[4] = v_10(0u);
   p = v_15;
   S v_16 = v_6(256u);
-  p[int(1)] = v_16;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_16;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.msl
index 4c5de79..af4022f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.spvasm
index e4904bc..da8408e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 86
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -67,17 +67,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v2float = OpTypePointer Private %mat3v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v2float = OpTypePointer Private %mat3v2float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-      %int_0 = OpConstant %int 0
-         %77 = OpTypeFunction %S %S_std140
+         %73 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -111,36 +107,36 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat3v2float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2float %66 None
-         %69 = OpCompositeConstruct %mat3v2float %62 %65 %68
-               OpStore %57 %69 None
-         %70 = OpAccessChain %_ptr_Private_v2float %p %int_1 %uint_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %74 = OpLoad %v2float %73 None
-         %75 = OpVectorShuffle %v2float %74 %74 1 0
-               OpStore %70 %75 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat3v2float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2float %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v2float %64 None
+         %66 = OpCompositeConstruct %mat3v2float %61 %63 %65
+               OpStore %56 %66 None
+         %67 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %70 = OpLoad %v2float %69 None
+         %71 = OpVectorShuffle %v2float %70 %70 1 0
+               OpStore %67 %71 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %77
+%tint_convert_S = OpFunction %S None %73
  %tint_input = OpFunctionParameter %S_std140
-         %78 = OpLabel
-         %79 = OpCompositeExtract %int %tint_input 0
-         %80 = OpCompositeExtract %v2float %tint_input 1
-         %81 = OpCompositeExtract %v2float %tint_input 2
-         %82 = OpCompositeExtract %v2float %tint_input 3
-         %83 = OpCompositeConstruct %mat3v2float %80 %81 %82
-         %84 = OpCompositeExtract %int %tint_input 4
-         %85 = OpCompositeConstruct %S %79 %83 %84
-               OpReturnValue %85
+         %74 = OpLabel
+         %75 = OpCompositeExtract %int %tint_input 0
+         %76 = OpCompositeExtract %v2float %tint_input 1
+         %77 = OpCompositeExtract %v2float %tint_input 2
+         %78 = OpCompositeExtract %v2float %tint_input 3
+         %79 = OpCompositeConstruct %mat3v2float %76 %77 %78
+         %80 = OpCompositeExtract %int %tint_input 4
+         %81 = OpCompositeConstruct %S %75 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.glsl
index bfff5f0..8195f1e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.glsl
@@ -116,8 +116,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.ir.msl
index 07922c7..261edbb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.msl
index 3b94d66..7a6a401 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.spvasm
index bca2716..61dd700 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 122
+; Bound: 117
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -80,20 +80,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-      %int_0 = OpConstant %int 0
-         %83 = OpTypeFunction %void %_arr_S_uint_4
-        %102 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %78 = OpTypeFunction %void %_arr_S_uint_4
+         %97 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %113 = OpTypeFunction %S %S_std140
+        %108 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -127,83 +123,82 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2float %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v2float %72 None
-         %75 = OpCompositeConstruct %mat3v2float %68 %71 %74
-               OpStore %63 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %int_1 %uint_1 %int_0
-         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %80 = OpLoad %v2float %79 None
-         %81 = OpVectorShuffle %v2float %80 %80 1 0
-               OpStore %76 %81 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2float %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2float %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v2float %69 None
+         %71 = OpCompositeConstruct %mat3v2float %66 %68 %70
+               OpStore %61 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %75 = OpLoad %v2float %74 None
+         %76 = OpVectorShuffle %v2float %75 %75 1 0
+               OpStore %72 %76 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %83
+%tint_store_and_preserve_padding = OpFunction %void None %78
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %79 = OpLabel
+         %80 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %80 %value_param
+               OpBranch %81
+         %81 = OpLabel
+               OpBranch %84
          %84 = OpLabel
-         %85 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %85 %value_param
-               OpBranch %86
-         %86 = OpLabel
-               OpBranch %89
-         %89 = OpLabel
-         %91 = OpPhi %uint %uint_0 %86 %92 %88
-               OpLoopMerge %90 %88 None
-               OpBranch %87
-         %87 = OpLabel
-         %93 = OpUGreaterThanEqual %bool %91 %uint_4
-               OpSelectionMerge %94 None
-               OpBranchConditional %93 %95 %94
-         %95 = OpLabel
-               OpBranch %90
-         %94 = OpLabel
-         %96 = OpAccessChain %_ptr_Function_S %85 %91
-         %97 = OpLoad %S %96 None
-         %98 = OpCompositeConstruct %_arr_uint_uint_1 %91
-         %99 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %98 %97
-               OpBranch %88
-         %88 = OpLabel
-         %92 = OpIAdd %uint %91 %uint_1
-               OpBranch %89
+         %86 = OpPhi %uint %uint_0 %81 %87 %83
+               OpLoopMerge %85 %83 None
+               OpBranch %82
+         %82 = OpLabel
+         %88 = OpUGreaterThanEqual %bool %86 %uint_4
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
          %90 = OpLabel
+               OpBranch %85
+         %89 = OpLabel
+         %91 = OpAccessChain %_ptr_Function_S %80 %86
+         %92 = OpLoad %S %91 None
+         %93 = OpCompositeConstruct %_arr_uint_uint_1 %86
+         %94 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %93 %92
+               OpBranch %83
+         %83 = OpLabel
+         %87 = OpIAdd %uint %86 %uint_1
+               OpBranch %84
+         %85 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %102
+%tint_store_and_preserve_padding_0 = OpFunction %void None %97
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %103 = OpLabel
-        %104 = OpCompositeExtract %uint %target_indices 0
-        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_0
-        %107 = OpCompositeExtract %int %value_param_0 0
-               OpStore %105 %107 None
-        %108 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %11 %uint_0 %104 %uint_1
-        %109 = OpCompositeExtract %mat3v2float %value_param_0 1
-               OpStore %108 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_2
-        %111 = OpCompositeExtract %int %value_param_0 2
-               OpStore %110 %111 None
+         %98 = OpLabel
+         %99 = OpCompositeExtract %uint %target_indices 0
+        %100 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_0
+        %102 = OpCompositeExtract %int %value_param_0 0
+               OpStore %100 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %11 %uint_0 %99 %uint_1
+        %104 = OpCompositeExtract %mat3v2float %value_param_0 1
+               OpStore %103 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_2
+        %106 = OpCompositeExtract %int %value_param_0 2
+               OpStore %105 %106 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %113
+%tint_convert_S = OpFunction %S None %108
  %tint_input = OpFunctionParameter %S_std140
-        %114 = OpLabel
-        %115 = OpCompositeExtract %int %tint_input 0
-        %116 = OpCompositeExtract %v2float %tint_input 1
-        %117 = OpCompositeExtract %v2float %tint_input 2
-        %118 = OpCompositeExtract %v2float %tint_input 3
-        %119 = OpCompositeConstruct %mat3v2float %116 %117 %118
-        %120 = OpCompositeExtract %int %tint_input 4
-        %121 = OpCompositeConstruct %S %115 %119 %120
-               OpReturnValue %121
+        %109 = OpLabel
+        %110 = OpCompositeExtract %int %tint_input 0
+        %111 = OpCompositeExtract %v2float %tint_input 1
+        %112 = OpCompositeExtract %v2float %tint_input 2
+        %113 = OpCompositeExtract %v2float %tint_input 3
+        %114 = OpCompositeConstruct %mat3v2float %111 %112 %113
+        %115 = OpCompositeExtract %int %tint_input 4
+        %116 = OpCompositeConstruct %S %110 %114 %115
+               OpReturnValue %116
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.glsl
index c5ed0f6..da11a3c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.glsl
@@ -82,9 +82,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat3x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat3x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 50d06c1..49f9e35 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -73,9 +73,9 @@
   S v_18[4] = v_10(0u);
   w = v_18;
   S v_19 = v_6(256u);
-  w[int(1)] = v_19;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_19;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 50d06c1..49f9e35 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -73,9 +73,9 @@
   S v_18[4] = v_10(0u);
   w = v_18;
   S v_19 = v_6(256u);
-  w[int(1)] = v_19;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_19;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
index ec49517..7af8f12 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.msl
index be2e59a..6023e07 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
index df744c8..8281f8c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 104
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -76,17 +76,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v2float = OpTypePointer Workgroup %mat3v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
-         %94 = OpTypeFunction %void
-         %99 = OpTypeFunction %S %S_std140
+         %90 = OpTypeFunction %void
+         %95 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -143,42 +139,42 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat3v2float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat3v2float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2float %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v2float %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v2float %83 None
-         %86 = OpCompositeConstruct %mat3v2float %80 %82 %85
-               OpStore %75 %86 None
-         %87 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %uint_1 %int_0
-         %90 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v2float %90 None
-         %92 = OpVectorShuffle %v2float %91 %91 1 0
-               OpStore %87 %92 None
+         %83 = OpCompositeConstruct %mat3v2float %78 %80 %82
+               OpStore %73 %83 None
+         %84 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_1 %uint_0
+         %86 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v2float %86 None
+         %88 = OpVectorShuffle %v2float %87 %87 1 0
+               OpStore %84 %88 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %99
+%tint_convert_S = OpFunction %S None %95
  %tint_input = OpFunctionParameter %S_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %int %tint_input 0
-        %102 = OpCompositeExtract %v2float %tint_input 1
-        %103 = OpCompositeExtract %v2float %tint_input 2
-        %104 = OpCompositeExtract %v2float %tint_input 3
-        %105 = OpCompositeConstruct %mat3v2float %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 4
-        %107 = OpCompositeConstruct %S %101 %105 %106
-               OpReturnValue %107
+         %96 = OpLabel
+         %97 = OpCompositeExtract %int %tint_input 0
+         %98 = OpCompositeExtract %v2float %tint_input 1
+         %99 = OpCompositeExtract %v2float %tint_input 2
+        %100 = OpCompositeExtract %v2float %tint_input 3
+        %101 = OpCompositeConstruct %mat3v2float %98 %99 %100
+        %102 = OpCompositeExtract %int %tint_input 4
+        %103 = OpCompositeConstruct %S %97 %101 %102
+               OpReturnValue %103
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index e0e7ba7..bd9b125 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -72,11 +72,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 3, 3> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 3, 3> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   uint4 ubo_load_7 = a[scalar_offset_3 / 4];
   uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy);
   vector<float16_t, 2> ubo_load_6_xz = vector<float16_t, 2>(f16tof32(ubo_load_6 & 0xFFFF));
@@ -86,7 +86,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 2u))) + (2u * min(uint(tint_symbol_3), 2u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 455d0b4..c0f2547 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -63,10 +63,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat3 v_6 = f16mat3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2);
-  f16vec3 v_7 = v_6[i()];
+  f16vec3 v_7 = v_6[min(uint(i()), 2u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -107,5 +107,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat3 l_a_i_a_i_m = v_6;
   f16vec3 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 3bc7fbe..ade6476e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -96,9 +96,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_25 = (256u * uint(i()));
-  uint v_26 = (64u * uint(i()));
-  uint v_27 = (8u * uint(i()));
+  uint v_25 = (256u * uint(min(uint(i()), 3u)));
+  uint v_26 = (64u * uint(min(uint(i()), 3u)));
+  uint v_27 = (8u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_20(0u);
   Outer l_a_i = v_17(v_25);
   Inner l_a_i_a[4] = v_12(v_25);
@@ -106,7 +106,7 @@
   matrix<float16_t, 3, 3> l_a_i_a_i_m = v_4((v_25 + v_26));
   uint4 v_28 = a[(((v_25 + v_26) + v_27) / 16u)];
   vector<float16_t, 3> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_25 + v_26) + v_27) % 16u) / 4u) == 2u)) ? (v_28.zw) : (v_28.xy))).xyz;
-  uint v_29 = (((v_25 + v_26) + v_27) + (uint(i()) * 2u));
+  uint v_29 = (((v_25 + v_26) + v_27) + (uint(min(uint(i()), 2u)) * 2u));
   uint v_30 = a[(v_29 / 16u)][((v_29 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_30 >> ((((v_29 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 33bc7d5..48dcaf2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -74,11 +74,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 3>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -88,5 +88,5 @@
   half3 const v_11 = half3(v_9[1u].packed);
   half3x3 const l_a_i_a_i_m = half3x3(v_10, v_11, half3(v_9[2u].packed));
   half3 const l_a_i_a_i_m_i = half3((*p_a_i_a_i_m_i));
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 56d6624..6cf01cf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -76,11 +76,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -88,7 +88,7 @@
   half3x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   half3 const l_a_i_a_i_m_i = half3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 92d667b..3d6fa8e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 144
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -74,6 +75,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -89,17 +91,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %64 = OpConstantNull %_arr_Outer_uint_4
+         %72 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %91 = OpConstantNull %_arr_Inner_uint_4
+         %99 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %115 = OpTypeFunction %Inner %Inner_std140
-        %123 = OpTypeFunction %Outer %Outer_std140
+        %125 = OpTypeFunction %Inner %Inner_std140
+        %133 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -110,132 +112,140 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %49 = OpVariable %_ptr_Function_mat3v3half Function
-         %56 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %58 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %64
-         %87 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %89 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
+         %55 = OpVariable %_ptr_Function_mat3v3half Function
+         %64 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %72
+         %95 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %97 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_0
-         %40 = OpLoad %v3half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_1
-         %43 = OpLoad %v3half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_0
          %46 = OpLoad %v3half %44 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat3v3half %40 %43 %46
-               OpStore %49 %l_a_i_a_i_m
-         %51 = OpFunctionCall %int %i
-         %52 = OpAccessChain %_ptr_Function_v3half %49 %51
-%l_a_i_a_i_m_i = OpLoad %v3half %52 None
-         %55 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %56 %55
-               OpBranch %65
-         %65 = OpLabel
-               OpBranch %68
-         %68 = OpLabel
-         %70 = OpPhi %uint %uint_0 %65 %71 %67
-               OpLoopMerge %69 %67 None
-               OpBranch %66
-         %66 = OpLabel
-         %72 = OpUGreaterThanEqual %bool %70 %uint_4
-               OpSelectionMerge %74 None
-               OpBranchConditional %72 %75 %74
-         %75 = OpLabel
-               OpBranch %69
+         %47 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_1
+         %49 = OpLoad %v3half %47 None
+         %50 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_2
+         %52 = OpLoad %v3half %50 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat3v3half %46 %49 %52
+               OpStore %55 %l_a_i_a_i_m
+         %57 = OpFunctionCall %int %i
+         %58 = OpBitcast %uint %57
+         %59 = OpExtInst %uint %33 UMin %58 %uint_2
+         %60 = OpAccessChain %_ptr_Function_v3half %55 %59
+%l_a_i_a_i_m_i = OpLoad %v3half %60 None
+         %63 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %64 %63
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %76
+         %76 = OpLabel
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
          %74 = OpLabel
-         %76 = OpAccessChain %_ptr_Function_Outer %58 %70
-         %78 = OpAccessChain %_ptr_Function_Outer_std140 %56 %70
-         %80 = OpLoad %Outer_std140 %78 None
-         %81 = OpFunctionCall %Outer %tint_convert_Outer %80
-               OpStore %76 %81 None
-               OpBranch %67
-         %67 = OpLabel
-         %71 = OpIAdd %uint %70 %uint_1
-               OpBranch %68
-         %69 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %58 None
-         %84 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %84
-         %86 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %87 %86
-               OpBranch %92
-         %92 = OpLabel
-               OpBranch %95
-         %95 = OpLabel
-         %97 = OpPhi %uint %uint_0 %92 %98 %94
-               OpLoopMerge %96 %94 None
-               OpBranch %93
-         %93 = OpLabel
-         %99 = OpUGreaterThanEqual %bool %97 %uint_4
-               OpSelectionMerge %100 None
-               OpBranchConditional %99 %101 %100
-        %101 = OpLabel
-               OpBranch %96
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %82 None
+               OpBranchConditional %80 %83 %82
+         %83 = OpLabel
+               OpBranch %77
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Function_Outer %66 %78
+         %86 = OpAccessChain %_ptr_Function_Outer_std140 %64 %78
+         %88 = OpLoad %Outer_std140 %86 None
+         %89 = OpFunctionCall %Outer %tint_convert_Outer %88
+               OpStore %84 %89 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %66 None
+         %92 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %92
+         %94 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %95 %94
+               OpBranch %100
         %100 = OpLabel
-        %102 = OpAccessChain %_ptr_Function_Inner %89 %97
-        %104 = OpAccessChain %_ptr_Function_Inner_std140 %87 %97
-        %106 = OpLoad %Inner_std140 %104 None
-        %107 = OpFunctionCall %Inner %tint_convert_Inner %106
-               OpStore %102 %107 None
-               OpBranch %94
-         %94 = OpLabel
-         %98 = OpIAdd %uint %97 %uint_1
-               OpBranch %95
-         %96 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %89 None
-        %110 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %110
-        %112 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %112
+               OpBranch %103
+        %103 = OpLabel
+        %105 = OpPhi %uint %uint_0 %100 %106 %102
+               OpLoopMerge %104 %102 None
+               OpBranch %101
+        %101 = OpLabel
+        %107 = OpUGreaterThanEqual %bool %105 %uint_4
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %108
+        %109 = OpLabel
+               OpBranch %104
+        %108 = OpLabel
+        %110 = OpAccessChain %_ptr_Function_Inner %97 %105
+        %112 = OpAccessChain %_ptr_Function_Inner_std140 %95 %105
+        %114 = OpLoad %Inner_std140 %112 None
+        %115 = OpFunctionCall %Inner %tint_convert_Inner %114
+               OpStore %110 %115 None
+               OpBranch %102
+        %102 = OpLabel
+        %106 = OpIAdd %uint %105 %uint_1
+               OpBranch %103
+        %104 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %97 None
+        %118 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %118
+        %120 = OpFunctionCall %int %i
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %33 UMin %121 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %122
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %115
+%tint_convert_Inner = OpFunction %Inner None %125
  %tint_input = OpFunctionParameter %Inner_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %v3half %tint_input 0
-        %118 = OpCompositeExtract %v3half %tint_input 1
-        %119 = OpCompositeExtract %v3half %tint_input 2
-        %120 = OpCompositeConstruct %mat3v3half %117 %118 %119
-        %121 = OpCompositeConstruct %Inner %120
-               OpReturnValue %121
+        %126 = OpLabel
+        %127 = OpCompositeExtract %v3half %tint_input 0
+        %128 = OpCompositeExtract %v3half %tint_input 1
+        %129 = OpCompositeExtract %v3half %tint_input 2
+        %130 = OpCompositeConstruct %mat3v3half %127 %128 %129
+        %131 = OpCompositeConstruct %Inner %130
+               OpReturnValue %131
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %123
+%tint_convert_Outer = OpFunction %Outer None %133
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %124 = OpLabel
-        %126 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %127 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
-        %125 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %126 %125
-               OpBranch %128
-        %128 = OpLabel
-               OpBranch %131
-        %131 = OpLabel
-        %133 = OpPhi %uint %uint_0 %128 %134 %130
-               OpLoopMerge %132 %130 None
-               OpBranch %129
-        %129 = OpLabel
-        %135 = OpUGreaterThanEqual %bool %133 %uint_4
-               OpSelectionMerge %136 None
-               OpBranchConditional %135 %137 %136
-        %137 = OpLabel
-               OpBranch %132
-        %136 = OpLabel
-        %138 = OpAccessChain %_ptr_Function_Inner %127 %133
-        %139 = OpAccessChain %_ptr_Function_Inner_std140 %126 %133
-        %140 = OpLoad %Inner_std140 %139 None
-        %141 = OpFunctionCall %Inner %tint_convert_Inner %140
-               OpStore %138 %141 None
-               OpBranch %130
-        %130 = OpLabel
-        %134 = OpIAdd %uint %133 %uint_1
-               OpBranch %131
-        %132 = OpLabel
-        %142 = OpLoad %_arr_Inner_uint_4 %127 None
-        %143 = OpCompositeConstruct %Outer %142
-               OpReturnValue %143
+        %134 = OpLabel
+        %136 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %137 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
+        %135 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %136 %135
+               OpBranch %138
+        %138 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+        %143 = OpPhi %uint %uint_0 %138 %144 %140
+               OpLoopMerge %142 %140 None
+               OpBranch %139
+        %139 = OpLabel
+        %145 = OpUGreaterThanEqual %bool %143 %uint_4
+               OpSelectionMerge %146 None
+               OpBranchConditional %145 %147 %146
+        %147 = OpLabel
+               OpBranch %142
+        %146 = OpLabel
+        %148 = OpAccessChain %_ptr_Function_Inner %137 %143
+        %149 = OpAccessChain %_ptr_Function_Inner_std140 %136 %143
+        %150 = OpLoad %Inner_std140 %149 None
+        %151 = OpFunctionCall %Inner %tint_convert_Inner %150
+               OpStore %148 %151 None
+               OpBranch %140
+        %140 = OpLabel
+        %144 = OpIAdd %uint %143 %uint_1
+               OpBranch %141
+        %142 = OpLabel
+        %152 = OpLoad %_arr_Inner_uint_4 %137 None
+        %153 = OpCompositeConstruct %Outer %152
+               OpReturnValue %153
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
index 1c257c6..3d64c0d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -58,7 +58,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3 v_4 = f16mat3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2);
+  f16mat3 v_4 = f16mat3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -77,8 +77,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))));
   {
     uint v_11 = 0u;
@@ -96,8 +96,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat3 l_a_3_a_2_m = v_4;
-  f16vec3 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index bdb2a9e..7df51d9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -67,11 +67,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 3>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -81,5 +81,5 @@
   half3 const v_11 = half3(v_9[1u].packed);
   half3x3 const l_a_3_a_2_m = half3x3(v_10, v_11, half3(v_9[2u].packed));
   half3 const l_a_3_a_2_m_1 = half3((*p_a_3_a_2_m_1));
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.spvasm
index 7a3042d..84c739f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 128
+; Bound: 126
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -67,14 +67,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
  %mat3v3half = OpTypeMatrix %v3half 3
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat3v3half
@@ -82,138 +80,138 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %49 = OpConstantNull %_arr_Outer_uint_4
+         %47 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %76 = OpConstantNull %_arr_Inner_uint_4
+         %74 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %99 = OpTypeFunction %Inner %Inner_std140
-        %107 = OpTypeFunction %Outer %Outer_std140
+         %97 = OpTypeFunction %Inner %Inner_std140
+        %105 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
-         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+         %39 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %41 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %47
+         %70 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %72 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_0
-         %30 = OpLoad %v3half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_1
-         %33 = OpLoad %v3half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_2
-         %36 = OpLoad %v3half %34 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat3v3half %30 %33 %36
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_0
+         %29 = OpLoad %v3half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_1
+         %32 = OpLoad %v3half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_2
+         %34 = OpLoad %v3half %33 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat3v3half %29 %32 %34
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3half %l_a_3_a_2_m 1
-         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %41 %40
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %53
-         %53 = OpLabel
-         %55 = OpPhi %uint %uint_0 %50 %56 %52
-               OpLoopMerge %54 %52 None
+         %38 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %39 %38
+               OpBranch %48
+         %48 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %57 = OpUGreaterThanEqual %bool %55 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %60 %59
-         %60 = OpLabel
-               OpBranch %54
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
-         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
-         %65 = OpLoad %Outer_std140 %63 None
-         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
-               OpStore %61 %66 None
+         %53 = OpPhi %uint %uint_0 %48 %54 %50
+               OpLoopMerge %52 %50 None
+               OpBranch %49
+         %49 = OpLabel
+         %55 = OpUGreaterThanEqual %bool %53 %uint_4
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %58 %57
+         %58 = OpLabel
                OpBranch %52
+         %57 = OpLabel
+         %59 = OpAccessChain %_ptr_Function_Outer %41 %53
+         %61 = OpAccessChain %_ptr_Function_Outer_std140 %39 %53
+         %63 = OpLoad %Outer_std140 %61 None
+         %64 = OpFunctionCall %Outer %tint_convert_Outer %63
+               OpStore %59 %64 None
+               OpBranch %50
+         %50 = OpLabel
+         %54 = OpIAdd %uint %53 %uint_1
+               OpBranch %51
          %52 = OpLabel
-         %56 = OpIAdd %uint %55 %uint_1
-               OpBranch %53
-         %54 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
-         %69 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
-         %71 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %72 %71
-               OpBranch %77
-         %77 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %82 = OpPhi %uint %uint_0 %77 %83 %79
-               OpLoopMerge %81 %79 None
+        %l_a = OpLoad %_arr_Outer_uint_4 %41 None
+         %67 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %67
+         %69 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %70 %69
+               OpBranch %75
+         %75 = OpLabel
                OpBranch %78
          %78 = OpLabel
-         %84 = OpUGreaterThanEqual %bool %82 %uint_4
-               OpSelectionMerge %85 None
-               OpBranchConditional %84 %86 %85
-         %86 = OpLabel
-               OpBranch %81
-         %85 = OpLabel
-         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
-         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
-         %91 = OpLoad %Inner_std140 %89 None
-         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
-               OpStore %87 %92 None
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %83 None
+               OpBranchConditional %82 %84 %83
+         %84 = OpLabel
                OpBranch %79
+         %83 = OpLabel
+         %85 = OpAccessChain %_ptr_Function_Inner %72 %80
+         %87 = OpAccessChain %_ptr_Function_Inner_std140 %70 %80
+         %89 = OpLoad %Inner_std140 %87 None
+         %90 = OpFunctionCall %Inner %tint_convert_Inner %89
+               OpStore %85 %90 None
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
          %79 = OpLabel
-         %83 = OpIAdd %uint %82 %uint_1
-               OpBranch %80
-         %81 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
-         %95 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %72 None
+         %93 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %93
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %99
+%tint_convert_Inner = OpFunction %Inner None %97
  %tint_input = OpFunctionParameter %Inner_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %v3half %tint_input 0
-        %102 = OpCompositeExtract %v3half %tint_input 1
-        %103 = OpCompositeExtract %v3half %tint_input 2
-        %104 = OpCompositeConstruct %mat3v3half %101 %102 %103
-        %105 = OpCompositeConstruct %Inner %104
-               OpReturnValue %105
+         %98 = OpLabel
+         %99 = OpCompositeExtract %v3half %tint_input 0
+        %100 = OpCompositeExtract %v3half %tint_input 1
+        %101 = OpCompositeExtract %v3half %tint_input 2
+        %102 = OpCompositeConstruct %mat3v3half %99 %100 %101
+        %103 = OpCompositeConstruct %Inner %102
+               OpReturnValue %103
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %107
+%tint_convert_Outer = OpFunction %Outer None %105
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %108 = OpLabel
-        %110 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %111 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
-        %109 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %110 %109
-               OpBranch %112
-        %112 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %117 = OpPhi %uint %uint_0 %112 %118 %114
-               OpLoopMerge %116 %114 None
+        %106 = OpLabel
+        %108 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %109 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
+        %107 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %108 %107
+               OpBranch %110
+        %110 = OpLabel
                OpBranch %113
         %113 = OpLabel
-        %119 = OpUGreaterThanEqual %bool %117 %uint_4
-               OpSelectionMerge %120 None
-               OpBranchConditional %119 %121 %120
-        %121 = OpLabel
-               OpBranch %116
-        %120 = OpLabel
-        %122 = OpAccessChain %_ptr_Function_Inner %111 %117
-        %123 = OpAccessChain %_ptr_Function_Inner_std140 %110 %117
-        %124 = OpLoad %Inner_std140 %123 None
-        %125 = OpFunctionCall %Inner %tint_convert_Inner %124
-               OpStore %122 %125 None
+        %115 = OpPhi %uint %uint_0 %110 %116 %112
+               OpLoopMerge %114 %112 None
+               OpBranch %111
+        %111 = OpLabel
+        %117 = OpUGreaterThanEqual %bool %115 %uint_4
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpBranch %114
+        %118 = OpLabel
+        %120 = OpAccessChain %_ptr_Function_Inner %109 %115
+        %121 = OpAccessChain %_ptr_Function_Inner_std140 %108 %115
+        %122 = OpLoad %Inner_std140 %121 None
+        %123 = OpFunctionCall %Inner %tint_convert_Inner %122
+               OpStore %120 %123 None
+               OpBranch %112
+        %112 = OpLabel
+        %116 = OpIAdd %uint %115 %uint_1
+               OpBranch %113
         %114 = OpLabel
-        %118 = OpIAdd %uint %117 %uint_1
-               OpBranch %115
-        %116 = OpLabel
-        %126 = OpLoad %_arr_Inner_uint_4 %111 None
-        %127 = OpCompositeConstruct %Outer %126
-               OpReturnValue %127
+        %124 = OpLoad %_arr_Inner_uint_4 %109 None
+        %125 = OpCompositeConstruct %Outer %124
+               OpReturnValue %125
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.glsl
index ae4a1ee..fd44855 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.glsl
@@ -40,7 +40,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3 t = transpose(f16mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2));
-  float16_t l = length(v.inner[0].m_col1.zxy);
-  float16_t a = abs(v.inner[0].m_col1.zxy[0u]);
+  f16mat3 t = transpose(f16mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2));
+  float16_t l = length(v.inner[0u].m_col1.zxy);
+  float16_t a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
index 7b79219..59df7ec 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -33,10 +33,10 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v = (*tint_module_vars.u)[2u].m;
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   half3x3 const t = transpose(half3x3(v_1, v_2, half3(v[2u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  half const a = abs(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  half const a = abs(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.spvasm
index 06f8063..90acc96 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %35 = OpExtInstImport "GLSL.std.450"
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -48,30 +48,28 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat3v3half = OpTypeMatrix %v3half 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v3half %24 None
-         %28 = OpCompositeConstruct %mat3v3half %20 %23 %26
-          %t = OpTranspose %mat3v3half %28
-         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %32 = OpLoad %v3half %30 None
-         %33 = OpVectorShuffle %v3half %32 %32 2 0 1
-          %l = OpExtInst %half %35 Length %33
-         %36 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %37 = OpLoad %v3half %36 None
-         %38 = OpVectorShuffle %v3half %37 %37 2 0 1
-         %39 = OpCompositeExtract %half %38 0
-          %a = OpExtInst %half %35 FAbs %39
+         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v3half %23 None
+         %27 = OpCompositeConstruct %mat3v3half %20 %22 %25
+          %t = OpTranspose %mat3v3half %27
+         %29 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %30 = OpLoad %v3half %29 None
+         %31 = OpVectorShuffle %v3half %30 %30 2 0 1
+          %l = OpExtInst %half %33 Length %31
+         %34 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %35 = OpLoad %v3half %34 None
+         %36 = OpVectorShuffle %v3half %35 %35 2 0 1
+         %37 = OpCompositeExtract %half %36 0
+          %a = OpExtInst %half %33 FAbs %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.glsl
index 28cc96f..0170bc3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.glsl
@@ -77,8 +77,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat3(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.ir.msl
index 48e5193..f2f20a1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.ir.msl
@@ -71,11 +71,11 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_9 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_9 = (*tint_module_vars.u)[2u].m;
   half3 const v_10 = half3(v_9[0u].packed);
   half3 const v_11 = half3(v_9[1u].packed);
   c(half3x3(v_10, v_11, half3(v_9[2u].packed)));
-  d(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.spvasm
index 237525b..c44b395 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 103
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -82,12 +82,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %S %S_std140
+         %94 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -146,38 +144,38 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3half %80 None
-         %83 = OpCompositeConstruct %mat3v3half %76 %79 %82
-         %84 = OpFunctionCall %void %c %83
-         %85 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %87 = OpLoad %v3half %85 None
-         %88 = OpVectorShuffle %v3half %87 %87 2 0 1
-         %89 = OpFunctionCall %void %d %88
-         %90 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v3half %90 None
-         %92 = OpVectorShuffle %v3half %91 %91 2 0 1
-         %93 = OpCompositeExtract %half %92 0
-         %94 = OpFunctionCall %void %e %93
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v3half %79 None
+         %82 = OpCompositeConstruct %mat3v3half %76 %78 %81
+         %83 = OpFunctionCall %void %c %82
+         %84 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v3half %84 None
+         %86 = OpVectorShuffle %v3half %85 %85 2 0 1
+         %87 = OpFunctionCall %void %d %86
+         %88 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v3half %88 None
+         %90 = OpVectorShuffle %v3half %89 %89 2 0 1
+         %91 = OpCompositeExtract %half %90 0
+         %92 = OpFunctionCall %void %e %91
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %94
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v3half %tint_input 1
-        %100 = OpCompositeExtract %v3half %tint_input 2
-        %101 = OpCompositeExtract %v3half %tint_input 3
-        %102 = OpCompositeConstruct %mat3v3half %99 %100 %101
-        %103 = OpCompositeExtract %int %tint_input 4
-        %104 = OpCompositeConstruct %S %98 %102 %103
-               OpReturnValue %104
+         %95 = OpLabel
+         %96 = OpCompositeExtract %int %tint_input 0
+         %97 = OpCompositeExtract %v3half %tint_input 1
+         %98 = OpCompositeExtract %v3half %tint_input 2
+         %99 = OpCompositeExtract %v3half %tint_input 3
+        %100 = OpCompositeConstruct %mat3v3half %97 %98 %99
+        %101 = OpCompositeExtract %int %tint_input 4
+        %102 = OpCompositeConstruct %S %96 %100 %101
+               OpReturnValue %102
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.glsl
index 2dc44ab..c4e41ad 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.glsl
@@ -68,7 +68,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index bd2fb6b..ec8e9aa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -65,8 +65,8 @@
   S v_19[4] = v_14(0u);
   p = v_19;
   S v_20 = v_10(256u);
-  p[int(1)] = v_20;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  p[1u] = v_20;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.msl
index 6b5910b..c62b903 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.ir.msl
@@ -58,10 +58,10 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_8 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_8 = (*tint_module_vars.u)[2u].m;
   half3 const v_9 = half3(v_8[0u].packed);
   half3 const v_10 = half3(v_8[1u].packed);
-  (*tint_module_vars.p)[3].m = half3x3(v_9, v_10, half3(v_8[2u].packed));
-  (*tint_module_vars.p)[1].m[0] = half3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = half3x3(v_9, v_10, half3(v_8[2u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = half3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.spvasm
index f4e4621..6bfa2df 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 86
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,17 +70,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v3half = OpTypePointer Private %mat3v3half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v3half = OpTypePointer Private %mat3v3half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-      %int_0 = OpConstant %int 0
-         %77 = OpTypeFunction %S %S_std140
+         %73 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -114,36 +110,36 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat3v3half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3half %66 None
-         %69 = OpCompositeConstruct %mat3v3half %62 %65 %68
-               OpStore %57 %69 None
-         %70 = OpAccessChain %_ptr_Private_v3half %p %int_1 %uint_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %74 = OpLoad %v3half %73 None
-         %75 = OpVectorShuffle %v3half %74 %74 2 0 1
-               OpStore %70 %75 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat3v3half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v3half %64 None
+         %66 = OpCompositeConstruct %mat3v3half %61 %63 %65
+               OpStore %56 %66 None
+         %67 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %70 = OpLoad %v3half %69 None
+         %71 = OpVectorShuffle %v3half %70 %70 2 0 1
+               OpStore %67 %71 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %77
+%tint_convert_S = OpFunction %S None %73
  %tint_input = OpFunctionParameter %S_std140
-         %78 = OpLabel
-         %79 = OpCompositeExtract %int %tint_input 0
-         %80 = OpCompositeExtract %v3half %tint_input 1
-         %81 = OpCompositeExtract %v3half %tint_input 2
-         %82 = OpCompositeExtract %v3half %tint_input 3
-         %83 = OpCompositeConstruct %mat3v3half %80 %81 %82
-         %84 = OpCompositeExtract %int %tint_input 4
-         %85 = OpCompositeConstruct %S %79 %83 %84
-               OpReturnValue %85
+         %74 = OpLabel
+         %75 = OpCompositeExtract %int %tint_input 0
+         %76 = OpCompositeExtract %v3half %tint_input 1
+         %77 = OpCompositeExtract %v3half %tint_input 2
+         %78 = OpCompositeExtract %v3half %tint_input 3
+         %79 = OpCompositeConstruct %mat3v3half %76 %77 %78
+         %80 = OpCompositeExtract %int %tint_input 4
+         %81 = OpCompositeConstruct %S %75 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
index 3ec731f..04c7ac34 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.glsl
@@ -122,9 +122,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  f16mat3 v_9 = f16mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  f16mat3 v_9 = f16mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.ir.msl
index 2a77a01..8087f74 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.ir.msl
@@ -33,6 +33,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -64,6 +67,7 @@
     uint v_5 = 0u;
     v_5 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_6 = v_5;
       if ((v_6 >= 4u)) {
         break;
@@ -87,10 +91,10 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_10 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_10 = (*tint_module_vars.u)[2u].m;
   half3 const v_11 = half3(v_10[0u].packed);
   half3 const v_12 = half3(v_10[1u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), half3x3(v_11, v_12, half3(v_10[2u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), half3x3(v_11, v_12, half3(v_10[2u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
index c04be56..35ebb8a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -66,7 +69,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
index 2b8e26c..d855db8 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 136
+; Bound: 130
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -86,20 +86,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_3 = OpConstant %int 3
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-      %int_0 = OpConstant %int 0
-         %85 = OpTypeFunction %void %_arr_S_uint_4
-        %104 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %79 = OpTypeFunction %void %_arr_S_uint_4
+         %98 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %117 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
-        %127 = OpTypeFunction %S %S_std140
+        %111 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3half
+        %121 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -133,100 +129,98 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3half %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3half %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
          %68 = OpLoad %v3half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %71 = OpLoad %v3half %69 None
-         %72 = OpCompositeConstruct %mat3v3half %65 %68 %71
-         %73 = OpBitcast %uint %int_3
-         %75 = OpCompositeConstruct %_arr_uint_uint_1 %73
-         %76 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %75 %72
-         %78 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %int_1 %uint_1 %int_0
-         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %82 = OpLoad %v3half %81 None
-         %83 = OpVectorShuffle %v3half %82 %82 2 0 1
-               OpStore %78 %83 None
+         %69 = OpCompositeConstruct %mat3v3half %63 %65 %68
+         %70 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %71 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %70 %69
+         %73 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %75 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %76 = OpLoad %v3half %75 None
+         %77 = OpVectorShuffle %v3half %76 %76 2 0 1
+               OpStore %73 %77 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %85
+%tint_store_and_preserve_padding = OpFunction %void None %79
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %86 = OpLabel
-         %87 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %87 %value_param
-               OpBranch %88
-         %88 = OpLabel
-               OpBranch %91
+         %80 = OpLabel
+         %81 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %81 %value_param
+               OpBranch %82
+         %82 = OpLabel
+               OpBranch %85
+         %85 = OpLabel
+         %87 = OpPhi %uint %uint_0 %82 %88 %84
+               OpLoopMerge %86 %84 None
+               OpBranch %83
+         %83 = OpLabel
+         %89 = OpUGreaterThanEqual %bool %87 %uint_4
+               OpSelectionMerge %90 None
+               OpBranchConditional %89 %91 %90
          %91 = OpLabel
-         %93 = OpPhi %uint %uint_0 %88 %94 %90
-               OpLoopMerge %92 %90 None
-               OpBranch %89
-         %89 = OpLabel
-         %95 = OpUGreaterThanEqual %bool %93 %uint_4
-               OpSelectionMerge %96 None
-               OpBranchConditional %95 %97 %96
-         %97 = OpLabel
-               OpBranch %92
-         %96 = OpLabel
-         %98 = OpAccessChain %_ptr_Function_S %87 %93
-         %99 = OpLoad %S %98 None
-        %100 = OpCompositeConstruct %_arr_uint_uint_1 %93
-        %101 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %100 %99
-               OpBranch %90
+               OpBranch %86
          %90 = OpLabel
-         %94 = OpIAdd %uint %93 %uint_1
-               OpBranch %91
-         %92 = OpLabel
+         %92 = OpAccessChain %_ptr_Function_S %81 %87
+         %93 = OpLoad %S %92 None
+         %94 = OpCompositeConstruct %_arr_uint_uint_1 %87
+         %95 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %94 %93
+               OpBranch %84
+         %84 = OpLabel
+         %88 = OpIAdd %uint %87 %uint_1
+               OpBranch %85
+         %86 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %104
+%tint_store_and_preserve_padding_0 = OpFunction %void None %98
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %105 = OpLabel
-        %106 = OpCompositeExtract %uint %target_indices 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_0
-        %109 = OpCompositeExtract %int %value_param_0 0
-               OpStore %107 %109 None
-        %110 = OpCompositeExtract %mat3v3half %value_param_0 1
-        %111 = OpCompositeConstruct %_arr_uint_uint_1 %106
-        %112 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %111 %110
-        %113 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_2
-        %114 = OpCompositeExtract %int %value_param_0 2
-               OpStore %113 %114 None
+         %99 = OpLabel
+        %100 = OpCompositeExtract %uint %target_indices 0
+        %101 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %100 %uint_0
+        %103 = OpCompositeExtract %int %value_param_0 0
+               OpStore %101 %103 None
+        %104 = OpCompositeExtract %mat3v3half %value_param_0 1
+        %105 = OpCompositeConstruct %_arr_uint_uint_1 %100
+        %106 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %105 %104
+        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %100 %uint_2
+        %108 = OpCompositeExtract %int %value_param_0 2
+               OpStore %107 %108 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %117
+%tint_store_and_preserve_padding_1 = OpFunction %void None %111
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat3v3half
-        %118 = OpLabel
-        %119 = OpCompositeExtract %uint %target_indices_0 0
-        %120 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %119 %uint_1 %uint_0
-        %121 = OpCompositeExtract %v3half %value_param_1 0
-               OpStore %120 %121 None
-        %122 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %119 %uint_1 %uint_1
-        %123 = OpCompositeExtract %v3half %value_param_1 1
-               OpStore %122 %123 None
-        %124 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %119 %uint_1 %uint_2
-        %125 = OpCompositeExtract %v3half %value_param_1 2
-               OpStore %124 %125 None
+        %112 = OpLabel
+        %113 = OpCompositeExtract %uint %target_indices_0 0
+        %114 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %113 %uint_1 %uint_0
+        %115 = OpCompositeExtract %v3half %value_param_1 0
+               OpStore %114 %115 None
+        %116 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %113 %uint_1 %uint_1
+        %117 = OpCompositeExtract %v3half %value_param_1 1
+               OpStore %116 %117 None
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %113 %uint_1 %uint_2
+        %119 = OpCompositeExtract %v3half %value_param_1 2
+               OpStore %118 %119 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %127
+%tint_convert_S = OpFunction %S None %121
  %tint_input = OpFunctionParameter %S_std140
-        %128 = OpLabel
-        %129 = OpCompositeExtract %int %tint_input 0
-        %130 = OpCompositeExtract %v3half %tint_input 1
-        %131 = OpCompositeExtract %v3half %tint_input 2
-        %132 = OpCompositeExtract %v3half %tint_input 3
-        %133 = OpCompositeConstruct %mat3v3half %130 %131 %132
-        %134 = OpCompositeExtract %int %tint_input 4
-        %135 = OpCompositeConstruct %S %129 %133 %134
-               OpReturnValue %135
+        %122 = OpLabel
+        %123 = OpCompositeExtract %int %tint_input 0
+        %124 = OpCompositeExtract %v3half %tint_input 1
+        %125 = OpCompositeExtract %v3half %tint_input 2
+        %126 = OpCompositeExtract %v3half %tint_input 3
+        %127 = OpCompositeConstruct %mat3v3half %124 %125 %126
+        %128 = OpCompositeExtract %int %tint_input 4
+        %129 = OpCompositeConstruct %S %123 %127 %128
+               OpReturnValue %129
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.glsl
index d558b4a..07f7b39 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.glsl
@@ -83,9 +83,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 479345a..af1474b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -85,9 +85,9 @@
   S v_22[4] = v_14(0u);
   w = v_22;
   S v_23 = v_10(256u);
-  w[int(1)] = v_23;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  w[1u] = v_23;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
index 26234c6..31a73ff 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -38,6 +38,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -78,6 +81,7 @@
     uint v_8 = 0u;
     v_8 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_9 = v_8;
       if ((v_9 >= 4u)) {
         break;
@@ -91,15 +95,15 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 3> const v_10 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 3> const v_10 = (*tint_module_vars.u)[2u].m;
   half3 const v_11 = half3(v_10[0u].packed);
   half3 const v_12 = half3(v_10[1u].packed);
   half3x3 const v_13 = half3x3(v_11, v_12, half3(v_10[2u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_half3(v_13[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_half3(v_13[1u]);
-  (*tint_module_vars.w)[3].m[2u].packed = packed_half3(v_13[2u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_half3(v_13[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_half3(v_13[1u]);
+  (*tint_module_vars.w)[3u].m[2u].packed = packed_half3(v_13[2u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_14 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.msl
index c25adcc..98e9462 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -49,6 +52,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
index f2d5e1f..c9bab5a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 104
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -79,17 +79,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v3half = OpTypePointer Workgroup %mat3v3half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-      %int_0 = OpConstant %int 0
-         %94 = OpTypeFunction %void
-         %99 = OpTypeFunction %S %S_std140
+         %90 = OpTypeFunction %void
+         %95 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -146,42 +142,42 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat3v3half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat3v3half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v3half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v3half %83 None
-         %86 = OpCompositeConstruct %mat3v3half %80 %82 %85
-               OpStore %75 %86 None
-         %87 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %uint_1 %int_0
-         %90 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v3half %90 None
-         %92 = OpVectorShuffle %v3half %91 %91 2 0 1
-               OpStore %87 %92 None
+         %83 = OpCompositeConstruct %mat3v3half %78 %80 %82
+               OpStore %73 %83 None
+         %84 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_1 %uint_0
+         %86 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v3half %86 None
+         %88 = OpVectorShuffle %v3half %87 %87 2 0 1
+               OpStore %84 %88 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %99
+%tint_convert_S = OpFunction %S None %95
  %tint_input = OpFunctionParameter %S_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %int %tint_input 0
-        %102 = OpCompositeExtract %v3half %tint_input 1
-        %103 = OpCompositeExtract %v3half %tint_input 2
-        %104 = OpCompositeExtract %v3half %tint_input 3
-        %105 = OpCompositeConstruct %mat3v3half %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 4
-        %107 = OpCompositeConstruct %S %101 %105 %106
-               OpReturnValue %107
+         %96 = OpLabel
+         %97 = OpCompositeExtract %int %tint_input 0
+         %98 = OpCompositeExtract %v3half %tint_input 1
+         %99 = OpCompositeExtract %v3half %tint_input 2
+        %100 = OpCompositeExtract %v3half %tint_input 3
+        %101 = OpCompositeConstruct %mat3v3half %98 %99 %100
+        %102 = OpCompositeExtract %int %tint_input 4
+        %103 = OpCompositeConstruct %S %97 %101 %102
+               OpReturnValue %103
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 6e898e3..e1aea3f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -60,17 +60,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_3 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 6e898e3..e1aea3f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -60,17 +60,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_3 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index e97442a..5f74eac 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -59,10 +59,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat3 v_6 = mat3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2);
-  vec3 v_7 = v_6[i()];
+  vec3 v_7 = v_6[min(uint(i()), 2u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))));
   {
@@ -103,5 +103,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat3 l_a_i_a_i_m = v_6;
   vec3 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 11a6f9d..5777346 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float3x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 11a6f9d..5777346 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float3x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 6e5c531..204094c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -74,11 +74,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -88,5 +88,5 @@
   float3 const v_11 = float3(v_9[1u].packed);
   float3x3 const l_a_i_a_i_m = float3x3(v_10, v_11, float3(v_9[2u].packed));
   float3 const l_a_i_a_i_m_i = float3((*p_a_i_a_i_m_i));
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index b7721ec..222053c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -76,11 +76,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -88,7 +88,7 @@
   float3x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   float3 const l_a_i_a_i_m_i = float3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 95ad90f..555542c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 144
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -71,6 +72,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -86,17 +88,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %64 = OpConstantNull %_arr_Outer_uint_4
+         %72 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %91 = OpConstantNull %_arr_Inner_uint_4
+         %99 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %115 = OpTypeFunction %Inner %Inner_std140
-        %123 = OpTypeFunction %Outer %Outer_std140
+        %125 = OpTypeFunction %Inner %Inner_std140
+        %133 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -107,132 +109,140 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %49 = OpVariable %_ptr_Function_mat3v3float Function
-         %56 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %58 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %64
-         %87 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %89 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
+         %55 = OpVariable %_ptr_Function_mat3v3float Function
+         %64 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %72
+         %95 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %97 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_0
-         %40 = OpLoad %v3float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_1
-         %43 = OpLoad %v3float %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_0
          %46 = OpLoad %v3float %44 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat3v3float %40 %43 %46
-               OpStore %49 %l_a_i_a_i_m
-         %51 = OpFunctionCall %int %i
-         %52 = OpAccessChain %_ptr_Function_v3float %49 %51
-%l_a_i_a_i_m_i = OpLoad %v3float %52 None
-         %55 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %56 %55
-               OpBranch %65
-         %65 = OpLabel
-               OpBranch %68
-         %68 = OpLabel
-         %70 = OpPhi %uint %uint_0 %65 %71 %67
-               OpLoopMerge %69 %67 None
-               OpBranch %66
-         %66 = OpLabel
-         %72 = OpUGreaterThanEqual %bool %70 %uint_4
-               OpSelectionMerge %74 None
-               OpBranchConditional %72 %75 %74
-         %75 = OpLabel
-               OpBranch %69
+         %47 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_1
+         %49 = OpLoad %v3float %47 None
+         %50 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_2
+         %52 = OpLoad %v3float %50 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat3v3float %46 %49 %52
+               OpStore %55 %l_a_i_a_i_m
+         %57 = OpFunctionCall %int %i
+         %58 = OpBitcast %uint %57
+         %59 = OpExtInst %uint %33 UMin %58 %uint_2
+         %60 = OpAccessChain %_ptr_Function_v3float %55 %59
+%l_a_i_a_i_m_i = OpLoad %v3float %60 None
+         %63 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %64 %63
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %76
+         %76 = OpLabel
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
          %74 = OpLabel
-         %76 = OpAccessChain %_ptr_Function_Outer %58 %70
-         %78 = OpAccessChain %_ptr_Function_Outer_std140 %56 %70
-         %80 = OpLoad %Outer_std140 %78 None
-         %81 = OpFunctionCall %Outer %tint_convert_Outer %80
-               OpStore %76 %81 None
-               OpBranch %67
-         %67 = OpLabel
-         %71 = OpIAdd %uint %70 %uint_1
-               OpBranch %68
-         %69 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %58 None
-         %84 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %84
-         %86 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %87 %86
-               OpBranch %92
-         %92 = OpLabel
-               OpBranch %95
-         %95 = OpLabel
-         %97 = OpPhi %uint %uint_0 %92 %98 %94
-               OpLoopMerge %96 %94 None
-               OpBranch %93
-         %93 = OpLabel
-         %99 = OpUGreaterThanEqual %bool %97 %uint_4
-               OpSelectionMerge %100 None
-               OpBranchConditional %99 %101 %100
-        %101 = OpLabel
-               OpBranch %96
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %82 None
+               OpBranchConditional %80 %83 %82
+         %83 = OpLabel
+               OpBranch %77
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Function_Outer %66 %78
+         %86 = OpAccessChain %_ptr_Function_Outer_std140 %64 %78
+         %88 = OpLoad %Outer_std140 %86 None
+         %89 = OpFunctionCall %Outer %tint_convert_Outer %88
+               OpStore %84 %89 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %66 None
+         %92 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %92
+         %94 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %95 %94
+               OpBranch %100
         %100 = OpLabel
-        %102 = OpAccessChain %_ptr_Function_Inner %89 %97
-        %104 = OpAccessChain %_ptr_Function_Inner_std140 %87 %97
-        %106 = OpLoad %Inner_std140 %104 None
-        %107 = OpFunctionCall %Inner %tint_convert_Inner %106
-               OpStore %102 %107 None
-               OpBranch %94
-         %94 = OpLabel
-         %98 = OpIAdd %uint %97 %uint_1
-               OpBranch %95
-         %96 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %89 None
-        %110 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %110
-        %112 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %112
+               OpBranch %103
+        %103 = OpLabel
+        %105 = OpPhi %uint %uint_0 %100 %106 %102
+               OpLoopMerge %104 %102 None
+               OpBranch %101
+        %101 = OpLabel
+        %107 = OpUGreaterThanEqual %bool %105 %uint_4
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %108
+        %109 = OpLabel
+               OpBranch %104
+        %108 = OpLabel
+        %110 = OpAccessChain %_ptr_Function_Inner %97 %105
+        %112 = OpAccessChain %_ptr_Function_Inner_std140 %95 %105
+        %114 = OpLoad %Inner_std140 %112 None
+        %115 = OpFunctionCall %Inner %tint_convert_Inner %114
+               OpStore %110 %115 None
+               OpBranch %102
+        %102 = OpLabel
+        %106 = OpIAdd %uint %105 %uint_1
+               OpBranch %103
+        %104 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %97 None
+        %118 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %118
+        %120 = OpFunctionCall %int %i
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %33 UMin %121 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %122
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %115
+%tint_convert_Inner = OpFunction %Inner None %125
  %tint_input = OpFunctionParameter %Inner_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %v3float %tint_input 0
-        %118 = OpCompositeExtract %v3float %tint_input 1
-        %119 = OpCompositeExtract %v3float %tint_input 2
-        %120 = OpCompositeConstruct %mat3v3float %117 %118 %119
-        %121 = OpCompositeConstruct %Inner %120
-               OpReturnValue %121
+        %126 = OpLabel
+        %127 = OpCompositeExtract %v3float %tint_input 0
+        %128 = OpCompositeExtract %v3float %tint_input 1
+        %129 = OpCompositeExtract %v3float %tint_input 2
+        %130 = OpCompositeConstruct %mat3v3float %127 %128 %129
+        %131 = OpCompositeConstruct %Inner %130
+               OpReturnValue %131
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %123
+%tint_convert_Outer = OpFunction %Outer None %133
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %124 = OpLabel
-        %126 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %127 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
-        %125 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %126 %125
-               OpBranch %128
-        %128 = OpLabel
-               OpBranch %131
-        %131 = OpLabel
-        %133 = OpPhi %uint %uint_0 %128 %134 %130
-               OpLoopMerge %132 %130 None
-               OpBranch %129
-        %129 = OpLabel
-        %135 = OpUGreaterThanEqual %bool %133 %uint_4
-               OpSelectionMerge %136 None
-               OpBranchConditional %135 %137 %136
-        %137 = OpLabel
-               OpBranch %132
-        %136 = OpLabel
-        %138 = OpAccessChain %_ptr_Function_Inner %127 %133
-        %139 = OpAccessChain %_ptr_Function_Inner_std140 %126 %133
-        %140 = OpLoad %Inner_std140 %139 None
-        %141 = OpFunctionCall %Inner %tint_convert_Inner %140
-               OpStore %138 %141 None
-               OpBranch %130
-        %130 = OpLabel
-        %134 = OpIAdd %uint %133 %uint_1
-               OpBranch %131
-        %132 = OpLabel
-        %142 = OpLoad %_arr_Inner_uint_4 %127 None
-        %143 = OpCompositeConstruct %Outer %142
-               OpReturnValue %143
+        %134 = OpLabel
+        %136 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %137 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
+        %135 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %136 %135
+               OpBranch %138
+        %138 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+        %143 = OpPhi %uint %uint_0 %138 %144 %140
+               OpLoopMerge %142 %140 None
+               OpBranch %139
+        %139 = OpLabel
+        %145 = OpUGreaterThanEqual %bool %143 %uint_4
+               OpSelectionMerge %146 None
+               OpBranchConditional %145 %147 %146
+        %147 = OpLabel
+               OpBranch %142
+        %146 = OpLabel
+        %148 = OpAccessChain %_ptr_Function_Inner %137 %143
+        %149 = OpAccessChain %_ptr_Function_Inner_std140 %136 %143
+        %150 = OpLoad %Inner_std140 %149 None
+        %151 = OpFunctionCall %Inner %tint_convert_Inner %150
+               OpStore %148 %151 None
+               OpBranch %140
+        %140 = OpLabel
+        %144 = OpIAdd %uint %143 %uint_1
+               OpBranch %141
+        %142 = OpLabel
+        %152 = OpLoad %_arr_Inner_uint_4 %137 None
+        %153 = OpCompositeConstruct %Outer %152
+               OpReturnValue %153
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 2024298..788e9b9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -54,7 +54,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3 v_4 = mat3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2);
+  mat3 v_4 = mat3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))))));
   {
@@ -73,8 +73,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f))));
   {
     uint v_11 = 0u;
@@ -92,8 +92,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat3 l_a_3_a_2_m = v_4;
-  vec3 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index d65e130..d6cf278 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -67,11 +67,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -81,5 +81,5 @@
   float3 const v_11 = float3(v_9[1u].packed);
   float3x3 const l_a_3_a_2_m = float3x3(v_10, v_11, float3(v_9[2u].packed));
   float3 const l_a_3_a_2_m_1 = float3((*p_a_3_a_2_m_1));
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index f717788..7168311 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 128
+; Bound: 126
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -64,14 +64,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
 %mat3v3float = OpTypeMatrix %v3float 3
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat3v3float
@@ -79,138 +77,138 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %49 = OpConstantNull %_arr_Outer_uint_4
+         %47 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %76 = OpConstantNull %_arr_Inner_uint_4
+         %74 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %99 = OpTypeFunction %Inner %Inner_std140
-        %107 = OpTypeFunction %Outer %Outer_std140
+         %97 = OpTypeFunction %Inner %Inner_std140
+        %105 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
-         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+         %39 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %41 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %47
+         %70 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %72 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_0
-         %30 = OpLoad %v3float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_1
-         %33 = OpLoad %v3float %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_2
-         %36 = OpLoad %v3float %34 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat3v3float %30 %33 %36
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_0
+         %29 = OpLoad %v3float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_1
+         %32 = OpLoad %v3float %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_2
+         %34 = OpLoad %v3float %33 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat3v3float %29 %32 %34
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3float %l_a_3_a_2_m 1
-         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %41 %40
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %53
-         %53 = OpLabel
-         %55 = OpPhi %uint %uint_0 %50 %56 %52
-               OpLoopMerge %54 %52 None
+         %38 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %39 %38
+               OpBranch %48
+         %48 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %57 = OpUGreaterThanEqual %bool %55 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %60 %59
-         %60 = OpLabel
-               OpBranch %54
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
-         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
-         %65 = OpLoad %Outer_std140 %63 None
-         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
-               OpStore %61 %66 None
+         %53 = OpPhi %uint %uint_0 %48 %54 %50
+               OpLoopMerge %52 %50 None
+               OpBranch %49
+         %49 = OpLabel
+         %55 = OpUGreaterThanEqual %bool %53 %uint_4
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %58 %57
+         %58 = OpLabel
                OpBranch %52
+         %57 = OpLabel
+         %59 = OpAccessChain %_ptr_Function_Outer %41 %53
+         %61 = OpAccessChain %_ptr_Function_Outer_std140 %39 %53
+         %63 = OpLoad %Outer_std140 %61 None
+         %64 = OpFunctionCall %Outer %tint_convert_Outer %63
+               OpStore %59 %64 None
+               OpBranch %50
+         %50 = OpLabel
+         %54 = OpIAdd %uint %53 %uint_1
+               OpBranch %51
          %52 = OpLabel
-         %56 = OpIAdd %uint %55 %uint_1
-               OpBranch %53
-         %54 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
-         %69 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
-         %71 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %72 %71
-               OpBranch %77
-         %77 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %82 = OpPhi %uint %uint_0 %77 %83 %79
-               OpLoopMerge %81 %79 None
+        %l_a = OpLoad %_arr_Outer_uint_4 %41 None
+         %67 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %67
+         %69 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %70 %69
+               OpBranch %75
+         %75 = OpLabel
                OpBranch %78
          %78 = OpLabel
-         %84 = OpUGreaterThanEqual %bool %82 %uint_4
-               OpSelectionMerge %85 None
-               OpBranchConditional %84 %86 %85
-         %86 = OpLabel
-               OpBranch %81
-         %85 = OpLabel
-         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
-         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
-         %91 = OpLoad %Inner_std140 %89 None
-         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
-               OpStore %87 %92 None
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %83 None
+               OpBranchConditional %82 %84 %83
+         %84 = OpLabel
                OpBranch %79
+         %83 = OpLabel
+         %85 = OpAccessChain %_ptr_Function_Inner %72 %80
+         %87 = OpAccessChain %_ptr_Function_Inner_std140 %70 %80
+         %89 = OpLoad %Inner_std140 %87 None
+         %90 = OpFunctionCall %Inner %tint_convert_Inner %89
+               OpStore %85 %90 None
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
          %79 = OpLabel
-         %83 = OpIAdd %uint %82 %uint_1
-               OpBranch %80
-         %81 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
-         %95 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %72 None
+         %93 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %93
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %99
+%tint_convert_Inner = OpFunction %Inner None %97
  %tint_input = OpFunctionParameter %Inner_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %v3float %tint_input 0
-        %102 = OpCompositeExtract %v3float %tint_input 1
-        %103 = OpCompositeExtract %v3float %tint_input 2
-        %104 = OpCompositeConstruct %mat3v3float %101 %102 %103
-        %105 = OpCompositeConstruct %Inner %104
-               OpReturnValue %105
+         %98 = OpLabel
+         %99 = OpCompositeExtract %v3float %tint_input 0
+        %100 = OpCompositeExtract %v3float %tint_input 1
+        %101 = OpCompositeExtract %v3float %tint_input 2
+        %102 = OpCompositeConstruct %mat3v3float %99 %100 %101
+        %103 = OpCompositeConstruct %Inner %102
+               OpReturnValue %103
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %107
+%tint_convert_Outer = OpFunction %Outer None %105
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %108 = OpLabel
-        %110 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %111 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
-        %109 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %110 %109
-               OpBranch %112
-        %112 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %117 = OpPhi %uint %uint_0 %112 %118 %114
-               OpLoopMerge %116 %114 None
+        %106 = OpLabel
+        %108 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %109 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
+        %107 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %108 %107
+               OpBranch %110
+        %110 = OpLabel
                OpBranch %113
         %113 = OpLabel
-        %119 = OpUGreaterThanEqual %bool %117 %uint_4
-               OpSelectionMerge %120 None
-               OpBranchConditional %119 %121 %120
-        %121 = OpLabel
-               OpBranch %116
-        %120 = OpLabel
-        %122 = OpAccessChain %_ptr_Function_Inner %111 %117
-        %123 = OpAccessChain %_ptr_Function_Inner_std140 %110 %117
-        %124 = OpLoad %Inner_std140 %123 None
-        %125 = OpFunctionCall %Inner %tint_convert_Inner %124
-               OpStore %122 %125 None
+        %115 = OpPhi %uint %uint_0 %110 %116 %112
+               OpLoopMerge %114 %112 None
+               OpBranch %111
+        %111 = OpLabel
+        %117 = OpUGreaterThanEqual %bool %115 %uint_4
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpBranch %114
+        %118 = OpLabel
+        %120 = OpAccessChain %_ptr_Function_Inner %109 %115
+        %121 = OpAccessChain %_ptr_Function_Inner_std140 %108 %115
+        %122 = OpLoad %Inner_std140 %121 None
+        %123 = OpFunctionCall %Inner %tint_convert_Inner %122
+               OpStore %120 %123 None
+               OpBranch %112
+        %112 = OpLabel
+        %116 = OpIAdd %uint %115 %uint_1
+               OpBranch %113
         %114 = OpLabel
-        %118 = OpIAdd %uint %117 %uint_1
-               OpBranch %115
-        %116 = OpLabel
-        %126 = OpLoad %_arr_Inner_uint_4 %111 None
-        %127 = OpCompositeConstruct %Outer %126
-               OpReturnValue %127
+        %124 = OpLoad %_arr_Inner_uint_4 %109 None
+        %125 = OpCompositeConstruct %Outer %124
+               OpReturnValue %125
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.glsl
index 75f8ab5..99a82dd 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.glsl
@@ -36,7 +36,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3 t = transpose(mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2));
-  float l = length(v.inner[0].m_col1.zxy);
-  float a = abs(v.inner[0].m_col1.zxy[0u]);
+  mat3 t = transpose(mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2));
+  float l = length(v.inner[0u].m_col1.zxy);
+  float a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
index ba7c168..2f2dee0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -32,10 +32,10 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*tint_module_vars.u)[2u].m;
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   float3x3 const t = transpose(float3x3(v_1, v_2, float3(v[2u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.spvasm
index 802d3c2..80288a6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
-         %35 = OpExtInstImport "GLSL.std.450"
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -45,30 +45,28 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat3v3float = OpTypeMatrix %v3float 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3float %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v3float %24 None
-         %28 = OpCompositeConstruct %mat3v3float %20 %23 %26
-          %t = OpTranspose %mat3v3float %28
-         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %32 = OpLoad %v3float %30 None
-         %33 = OpVectorShuffle %v3float %32 %32 2 0 1
-          %l = OpExtInst %float %35 Length %33
-         %36 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %37 = OpLoad %v3float %36 None
-         %38 = OpVectorShuffle %v3float %37 %37 2 0 1
-         %39 = OpCompositeExtract %float %38 0
-          %a = OpExtInst %float %35 FAbs %39
+         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3float %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v3float %23 None
+         %27 = OpCompositeConstruct %mat3v3float %20 %22 %25
+          %t = OpTranspose %mat3v3float %27
+         %29 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %30 = OpLoad %v3float %29 None
+         %31 = OpVectorShuffle %v3float %30 %30 2 0 1
+          %l = OpExtInst %float %33 Length %31
+         %34 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %35 = OpLoad %v3float %34 None
+         %36 = OpVectorShuffle %v3float %35 %35 2 0 1
+         %37 = OpCompositeExtract %float %36 0
+          %a = OpExtInst %float %33 FAbs %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.glsl
index c19ff27..d6d8836 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.glsl
@@ -73,8 +73,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat3(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.ir.msl
index 1ac9b1f..a39d77a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.ir.msl
@@ -70,11 +70,11 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_9 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_9 = (*tint_module_vars.u)[2u].m;
   float3 const v_10 = float3(v_9[0u].packed);
   float3 const v_11 = float3(v_9[1u].packed);
   c(float3x3(v_10, v_11, float3(v_9[2u].packed)));
-  d(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.spvasm
index a0e10b8..4a9192c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 103
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -79,12 +79,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %S %S_std140
+         %94 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -143,38 +141,38 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3float %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3float %80 None
-         %83 = OpCompositeConstruct %mat3v3float %76 %79 %82
-         %84 = OpFunctionCall %void %c %83
-         %85 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %87 = OpLoad %v3float %85 None
-         %88 = OpVectorShuffle %v3float %87 %87 2 0 1
-         %89 = OpFunctionCall %void %d %88
-         %90 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v3float %90 None
-         %92 = OpVectorShuffle %v3float %91 %91 2 0 1
-         %93 = OpCompositeExtract %float %92 0
-         %94 = OpFunctionCall %void %e %93
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3float %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v3float %79 None
+         %82 = OpCompositeConstruct %mat3v3float %76 %78 %81
+         %83 = OpFunctionCall %void %c %82
+         %84 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v3float %84 None
+         %86 = OpVectorShuffle %v3float %85 %85 2 0 1
+         %87 = OpFunctionCall %void %d %86
+         %88 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v3float %88 None
+         %90 = OpVectorShuffle %v3float %89 %89 2 0 1
+         %91 = OpCompositeExtract %float %90 0
+         %92 = OpFunctionCall %void %e %91
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %94
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v3float %tint_input 1
-        %100 = OpCompositeExtract %v3float %tint_input 2
-        %101 = OpCompositeExtract %v3float %tint_input 3
-        %102 = OpCompositeConstruct %mat3v3float %99 %100 %101
-        %103 = OpCompositeExtract %int %tint_input 4
-        %104 = OpCompositeConstruct %S %98 %102 %103
-               OpReturnValue %104
+         %95 = OpLabel
+         %96 = OpCompositeExtract %int %tint_input 0
+         %97 = OpCompositeExtract %v3float %tint_input 1
+         %98 = OpCompositeExtract %v3float %tint_input 2
+         %99 = OpCompositeExtract %v3float %tint_input 3
+        %100 = OpCompositeConstruct %mat3v3float %97 %98 %99
+        %101 = OpCompositeExtract %int %tint_input 4
+        %102 = OpCompositeConstruct %S %96 %100 %101
+               OpReturnValue %102
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.glsl
index bc49cae..18030a8 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.glsl
@@ -64,7 +64,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 4a7e854..6109350 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 4a7e854..6109350 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.msl
index f917d62..19cc269 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.ir.msl
@@ -57,10 +57,10 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_8 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_8 = (*tint_module_vars.u)[2u].m;
   float3 const v_9 = float3(v_8[0u].packed);
   float3 const v_10 = float3(v_8[1u].packed);
-  (*tint_module_vars.p)[3].m = float3x3(v_9, v_10, float3(v_8[2u].packed));
-  (*tint_module_vars.p)[1].m[0] = float3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = float3x3(v_9, v_10, float3(v_8[2u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = float3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.spvasm
index 2f2e93e..21e276f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 86
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -67,17 +67,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v3float = OpTypePointer Private %mat3v3float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v3float = OpTypePointer Private %mat3v3float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
-         %77 = OpTypeFunction %S %S_std140
+         %73 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -111,36 +107,36 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat3v3float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3float %66 None
-         %69 = OpCompositeConstruct %mat3v3float %62 %65 %68
-               OpStore %57 %69 None
-         %70 = OpAccessChain %_ptr_Private_v3float %p %int_1 %uint_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %74 = OpLoad %v3float %73 None
-         %75 = OpVectorShuffle %v3float %74 %74 2 0 1
-               OpStore %70 %75 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat3v3float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3float %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v3float %64 None
+         %66 = OpCompositeConstruct %mat3v3float %61 %63 %65
+               OpStore %56 %66 None
+         %67 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %70 = OpLoad %v3float %69 None
+         %71 = OpVectorShuffle %v3float %70 %70 2 0 1
+               OpStore %67 %71 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %77
+%tint_convert_S = OpFunction %S None %73
  %tint_input = OpFunctionParameter %S_std140
-         %78 = OpLabel
-         %79 = OpCompositeExtract %int %tint_input 0
-         %80 = OpCompositeExtract %v3float %tint_input 1
-         %81 = OpCompositeExtract %v3float %tint_input 2
-         %82 = OpCompositeExtract %v3float %tint_input 3
-         %83 = OpCompositeConstruct %mat3v3float %80 %81 %82
-         %84 = OpCompositeExtract %int %tint_input 4
-         %85 = OpCompositeConstruct %S %79 %83 %84
-               OpReturnValue %85
+         %74 = OpLabel
+         %75 = OpCompositeExtract %int %tint_input 0
+         %76 = OpCompositeExtract %v3float %tint_input 1
+         %77 = OpCompositeExtract %v3float %tint_input 2
+         %78 = OpCompositeExtract %v3float %tint_input 3
+         %79 = OpCompositeConstruct %mat3v3float %76 %77 %78
+         %80 = OpCompositeExtract %int %tint_input 4
+         %81 = OpCompositeConstruct %S %75 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
index 8c7b653..b73cb6c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -112,9 +112,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  mat3 v_9 = mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  mat3 v_9 = mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.ir.msl
index 886f65e..d0c04d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.ir.msl
@@ -32,6 +32,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -63,6 +66,7 @@
     uint v_5 = 0u;
     v_5 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_6 = v_5;
       if ((v_6 >= 4u)) {
         break;
@@ -86,10 +90,10 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_10 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_10 = (*tint_module_vars.u)[2u].m;
   float3 const v_11 = float3(v_10[0u].packed);
   float3 const v_12 = float3(v_10[1u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), float3x3(v_11, v_12, float3(v_10[2u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), float3x3(v_11, v_12, float3(v_10[2u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
index 152aba8..1cd0de9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -65,7 +68,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
index 34c1756..6faa05f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 136
+; Bound: 130
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -83,20 +83,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_3 = OpConstant %int 3
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
-         %85 = OpTypeFunction %void %_arr_S_uint_4
-        %104 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %79 = OpTypeFunction %void %_arr_S_uint_4
+         %98 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %117 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
-        %127 = OpTypeFunction %S %S_std140
+        %111 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+        %121 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -130,100 +126,98 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3float %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3float %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
          %68 = OpLoad %v3float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %71 = OpLoad %v3float %69 None
-         %72 = OpCompositeConstruct %mat3v3float %65 %68 %71
-         %73 = OpBitcast %uint %int_3
-         %75 = OpCompositeConstruct %_arr_uint_uint_1 %73
-         %76 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %75 %72
-         %78 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %int_1 %uint_1 %int_0
-         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %82 = OpLoad %v3float %81 None
-         %83 = OpVectorShuffle %v3float %82 %82 2 0 1
-               OpStore %78 %83 None
+         %69 = OpCompositeConstruct %mat3v3float %63 %65 %68
+         %70 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %71 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %70 %69
+         %73 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %76 = OpLoad %v3float %75 None
+         %77 = OpVectorShuffle %v3float %76 %76 2 0 1
+               OpStore %73 %77 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %85
+%tint_store_and_preserve_padding = OpFunction %void None %79
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %86 = OpLabel
-         %87 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %87 %value_param
-               OpBranch %88
-         %88 = OpLabel
-               OpBranch %91
+         %80 = OpLabel
+         %81 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %81 %value_param
+               OpBranch %82
+         %82 = OpLabel
+               OpBranch %85
+         %85 = OpLabel
+         %87 = OpPhi %uint %uint_0 %82 %88 %84
+               OpLoopMerge %86 %84 None
+               OpBranch %83
+         %83 = OpLabel
+         %89 = OpUGreaterThanEqual %bool %87 %uint_4
+               OpSelectionMerge %90 None
+               OpBranchConditional %89 %91 %90
          %91 = OpLabel
-         %93 = OpPhi %uint %uint_0 %88 %94 %90
-               OpLoopMerge %92 %90 None
-               OpBranch %89
-         %89 = OpLabel
-         %95 = OpUGreaterThanEqual %bool %93 %uint_4
-               OpSelectionMerge %96 None
-               OpBranchConditional %95 %97 %96
-         %97 = OpLabel
-               OpBranch %92
-         %96 = OpLabel
-         %98 = OpAccessChain %_ptr_Function_S %87 %93
-         %99 = OpLoad %S %98 None
-        %100 = OpCompositeConstruct %_arr_uint_uint_1 %93
-        %101 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %100 %99
-               OpBranch %90
+               OpBranch %86
          %90 = OpLabel
-         %94 = OpIAdd %uint %93 %uint_1
-               OpBranch %91
-         %92 = OpLabel
+         %92 = OpAccessChain %_ptr_Function_S %81 %87
+         %93 = OpLoad %S %92 None
+         %94 = OpCompositeConstruct %_arr_uint_uint_1 %87
+         %95 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %94 %93
+               OpBranch %84
+         %84 = OpLabel
+         %88 = OpIAdd %uint %87 %uint_1
+               OpBranch %85
+         %86 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %104
+%tint_store_and_preserve_padding_0 = OpFunction %void None %98
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %105 = OpLabel
-        %106 = OpCompositeExtract %uint %target_indices 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_0
-        %109 = OpCompositeExtract %int %value_param_0 0
-               OpStore %107 %109 None
-        %110 = OpCompositeExtract %mat3v3float %value_param_0 1
-        %111 = OpCompositeConstruct %_arr_uint_uint_1 %106
-        %112 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %111 %110
-        %113 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_2
-        %114 = OpCompositeExtract %int %value_param_0 2
-               OpStore %113 %114 None
+         %99 = OpLabel
+        %100 = OpCompositeExtract %uint %target_indices 0
+        %101 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %100 %uint_0
+        %103 = OpCompositeExtract %int %value_param_0 0
+               OpStore %101 %103 None
+        %104 = OpCompositeExtract %mat3v3float %value_param_0 1
+        %105 = OpCompositeConstruct %_arr_uint_uint_1 %100
+        %106 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %105 %104
+        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %100 %uint_2
+        %108 = OpCompositeExtract %int %value_param_0 2
+               OpStore %107 %108 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %117
+%tint_store_and_preserve_padding_1 = OpFunction %void None %111
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat3v3float
-        %118 = OpLabel
-        %119 = OpCompositeExtract %uint %target_indices_0 0
-        %120 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %119 %uint_1 %uint_0
-        %121 = OpCompositeExtract %v3float %value_param_1 0
-               OpStore %120 %121 None
-        %122 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %119 %uint_1 %uint_1
-        %123 = OpCompositeExtract %v3float %value_param_1 1
-               OpStore %122 %123 None
-        %124 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %119 %uint_1 %uint_2
-        %125 = OpCompositeExtract %v3float %value_param_1 2
-               OpStore %124 %125 None
+        %112 = OpLabel
+        %113 = OpCompositeExtract %uint %target_indices_0 0
+        %114 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %113 %uint_1 %uint_0
+        %115 = OpCompositeExtract %v3float %value_param_1 0
+               OpStore %114 %115 None
+        %116 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %113 %uint_1 %uint_1
+        %117 = OpCompositeExtract %v3float %value_param_1 1
+               OpStore %116 %117 None
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %113 %uint_1 %uint_2
+        %119 = OpCompositeExtract %v3float %value_param_1 2
+               OpStore %118 %119 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %127
+%tint_convert_S = OpFunction %S None %121
  %tint_input = OpFunctionParameter %S_std140
-        %128 = OpLabel
-        %129 = OpCompositeExtract %int %tint_input 0
-        %130 = OpCompositeExtract %v3float %tint_input 1
-        %131 = OpCompositeExtract %v3float %tint_input 2
-        %132 = OpCompositeExtract %v3float %tint_input 3
-        %133 = OpCompositeConstruct %mat3v3float %130 %131 %132
-        %134 = OpCompositeExtract %int %tint_input 4
-        %135 = OpCompositeConstruct %S %129 %133 %134
-               OpReturnValue %135
+        %122 = OpLabel
+        %123 = OpCompositeExtract %int %tint_input 0
+        %124 = OpCompositeExtract %v3float %tint_input 1
+        %125 = OpCompositeExtract %v3float %tint_input 2
+        %126 = OpCompositeExtract %v3float %tint_input 3
+        %127 = OpCompositeConstruct %mat3v3float %124 %125 %126
+        %128 = OpCompositeExtract %int %tint_input 4
+        %129 = OpCompositeConstruct %S %123 %127 %128
+               OpReturnValue %129
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.glsl
index ed77118..493e7f2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.glsl
@@ -79,9 +79,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 06a885e..82e1792 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 06a885e..82e1792 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
index 4d56302..7f9fc85 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -37,6 +37,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -77,6 +80,7 @@
     uint v_8 = 0u;
     v_8 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_9 = v_8;
       if ((v_9 >= 4u)) {
         break;
@@ -90,15 +94,15 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 3> const v_10 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 3> const v_10 = (*tint_module_vars.u)[2u].m;
   float3 const v_11 = float3(v_10[0u].packed);
   float3 const v_12 = float3(v_10[1u].packed);
   float3x3 const v_13 = float3x3(v_11, v_12, float3(v_10[2u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_float3(v_13[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_float3(v_13[1u]);
-  (*tint_module_vars.w)[3].m[2u].packed = packed_float3(v_13[2u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_float3(v_13[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_float3(v_13[1u]);
+  (*tint_module_vars.w)[3u].m[2u].packed = packed_float3(v_13[2u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_14 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.msl
index 1b4e1e1..e9f447a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -48,6 +51,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
index 9a8cbd0..ea606ef 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 104
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -76,17 +76,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v3float = OpTypePointer Workgroup %mat3v3float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
-         %94 = OpTypeFunction %void
-         %99 = OpTypeFunction %S %S_std140
+         %90 = OpTypeFunction %void
+         %95 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -143,42 +139,42 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat3v3float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat3v3float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3float %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v3float %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v3float %83 None
-         %86 = OpCompositeConstruct %mat3v3float %80 %82 %85
-               OpStore %75 %86 None
-         %87 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %uint_1 %int_0
-         %90 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v3float %90 None
-         %92 = OpVectorShuffle %v3float %91 %91 2 0 1
-               OpStore %87 %92 None
+         %83 = OpCompositeConstruct %mat3v3float %78 %80 %82
+               OpStore %73 %83 None
+         %84 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_1 %uint_0
+         %86 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v3float %86 None
+         %88 = OpVectorShuffle %v3float %87 %87 2 0 1
+               OpStore %84 %88 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %99
+%tint_convert_S = OpFunction %S None %95
  %tint_input = OpFunctionParameter %S_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %int %tint_input 0
-        %102 = OpCompositeExtract %v3float %tint_input 1
-        %103 = OpCompositeExtract %v3float %tint_input 2
-        %104 = OpCompositeExtract %v3float %tint_input 3
-        %105 = OpCompositeConstruct %mat3v3float %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 4
-        %107 = OpCompositeConstruct %S %101 %105 %106
-               OpReturnValue %107
+         %96 = OpLabel
+         %97 = OpCompositeExtract %int %tint_input 0
+         %98 = OpCompositeExtract %v3float %tint_input 1
+         %99 = OpCompositeExtract %v3float %tint_input 2
+        %100 = OpCompositeExtract %v3float %tint_input 3
+        %101 = OpCompositeConstruct %mat3v3float %98 %99 %100
+        %102 = OpCompositeExtract %int %tint_input 4
+        %103 = OpCompositeConstruct %S %97 %101 %102
+               OpReturnValue %103
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index a8fe52d..56639fc 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -72,11 +72,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 3, 4> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 3, 4> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   uint4 ubo_load_7 = a[scalar_offset_3 / 4];
   uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy);
   vector<float16_t, 2> ubo_load_6_xz = vector<float16_t, 2>(f16tof32(ubo_load_6 & 0xFFFF));
@@ -86,7 +86,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 2u))) + (2u * min(uint(tint_symbol_3), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 6b1561f..3f19ba0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -63,10 +63,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat3x4 v_6 = f16mat3x4(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2);
-  f16vec4 v_7 = v_6[i()];
+  f16vec4 v_7 = v_6[min(uint(i()), 2u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -107,5 +107,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat3x4 l_a_i_a_i_m = v_6;
   f16vec4 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index dfbe35b..40fa69b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -96,9 +96,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_25 = (256u * uint(i()));
-  uint v_26 = (64u * uint(i()));
-  uint v_27 = (8u * uint(i()));
+  uint v_25 = (256u * uint(min(uint(i()), 3u)));
+  uint v_26 = (64u * uint(min(uint(i()), 3u)));
+  uint v_27 = (8u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_20(0u);
   Outer l_a_i = v_17(v_25);
   Inner l_a_i_a[4] = v_12(v_25);
@@ -106,7 +106,7 @@
   matrix<float16_t, 3, 4> l_a_i_a_i_m = v_4((v_25 + v_26));
   uint4 v_28 = a[(((v_25 + v_26) + v_27) / 16u)];
   vector<float16_t, 4> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_25 + v_26) + v_27) % 16u) / 4u) == 2u)) ? (v_28.zw) : (v_28.xy)));
-  uint v_29 = (((v_25 + v_26) + v_27) + (uint(i()) * 2u));
+  uint v_29 = (((v_25 + v_26) + v_27) + (uint(min(uint(i()), 3u)) * 2u));
   uint v_30 = a[(v_29 / 16u)][((v_29 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_30 >> ((((v_29 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 98ccff7..d93135f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half3x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half3x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 985b40c..257733a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half3x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 8fd4a361..4845317 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 144
+; Bound: 154
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -74,6 +75,7 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
@@ -89,17 +91,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %64 = OpConstantNull %_arr_Outer_uint_4
+         %72 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %91 = OpConstantNull %_arr_Inner_uint_4
+         %99 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %115 = OpTypeFunction %Inner %Inner_std140
-        %123 = OpTypeFunction %Outer %Outer_std140
+        %125 = OpTypeFunction %Inner %Inner_std140
+        %133 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -110,132 +112,140 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %49 = OpVariable %_ptr_Function_mat3v4half Function
-         %56 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %58 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %64
-         %87 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %89 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
+         %55 = OpVariable %_ptr_Function_mat3v4half Function
+         %64 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %72
+         %95 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %97 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_0
-         %40 = OpLoad %v4half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_1
-         %43 = OpLoad %v4half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_0
          %46 = OpLoad %v4half %44 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat3v4half %40 %43 %46
-               OpStore %49 %l_a_i_a_i_m
-         %51 = OpFunctionCall %int %i
-         %52 = OpAccessChain %_ptr_Function_v4half %49 %51
-%l_a_i_a_i_m_i = OpLoad %v4half %52 None
-         %55 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %56 %55
-               OpBranch %65
-         %65 = OpLabel
-               OpBranch %68
-         %68 = OpLabel
-         %70 = OpPhi %uint %uint_0 %65 %71 %67
-               OpLoopMerge %69 %67 None
-               OpBranch %66
-         %66 = OpLabel
-         %72 = OpUGreaterThanEqual %bool %70 %uint_4
-               OpSelectionMerge %74 None
-               OpBranchConditional %72 %75 %74
-         %75 = OpLabel
-               OpBranch %69
+         %47 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_1
+         %49 = OpLoad %v4half %47 None
+         %50 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_2
+         %52 = OpLoad %v4half %50 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat3v4half %46 %49 %52
+               OpStore %55 %l_a_i_a_i_m
+         %57 = OpFunctionCall %int %i
+         %58 = OpBitcast %uint %57
+         %59 = OpExtInst %uint %33 UMin %58 %uint_2
+         %60 = OpAccessChain %_ptr_Function_v4half %55 %59
+%l_a_i_a_i_m_i = OpLoad %v4half %60 None
+         %63 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %64 %63
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %76
+         %76 = OpLabel
+         %78 = OpPhi %uint %uint_0 %73 %79 %75
+               OpLoopMerge %77 %75 None
+               OpBranch %74
          %74 = OpLabel
-         %76 = OpAccessChain %_ptr_Function_Outer %58 %70
-         %78 = OpAccessChain %_ptr_Function_Outer_std140 %56 %70
-         %80 = OpLoad %Outer_std140 %78 None
-         %81 = OpFunctionCall %Outer %tint_convert_Outer %80
-               OpStore %76 %81 None
-               OpBranch %67
-         %67 = OpLabel
-         %71 = OpIAdd %uint %70 %uint_1
-               OpBranch %68
-         %69 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %58 None
-         %84 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %84
-         %86 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %87 %86
-               OpBranch %92
-         %92 = OpLabel
-               OpBranch %95
-         %95 = OpLabel
-         %97 = OpPhi %uint %uint_0 %92 %98 %94
-               OpLoopMerge %96 %94 None
-               OpBranch %93
-         %93 = OpLabel
-         %99 = OpUGreaterThanEqual %bool %97 %uint_4
-               OpSelectionMerge %100 None
-               OpBranchConditional %99 %101 %100
-        %101 = OpLabel
-               OpBranch %96
+         %80 = OpUGreaterThanEqual %bool %78 %uint_4
+               OpSelectionMerge %82 None
+               OpBranchConditional %80 %83 %82
+         %83 = OpLabel
+               OpBranch %77
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Function_Outer %66 %78
+         %86 = OpAccessChain %_ptr_Function_Outer_std140 %64 %78
+         %88 = OpLoad %Outer_std140 %86 None
+         %89 = OpFunctionCall %Outer %tint_convert_Outer %88
+               OpStore %84 %89 None
+               OpBranch %75
+         %75 = OpLabel
+         %79 = OpIAdd %uint %78 %uint_1
+               OpBranch %76
+         %77 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %66 None
+         %92 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %92
+         %94 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %95 %94
+               OpBranch %100
         %100 = OpLabel
-        %102 = OpAccessChain %_ptr_Function_Inner %89 %97
-        %104 = OpAccessChain %_ptr_Function_Inner_std140 %87 %97
-        %106 = OpLoad %Inner_std140 %104 None
-        %107 = OpFunctionCall %Inner %tint_convert_Inner %106
-               OpStore %102 %107 None
-               OpBranch %94
-         %94 = OpLabel
-         %98 = OpIAdd %uint %97 %uint_1
-               OpBranch %95
-         %96 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %89 None
-        %110 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %110
-        %112 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %112
+               OpBranch %103
+        %103 = OpLabel
+        %105 = OpPhi %uint %uint_0 %100 %106 %102
+               OpLoopMerge %104 %102 None
+               OpBranch %101
+        %101 = OpLabel
+        %107 = OpUGreaterThanEqual %bool %105 %uint_4
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %108
+        %109 = OpLabel
+               OpBranch %104
+        %108 = OpLabel
+        %110 = OpAccessChain %_ptr_Function_Inner %97 %105
+        %112 = OpAccessChain %_ptr_Function_Inner_std140 %95 %105
+        %114 = OpLoad %Inner_std140 %112 None
+        %115 = OpFunctionCall %Inner %tint_convert_Inner %114
+               OpStore %110 %115 None
+               OpBranch %102
+        %102 = OpLabel
+        %106 = OpIAdd %uint %105 %uint_1
+               OpBranch %103
+        %104 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %97 None
+        %118 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %118
+        %120 = OpFunctionCall %int %i
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %33 UMin %121 %uint_3
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %122
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %115
+%tint_convert_Inner = OpFunction %Inner None %125
  %tint_input = OpFunctionParameter %Inner_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %v4half %tint_input 0
-        %118 = OpCompositeExtract %v4half %tint_input 1
-        %119 = OpCompositeExtract %v4half %tint_input 2
-        %120 = OpCompositeConstruct %mat3v4half %117 %118 %119
-        %121 = OpCompositeConstruct %Inner %120
-               OpReturnValue %121
+        %126 = OpLabel
+        %127 = OpCompositeExtract %v4half %tint_input 0
+        %128 = OpCompositeExtract %v4half %tint_input 1
+        %129 = OpCompositeExtract %v4half %tint_input 2
+        %130 = OpCompositeConstruct %mat3v4half %127 %128 %129
+        %131 = OpCompositeConstruct %Inner %130
+               OpReturnValue %131
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %123
+%tint_convert_Outer = OpFunction %Outer None %133
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %124 = OpLabel
-        %126 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %127 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %91
-        %125 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %126 %125
-               OpBranch %128
-        %128 = OpLabel
-               OpBranch %131
-        %131 = OpLabel
-        %133 = OpPhi %uint %uint_0 %128 %134 %130
-               OpLoopMerge %132 %130 None
-               OpBranch %129
-        %129 = OpLabel
-        %135 = OpUGreaterThanEqual %bool %133 %uint_4
-               OpSelectionMerge %136 None
-               OpBranchConditional %135 %137 %136
-        %137 = OpLabel
-               OpBranch %132
-        %136 = OpLabel
-        %138 = OpAccessChain %_ptr_Function_Inner %127 %133
-        %139 = OpAccessChain %_ptr_Function_Inner_std140 %126 %133
-        %140 = OpLoad %Inner_std140 %139 None
-        %141 = OpFunctionCall %Inner %tint_convert_Inner %140
-               OpStore %138 %141 None
-               OpBranch %130
-        %130 = OpLabel
-        %134 = OpIAdd %uint %133 %uint_1
-               OpBranch %131
-        %132 = OpLabel
-        %142 = OpLoad %_arr_Inner_uint_4 %127 None
-        %143 = OpCompositeConstruct %Outer %142
-               OpReturnValue %143
+        %134 = OpLabel
+        %136 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %137 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %99
+        %135 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %136 %135
+               OpBranch %138
+        %138 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+        %143 = OpPhi %uint %uint_0 %138 %144 %140
+               OpLoopMerge %142 %140 None
+               OpBranch %139
+        %139 = OpLabel
+        %145 = OpUGreaterThanEqual %bool %143 %uint_4
+               OpSelectionMerge %146 None
+               OpBranchConditional %145 %147 %146
+        %147 = OpLabel
+               OpBranch %142
+        %146 = OpLabel
+        %148 = OpAccessChain %_ptr_Function_Inner %137 %143
+        %149 = OpAccessChain %_ptr_Function_Inner_std140 %136 %143
+        %150 = OpLoad %Inner_std140 %149 None
+        %151 = OpFunctionCall %Inner %tint_convert_Inner %150
+               OpStore %148 %151 None
+               OpBranch %140
+        %140 = OpLabel
+        %144 = OpIAdd %uint %143 %uint_1
+               OpBranch %141
+        %142 = OpLabel
+        %152 = OpLoad %_arr_Inner_uint_4 %137 None
+        %153 = OpCompositeConstruct %Outer %152
+               OpReturnValue %153
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
index 48bf44c..9ec15d8 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -58,7 +58,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x4 v_4 = f16mat3x4(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2);
+  f16mat3x4 v_4 = f16mat3x4(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -77,8 +77,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat3x4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))));
   {
     uint v_11 = 0u;
@@ -96,8 +96,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat3x4 l_a_3_a_2_m = v_4;
-  f16vec4 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec4 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 7984819..e4cc75f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half3x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half3x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.spvasm
index 15f4458..b079419 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 128
+; Bound: 126
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -67,14 +67,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
  %mat3v4half = OpTypeMatrix %v4half 3
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat3v4half
@@ -82,138 +80,138 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %49 = OpConstantNull %_arr_Outer_uint_4
+         %47 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %76 = OpConstantNull %_arr_Inner_uint_4
+         %74 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-         %99 = OpTypeFunction %Inner %Inner_std140
-        %107 = OpTypeFunction %Outer %Outer_std140
+         %97 = OpTypeFunction %Inner %Inner_std140
+        %105 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
-         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+         %39 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %41 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %47
+         %70 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %72 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_0
-         %30 = OpLoad %v4half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_1
-         %33 = OpLoad %v4half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_2
-         %36 = OpLoad %v4half %34 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat3v4half %30 %33 %36
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_0
+         %29 = OpLoad %v4half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_1
+         %32 = OpLoad %v4half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_2
+         %34 = OpLoad %v4half %33 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat3v4half %29 %32 %34
 %l_a_3_a_2_m_1 = OpCompositeExtract %v4half %l_a_3_a_2_m 1
-         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %41 %40
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %53
-         %53 = OpLabel
-         %55 = OpPhi %uint %uint_0 %50 %56 %52
-               OpLoopMerge %54 %52 None
+         %38 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %39 %38
+               OpBranch %48
+         %48 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %57 = OpUGreaterThanEqual %bool %55 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %60 %59
-         %60 = OpLabel
-               OpBranch %54
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
-         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
-         %65 = OpLoad %Outer_std140 %63 None
-         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
-               OpStore %61 %66 None
+         %53 = OpPhi %uint %uint_0 %48 %54 %50
+               OpLoopMerge %52 %50 None
+               OpBranch %49
+         %49 = OpLabel
+         %55 = OpUGreaterThanEqual %bool %53 %uint_4
+               OpSelectionMerge %57 None
+               OpBranchConditional %55 %58 %57
+         %58 = OpLabel
                OpBranch %52
+         %57 = OpLabel
+         %59 = OpAccessChain %_ptr_Function_Outer %41 %53
+         %61 = OpAccessChain %_ptr_Function_Outer_std140 %39 %53
+         %63 = OpLoad %Outer_std140 %61 None
+         %64 = OpFunctionCall %Outer %tint_convert_Outer %63
+               OpStore %59 %64 None
+               OpBranch %50
+         %50 = OpLabel
+         %54 = OpIAdd %uint %53 %uint_1
+               OpBranch %51
          %52 = OpLabel
-         %56 = OpIAdd %uint %55 %uint_1
-               OpBranch %53
-         %54 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
-         %69 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
-         %71 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %72 %71
-               OpBranch %77
-         %77 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %82 = OpPhi %uint %uint_0 %77 %83 %79
-               OpLoopMerge %81 %79 None
+        %l_a = OpLoad %_arr_Outer_uint_4 %41 None
+         %67 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %67
+         %69 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %70 %69
+               OpBranch %75
+         %75 = OpLabel
                OpBranch %78
          %78 = OpLabel
-         %84 = OpUGreaterThanEqual %bool %82 %uint_4
-               OpSelectionMerge %85 None
-               OpBranchConditional %84 %86 %85
-         %86 = OpLabel
-               OpBranch %81
-         %85 = OpLabel
-         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
-         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
-         %91 = OpLoad %Inner_std140 %89 None
-         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
-               OpStore %87 %92 None
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %83 None
+               OpBranchConditional %82 %84 %83
+         %84 = OpLabel
                OpBranch %79
+         %83 = OpLabel
+         %85 = OpAccessChain %_ptr_Function_Inner %72 %80
+         %87 = OpAccessChain %_ptr_Function_Inner_std140 %70 %80
+         %89 = OpLoad %Inner_std140 %87 None
+         %90 = OpFunctionCall %Inner %tint_convert_Inner %89
+               OpStore %85 %90 None
+               OpBranch %77
+         %77 = OpLabel
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
          %79 = OpLabel
-         %83 = OpIAdd %uint %82 %uint_1
-               OpBranch %80
-         %81 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
-         %95 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %72 None
+         %93 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %93
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %99
+%tint_convert_Inner = OpFunction %Inner None %97
  %tint_input = OpFunctionParameter %Inner_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %v4half %tint_input 0
-        %102 = OpCompositeExtract %v4half %tint_input 1
-        %103 = OpCompositeExtract %v4half %tint_input 2
-        %104 = OpCompositeConstruct %mat3v4half %101 %102 %103
-        %105 = OpCompositeConstruct %Inner %104
-               OpReturnValue %105
+         %98 = OpLabel
+         %99 = OpCompositeExtract %v4half %tint_input 0
+        %100 = OpCompositeExtract %v4half %tint_input 1
+        %101 = OpCompositeExtract %v4half %tint_input 2
+        %102 = OpCompositeConstruct %mat3v4half %99 %100 %101
+        %103 = OpCompositeConstruct %Inner %102
+               OpReturnValue %103
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %107
+%tint_convert_Outer = OpFunction %Outer None %105
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %108 = OpLabel
-        %110 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %111 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
-        %109 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %110 %109
-               OpBranch %112
-        %112 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %117 = OpPhi %uint %uint_0 %112 %118 %114
-               OpLoopMerge %116 %114 None
+        %106 = OpLabel
+        %108 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %109 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %74
+        %107 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %108 %107
+               OpBranch %110
+        %110 = OpLabel
                OpBranch %113
         %113 = OpLabel
-        %119 = OpUGreaterThanEqual %bool %117 %uint_4
-               OpSelectionMerge %120 None
-               OpBranchConditional %119 %121 %120
-        %121 = OpLabel
-               OpBranch %116
-        %120 = OpLabel
-        %122 = OpAccessChain %_ptr_Function_Inner %111 %117
-        %123 = OpAccessChain %_ptr_Function_Inner_std140 %110 %117
-        %124 = OpLoad %Inner_std140 %123 None
-        %125 = OpFunctionCall %Inner %tint_convert_Inner %124
-               OpStore %122 %125 None
+        %115 = OpPhi %uint %uint_0 %110 %116 %112
+               OpLoopMerge %114 %112 None
+               OpBranch %111
+        %111 = OpLabel
+        %117 = OpUGreaterThanEqual %bool %115 %uint_4
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpBranch %114
+        %118 = OpLabel
+        %120 = OpAccessChain %_ptr_Function_Inner %109 %115
+        %121 = OpAccessChain %_ptr_Function_Inner_std140 %108 %115
+        %122 = OpLoad %Inner_std140 %121 None
+        %123 = OpFunctionCall %Inner %tint_convert_Inner %122
+               OpStore %120 %123 None
+               OpBranch %112
+        %112 = OpLabel
+        %116 = OpIAdd %uint %115 %uint_1
+               OpBranch %113
         %114 = OpLabel
-        %118 = OpIAdd %uint %117 %uint_1
-               OpBranch %115
-        %116 = OpLabel
-        %126 = OpLoad %_arr_Inner_uint_4 %111 None
-        %127 = OpCompositeConstruct %Outer %126
-               OpReturnValue %127
+        %124 = OpLoad %_arr_Inner_uint_4 %109 None
+        %125 = OpCompositeConstruct %Outer %124
+               OpReturnValue %125
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.glsl
index 71ef942..2f8ab54 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.glsl
@@ -40,7 +40,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x3 t = transpose(f16mat3x4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2));
-  float16_t l = length(v.inner[0].m_col1.ywxz);
-  float16_t a = abs(v.inner[0].m_col1.ywxz[0u]);
+  f16mat4x3 t = transpose(f16mat3x4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2));
+  float16_t l = length(v.inner[0u].m_col1.ywxz);
+  float16_t a = abs(v.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
index b0bba90..4c118ec 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half4x3 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  half const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  half4x3 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.spvasm
index 561ee30..86ee644 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %37 = OpExtInstImport "GLSL.std.450"
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -48,32 +48,30 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat3v4half = OpTypeMatrix %v4half 3
      %v3half = OpTypeVector %half 3
  %mat4v3half = OpTypeMatrix %v3half 4
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v4half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v4half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v4half %24 None
-         %28 = OpCompositeConstruct %mat3v4half %20 %23 %26
-          %t = OpTranspose %mat4v3half %28
-         %32 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v4half %32 None
-         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
-          %l = OpExtInst %half %37 Length %35
-         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %39 = OpLoad %v4half %38 None
-         %40 = OpVectorShuffle %v4half %39 %39 1 3 0 2
-         %41 = OpCompositeExtract %half %40 0
-          %a = OpExtInst %half %37 FAbs %41
+         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v4half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v4half %23 None
+         %27 = OpCompositeConstruct %mat3v4half %20 %22 %25
+          %t = OpTranspose %mat4v3half %27
+         %31 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v4half %31 None
+         %33 = OpVectorShuffle %v4half %32 %32 1 3 0 2
+          %l = OpExtInst %half %35 Length %33
+         %36 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %37 = OpLoad %v4half %36 None
+         %38 = OpVectorShuffle %v4half %37 %37 1 3 0 2
+         %39 = OpCompositeExtract %half %38 0
+          %a = OpExtInst %half %35 FAbs %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.glsl
index 809bf60..11433c4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.glsl
@@ -77,8 +77,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat3x4(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2));
-  d(v_1.inner[0].m_col1.ywxz);
-  e(v_1.inner[0].m_col1.ywxz[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat3x4(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2));
+  d(v_1.inner[0u].m_col1.ywxz);
+  e(v_1.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.ir.msl
index 0723fb0..7883b98 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.spvasm
index 335e375..c678e00 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 105
+; Bound: 103
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -82,12 +82,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %S %S_std140
+         %94 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -146,38 +144,38 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v4half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v4half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v4half %80 None
-         %83 = OpCompositeConstruct %mat3v4half %76 %79 %82
-         %84 = OpFunctionCall %void %c %83
-         %85 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %87 = OpLoad %v4half %85 None
-         %88 = OpVectorShuffle %v4half %87 %87 1 3 0 2
-         %89 = OpFunctionCall %void %d %88
-         %90 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v4half %90 None
-         %92 = OpVectorShuffle %v4half %91 %91 1 3 0 2
-         %93 = OpCompositeExtract %half %92 0
-         %94 = OpFunctionCall %void %e %93
+         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v4half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v4half %79 None
+         %82 = OpCompositeConstruct %mat3v4half %76 %78 %81
+         %83 = OpFunctionCall %void %c %82
+         %84 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %85 = OpLoad %v4half %84 None
+         %86 = OpVectorShuffle %v4half %85 %85 1 3 0 2
+         %87 = OpFunctionCall %void %d %86
+         %88 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v4half %88 None
+         %90 = OpVectorShuffle %v4half %89 %89 1 3 0 2
+         %91 = OpCompositeExtract %half %90 0
+         %92 = OpFunctionCall %void %e %91
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %96
+%tint_convert_S = OpFunction %S None %94
  %tint_input = OpFunctionParameter %S_std140
-         %97 = OpLabel
-         %98 = OpCompositeExtract %int %tint_input 0
-         %99 = OpCompositeExtract %v4half %tint_input 1
-        %100 = OpCompositeExtract %v4half %tint_input 2
-        %101 = OpCompositeExtract %v4half %tint_input 3
-        %102 = OpCompositeConstruct %mat3v4half %99 %100 %101
-        %103 = OpCompositeExtract %int %tint_input 4
-        %104 = OpCompositeConstruct %S %98 %102 %103
-               OpReturnValue %104
+         %95 = OpLabel
+         %96 = OpCompositeExtract %int %tint_input 0
+         %97 = OpCompositeExtract %v4half %tint_input 1
+         %98 = OpCompositeExtract %v4half %tint_input 2
+         %99 = OpCompositeExtract %v4half %tint_input 3
+        %100 = OpCompositeConstruct %mat3v4half %97 %98 %99
+        %101 = OpCompositeExtract %int %tint_input 4
+        %102 = OpCompositeConstruct %S %96 %100 %101
+               OpReturnValue %102
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.glsl
index 8a1468b..a31a702 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.glsl
@@ -68,7 +68,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat3x4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  p[1].m[0] = v.inner[0].m_col1.ywxz;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat3x4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  p[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 5a05965..2ecd202 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -65,8 +65,8 @@
   S v_19[4] = v_14(0u);
   p = v_19;
   S v_20 = v_10(256u);
-  p[int(1)] = v_20;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  p[1u] = v_20;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.msl
index f396b47..da88817 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.spvasm
index 20db9f5..5533b91d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 86
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -70,17 +70,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v4half = OpTypePointer Private %mat3v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v4half = OpTypePointer Private %mat3v4half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-      %int_0 = OpConstant %int 0
-         %77 = OpTypeFunction %S %S_std140
+         %73 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -114,36 +110,36 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat3v4half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v4half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v4half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v4half %66 None
-         %69 = OpCompositeConstruct %mat3v4half %62 %65 %68
-               OpStore %57 %69 None
-         %70 = OpAccessChain %_ptr_Private_v4half %p %int_1 %uint_1 %int_0
-         %73 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %74 = OpLoad %v4half %73 None
-         %75 = OpVectorShuffle %v4half %74 %74 1 3 0 2
-               OpStore %70 %75 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat3v4half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v4half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v4half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v4half %64 None
+         %66 = OpCompositeConstruct %mat3v4half %61 %63 %65
+               OpStore %56 %66 None
+         %67 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_1 %uint_0
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %70 = OpLoad %v4half %69 None
+         %71 = OpVectorShuffle %v4half %70 %70 1 3 0 2
+               OpStore %67 %71 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %77
+%tint_convert_S = OpFunction %S None %73
  %tint_input = OpFunctionParameter %S_std140
-         %78 = OpLabel
-         %79 = OpCompositeExtract %int %tint_input 0
-         %80 = OpCompositeExtract %v4half %tint_input 1
-         %81 = OpCompositeExtract %v4half %tint_input 2
-         %82 = OpCompositeExtract %v4half %tint_input 3
-         %83 = OpCompositeConstruct %mat3v4half %80 %81 %82
-         %84 = OpCompositeExtract %int %tint_input 4
-         %85 = OpCompositeConstruct %S %79 %83 %84
-               OpReturnValue %85
+         %74 = OpLabel
+         %75 = OpCompositeExtract %int %tint_input 0
+         %76 = OpCompositeExtract %v4half %tint_input 1
+         %77 = OpCompositeExtract %v4half %tint_input 2
+         %78 = OpCompositeExtract %v4half %tint_input 3
+         %79 = OpCompositeConstruct %mat3v4half %76 %77 %78
+         %80 = OpCompositeExtract %int %tint_input 4
+         %81 = OpCompositeConstruct %S %75 %79 %80
+               OpReturnValue %81
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.glsl
index 8ea9c6e..f3e23d3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.glsl
@@ -117,8 +117,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat3x4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.ywxz;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat3x4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.ir.msl
index b9e1126..8c5a7ae 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.msl
index c9bca39..4cdab95 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.spvasm
index ec5dd48..ca7d5c5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 122
+; Bound: 117
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -83,20 +83,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat3v4half = OpTypePointer StorageBuffer %mat3v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-      %int_0 = OpConstant %int 0
-         %83 = OpTypeFunction %void %_arr_S_uint_4
-        %102 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %78 = OpTypeFunction %void %_arr_S_uint_4
+         %97 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %113 = OpTypeFunction %S %S_std140
+        %108 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -130,83 +126,82 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v4half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v4half %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v4half %72 None
-         %75 = OpCompositeConstruct %mat3v4half %68 %71 %74
-               OpStore %63 %75 None
-         %76 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %int_1 %uint_1 %int_0
-         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %80 = OpLoad %v4half %79 None
-         %81 = OpVectorShuffle %v4half %80 %80 1 3 0 2
-               OpStore %76 %81 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v4half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v4half %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v4half %69 None
+         %71 = OpCompositeConstruct %mat3v4half %66 %68 %70
+               OpStore %61 %71 None
+         %72 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %75 = OpLoad %v4half %74 None
+         %76 = OpVectorShuffle %v4half %75 %75 1 3 0 2
+               OpStore %72 %76 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %83
+%tint_store_and_preserve_padding = OpFunction %void None %78
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %79 = OpLabel
+         %80 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %80 %value_param
+               OpBranch %81
+         %81 = OpLabel
+               OpBranch %84
          %84 = OpLabel
-         %85 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %85 %value_param
-               OpBranch %86
-         %86 = OpLabel
-               OpBranch %89
-         %89 = OpLabel
-         %91 = OpPhi %uint %uint_0 %86 %92 %88
-               OpLoopMerge %90 %88 None
-               OpBranch %87
-         %87 = OpLabel
-         %93 = OpUGreaterThanEqual %bool %91 %uint_4
-               OpSelectionMerge %94 None
-               OpBranchConditional %93 %95 %94
-         %95 = OpLabel
-               OpBranch %90
-         %94 = OpLabel
-         %96 = OpAccessChain %_ptr_Function_S %85 %91
-         %97 = OpLoad %S %96 None
-         %98 = OpCompositeConstruct %_arr_uint_uint_1 %91
-         %99 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %98 %97
-               OpBranch %88
-         %88 = OpLabel
-         %92 = OpIAdd %uint %91 %uint_1
-               OpBranch %89
+         %86 = OpPhi %uint %uint_0 %81 %87 %83
+               OpLoopMerge %85 %83 None
+               OpBranch %82
+         %82 = OpLabel
+         %88 = OpUGreaterThanEqual %bool %86 %uint_4
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
          %90 = OpLabel
+               OpBranch %85
+         %89 = OpLabel
+         %91 = OpAccessChain %_ptr_Function_S %80 %86
+         %92 = OpLoad %S %91 None
+         %93 = OpCompositeConstruct %_arr_uint_uint_1 %86
+         %94 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %93 %92
+               OpBranch %83
+         %83 = OpLabel
+         %87 = OpIAdd %uint %86 %uint_1
+               OpBranch %84
+         %85 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %102
+%tint_store_and_preserve_padding_0 = OpFunction %void None %97
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %103 = OpLabel
-        %104 = OpCompositeExtract %uint %target_indices 0
-        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_0
-        %107 = OpCompositeExtract %int %value_param_0 0
-               OpStore %105 %107 None
-        %108 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %11 %uint_0 %104 %uint_1
-        %109 = OpCompositeExtract %mat3v4half %value_param_0 1
-               OpStore %108 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %104 %uint_2
-        %111 = OpCompositeExtract %int %value_param_0 2
-               OpStore %110 %111 None
+         %98 = OpLabel
+         %99 = OpCompositeExtract %uint %target_indices 0
+        %100 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_0
+        %102 = OpCompositeExtract %int %value_param_0 0
+               OpStore %100 %102 None
+        %103 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %11 %uint_0 %99 %uint_1
+        %104 = OpCompositeExtract %mat3v4half %value_param_0 1
+               OpStore %103 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %99 %uint_2
+        %106 = OpCompositeExtract %int %value_param_0 2
+               OpStore %105 %106 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %113
+%tint_convert_S = OpFunction %S None %108
  %tint_input = OpFunctionParameter %S_std140
-        %114 = OpLabel
-        %115 = OpCompositeExtract %int %tint_input 0
-        %116 = OpCompositeExtract %v4half %tint_input 1
-        %117 = OpCompositeExtract %v4half %tint_input 2
-        %118 = OpCompositeExtract %v4half %tint_input 3
-        %119 = OpCompositeConstruct %mat3v4half %116 %117 %118
-        %120 = OpCompositeExtract %int %tint_input 4
-        %121 = OpCompositeConstruct %S %115 %119 %120
-               OpReturnValue %121
+        %109 = OpLabel
+        %110 = OpCompositeExtract %int %tint_input 0
+        %111 = OpCompositeExtract %v4half %tint_input 1
+        %112 = OpCompositeExtract %v4half %tint_input 2
+        %113 = OpCompositeExtract %v4half %tint_input 3
+        %114 = OpCompositeConstruct %mat3v4half %111 %112 %113
+        %115 = OpCompositeExtract %int %tint_input 4
+        %116 = OpCompositeConstruct %S %110 %114 %115
+               OpReturnValue %116
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.glsl
index b8e7e3b..f9d1a74 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.glsl
@@ -83,9 +83,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat3x4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2);
-  w[1].m[0] = v.inner[0].m_col1.ywxz;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat3x4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2);
+  w[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 65ad625..046a14d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -85,9 +85,9 @@
   S v_22[4] = v_14(0u);
   w = v_22;
   S v_23 = v_10(256u);
-  w[int(1)] = v_23;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  w[1u] = v_23;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
index 8713553..176d1cf 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.msl
index b83e3c3..e06b7b1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
index ab06121..893b522 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 104
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -79,17 +79,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v4half = OpTypePointer Workgroup %mat3v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-      %int_0 = OpConstant %int 0
-         %94 = OpTypeFunction %void
-         %99 = OpTypeFunction %S %S_std140
+         %90 = OpTypeFunction %void
+         %95 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -146,42 +142,42 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat3v4half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v4half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat3v4half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v4half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v4half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v4half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v4half %83 None
-         %86 = OpCompositeConstruct %mat3v4half %80 %82 %85
-               OpStore %75 %86 None
-         %87 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %uint_1 %int_0
-         %90 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %91 = OpLoad %v4half %90 None
-         %92 = OpVectorShuffle %v4half %91 %91 1 3 0 2
-               OpStore %87 %92 None
+         %83 = OpCompositeConstruct %mat3v4half %78 %80 %82
+               OpStore %73 %83 None
+         %84 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_1 %uint_0
+         %86 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v4half %86 None
+         %88 = OpVectorShuffle %v4half %87 %87 1 3 0 2
+               OpStore %84 %88 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %94
-         %95 = OpLabel
-         %96 = OpLoad %uint %f_local_invocation_index_Input None
-         %97 = OpFunctionCall %void %f_inner %96
+          %f = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %uint %f_local_invocation_index_Input None
+         %93 = OpFunctionCall %void %f_inner %92
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %99
+%tint_convert_S = OpFunction %S None %95
  %tint_input = OpFunctionParameter %S_std140
-        %100 = OpLabel
-        %101 = OpCompositeExtract %int %tint_input 0
-        %102 = OpCompositeExtract %v4half %tint_input 1
-        %103 = OpCompositeExtract %v4half %tint_input 2
-        %104 = OpCompositeExtract %v4half %tint_input 3
-        %105 = OpCompositeConstruct %mat3v4half %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 4
-        %107 = OpCompositeConstruct %S %101 %105 %106
-               OpReturnValue %107
+         %96 = OpLabel
+         %97 = OpCompositeExtract %int %tint_input 0
+         %98 = OpCompositeExtract %v4half %tint_input 1
+         %99 = OpCompositeExtract %v4half %tint_input 2
+        %100 = OpCompositeExtract %v4half %tint_input 3
+        %101 = OpCompositeConstruct %mat3v4half %98 %99 %100
+        %102 = OpCompositeExtract %int %tint_input 4
+        %103 = OpCompositeConstruct %S %97 %101 %102
+               OpReturnValue %103
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4573d02..b0d496c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -60,17 +60,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_3 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 4573d02..b0d496c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -60,17 +60,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float3x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_3 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float3x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_3 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 2u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_3 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_4 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_4 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 2u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_4 / 4][scalar_offset_4 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 8aabfb5..982ca97 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -24,14 +24,14 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
-  int v_2 = i();
-  int v_3 = i();
+  uint v_1 = min(uint(i()), 3u);
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 2u);
   Outer l_a[4] = v.inner;
   Outer l_a_i = v.inner[v_1];
   Inner l_a_i_a[4] = v.inner[v_1].a;
   Inner l_a_i_a_i = v.inner[v_1].a[v_2];
   mat3x4 l_a_i_a_i_m = v.inner[v_1].a[v_2].m;
   vec4 l_a_i_a_i_m_i = v.inner[v_1].a[v_2].m[v_3];
-  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][i()];
+  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 12ac2d6..54ee2ed 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float3x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 12ac2d6..54ee2ed 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 2u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float3x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index c72b84d..4be81e4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float3x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 2u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float3x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 92e2f67..9e2bb7c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 2u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   float3x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 0747257..dfc1200 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,10 +63,12 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
           %i = OpFunction %int None %18
@@ -80,21 +83,29 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %31
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %33
     %p_a_i_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_i %uint_0
-         %36 = OpFunctionCall %int %i
-  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %36
+         %40 = OpFunctionCall %int %i
+         %41 = OpBitcast %uint %40
+         %42 = OpExtInst %uint %34 UMin %41 %uint_3
+  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %42
 %p_a_i_a_i_m = OpAccessChain %_ptr_Uniform_mat3v4float %p_a_i_a_i %uint_0
-         %41 = OpFunctionCall %int %i
-%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %41
+         %47 = OpFunctionCall %int %i
+         %48 = OpBitcast %uint %47
+         %49 = OpExtInst %uint %34 UMin %48 %uint_2
+%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %49
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_i = OpLoad %Outer %p_a_i None
     %l_a_i_a = OpLoad %_arr_Inner_uint_4 %p_a_i_a None
   %l_a_i_a_i = OpLoad %Inner %p_a_i_a_i None
 %l_a_i_a_i_m = OpLoad %mat3v4float %p_a_i_a_i_m None
 %l_a_i_a_i_m_i = OpLoad %v4float %p_a_i_a_i_m_i None
-         %50 = OpFunctionCall %int %i
-         %51 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %50
-%l_a_i_a_i_m_i_i = OpLoad %float %51 None
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %34 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %61
+%l_a_i_a_i_m_i_i = OpLoad %float %62 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
index 79e6ace..d4c0b9f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -20,10 +20,10 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   Outer l_a[4] = v.inner;
-  Outer l_a_3 = v.inner[3];
-  Inner l_a_3_a[4] = v.inner[3].a;
-  Inner l_a_3_a_2 = v.inner[3].a[2];
-  mat3x4 l_a_3_a_2_m = v.inner[3].a[2].m;
-  vec4 l_a_3_a_2_m_1 = v.inner[3].a[2].m[1];
-  float l_a_3_a_2_m_1_0 = v.inner[3].a[2].m[1].x;
+  Outer l_a_3 = v.inner[3u];
+  Inner l_a_3_a[4] = v.inner[3u].a;
+  Inner l_a_3_a_2 = v.inner[3u].a[2u];
+  mat3x4 l_a_3_a_2_m = v.inner[3u].a[2u].m;
+  vec4 l_a_3_a_2_m_1 = v.inner[3u].a[2u].m[1u];
+  float l_a_3_a_2_m_1_0 = v.inner[3u].a[2u].m[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 413fb0a..c190844 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float3x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float3x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index c3ebc8e..4404c73 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,31 +55,29 @@
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
-      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %int_3
+      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %uint_3
     %p_a_3_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_3 %uint_0
-  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %int_2
+  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %uint_2
 %p_a_3_a_2_m = OpAccessChain %_ptr_Uniform_mat3v4float %p_a_3_a_2 %uint_0
-%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %int_1
+%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %uint_1
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_3 = OpLoad %Outer %p_a_3 None
     %l_a_3_a = OpLoad %_arr_Inner_uint_4 %p_a_3_a None
   %l_a_3_a_2 = OpLoad %Inner %p_a_3_a_2 None
 %l_a_3_a_2_m = OpLoad %mat3v4float %p_a_3_a_2_m None
 %l_a_3_a_2_m_1 = OpLoad %v4float %p_a_3_a_2_m_1 None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %int_0
-%l_a_3_a_2_m_1_0 = OpLoad %float %40 None
+         %39 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %uint_0
+%l_a_3_a_2_m_1_0 = OpLoad %float %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.glsl
index 428a9b8..07d3007 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.glsl
@@ -31,7 +31,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x3 t = transpose(v.inner[2].m);
-  float l = length(v.inner[0].m[1].ywxz);
-  float a = abs(v.inner[0].m[1].ywxz[0u]);
+  mat4x3 t = transpose(v.inner[2u].m);
+  float l = length(v.inner[0u].m[1u].ywxz);
+  float a = abs(v.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
index a7710b4..5f536fa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -27,7 +27,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float4x3 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  float4x3 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.spvasm
index 3281c8e..0f86624 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
-         %32 = OpExtInstImport "GLSL.std.450"
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -44,26 +44,24 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2 %uint_1
+         %16 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2 %uint_1
          %21 = OpLoad %mat3v4float %16 None
           %t = OpTranspose %mat4v3float %21
-         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %29 = OpLoad %v4float %25 None
-         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
-          %l = OpExtInst %float %32 Length %30
-         %33 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %34 = OpLoad %v4float %33 None
-         %35 = OpVectorShuffle %v4float %34 %34 1 3 0 2
-         %36 = OpCompositeExtract %float %35 0
-          %a = OpExtInst %float %32 FAbs %36
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %27 = OpLoad %v4float %25 None
+         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
+          %l = OpExtInst %float %30 Length %28
+         %31 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %32 = OpLoad %v4float %31 None
+         %33 = OpVectorShuffle %v4float %32 %32 1 3 0 2
+         %34 = OpCompositeExtract %float %33 0
+          %a = OpExtInst %float %30 FAbs %34
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.glsl
index 064cae5..38a3694 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.glsl
@@ -42,8 +42,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[2]);
-  c(v_1.inner[2].m);
-  d(v_1.inner[0].m[1].ywxz);
-  e(v_1.inner[0].m[1].ywxz[0u]);
+  b(v_1.inner[2u]);
+  c(v_1.inner[2u].m);
+  d(v_1.inner[0u].m[1u].ywxz);
+  e(v_1.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.ir.msl
index db2c19b..3587f97 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.ir.msl
@@ -43,8 +43,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.spvasm
index 33191c0..4b71849 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -56,12 +56,10 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %a = OpFunction %void None %15
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %16 = OpLabel
@@ -92,20 +90,20 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_S_uint_4 %36 None
          %40 = OpFunctionCall %void %a %39
-         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %44 = OpLoad %S %41 None
          %45 = OpFunctionCall %void %b %44
-         %46 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2 %uint_1
+         %46 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2 %uint_1
          %49 = OpLoad %mat3v4float %46 None
          %50 = OpFunctionCall %void %c %49
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %55 = OpLoad %v4float %51 None
-         %56 = OpVectorShuffle %v4float %55 %55 1 3 0 2
-         %57 = OpFunctionCall %void %d %56
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %59 = OpLoad %v4float %58 None
-         %60 = OpVectorShuffle %v4float %59 %59 1 3 0 2
-         %61 = OpCompositeExtract %float %60 0
-         %62 = OpFunctionCall %void %e %61
+         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %53 = OpLoad %v4float %51 None
+         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
+         %55 = OpFunctionCall %void %d %54
+         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %56 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+         %59 = OpCompositeExtract %float %58 0
+         %60 = OpFunctionCall %void %e %59
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.glsl
index 0e2af14..583291f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.glsl
@@ -33,7 +33,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[3].m = v.inner[2].m;
-  p[1].m[0] = v.inner[0].m[1].ywxz;
+  p[1u] = v.inner[2u];
+  p[3u].m = v.inner[2u].m;
+  p[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 0483597..85941d9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 0483597..85941d9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(256u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(272u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(272u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.msl
index 265eba8..cec90f9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.spvasm
index 9765c76..716dcc1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,33 +45,31 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
-%_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat3v4float = OpTypePointer Private %mat3v4float
-      %int_3 = OpConstant %int 3
      %uint_1 = OpConstant %uint 1
+%_ptr_Uniform_S = OpTypePointer Uniform %S
+     %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat3v4float = OpTypePointer Private %mat3v4float
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_S %p %int_1
-         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %23 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %29 = OpLoad %S %26 None
                OpStore %23 %29 None
-         %30 = OpAccessChain %_ptr_Private_mat3v4float %p %int_3 %uint_1
-         %34 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2 %uint_1
-         %36 = OpLoad %mat3v4float %34 None
-               OpStore %30 %36 None
-         %37 = OpAccessChain %_ptr_Private_v4float %p %int_1 %uint_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %42 = OpLoad %v4float %40 None
-         %43 = OpVectorShuffle %v4float %42 %42 1 3 0 2
-               OpStore %37 %43 None
+         %30 = OpAccessChain %_ptr_Private_mat3v4float %p %uint_3 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2 %uint_1
+         %35 = OpLoad %mat3v4float %33 None
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %40 = OpLoad %v4float %38 None
+         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
+               OpStore %36 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.glsl
index f0279a4..19e4509 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.glsl
@@ -58,8 +58,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(v.inner);
-  S v_4 = v.inner[2];
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_4);
-  v_1.inner[3].m = v.inner[2].m;
-  v_1.inner[1].m[0] = v.inner[0].m[1].ywxz;
+  S v_4 = v.inner[2u];
+  tint_store_and_preserve_padding_1(uint[1](1u), v_4);
+  v_1.inner[3u].m = v.inner[2u].m;
+  v_1.inner[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.ir.msl
index 6565537..2bc64ef 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -37,6 +40,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -53,7 +57,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.msl
index e349da5..e555811 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -30,7 +33,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.spvasm
index 11b57d4..a1acf35 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -57,87 +57,83 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %50 = OpTypeFunction %void %_arr_S_uint_4
+         %47 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
        %bool = OpTypeBool
 %_ptr_Function_S = OpTypePointer Function %S
-         %72 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %69 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-     %uint_2 = OpConstant %uint 2
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
          %23 = OpFunctionCall %void %tint_store_and_preserve_padding %22
-         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %28 = OpLoad %S %25 None
-         %29 = OpBitcast %uint %int_1
-         %33 = OpCompositeConstruct %_arr_uint_uint_1 %29
-         %34 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %33 %28
-         %36 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %12 %uint_0 %int_3 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2 %uint_1
-         %41 = OpLoad %mat3v4float %39 None
-               OpStore %36 %41 None
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %int_1 %uint_1 %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %47 = OpLoad %v4float %45 None
-         %48 = OpVectorShuffle %v4float %47 %47 1 3 0 2
-               OpStore %42 %48 None
+         %31 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %32 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %31 %28
+         %34 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %12 %uint_0 %uint_3 %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2 %uint_1
+         %39 = OpLoad %mat3v4float %37 None
+               OpStore %34 %39 None
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %uint_1 %uint_1 %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %44 = OpLoad %v4float %42 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+               OpStore %40 %45 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %50
+%tint_store_and_preserve_padding = OpFunction %void None %47
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %48 = OpLabel
+         %49 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %49 %value_param
+               OpBranch %51
          %51 = OpLabel
-         %52 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %52 %value_param
                OpBranch %54
          %54 = OpLabel
-               OpBranch %57
-         %57 = OpLabel
-         %59 = OpPhi %uint %uint_0 %54 %60 %56
-               OpLoopMerge %58 %56 None
+         %56 = OpPhi %uint %uint_0 %51 %57 %53
+               OpLoopMerge %55 %53 None
+               OpBranch %52
+         %52 = OpLabel
+         %58 = OpUGreaterThanEqual %bool %56 %uint_4
+               OpSelectionMerge %60 None
+               OpBranchConditional %58 %61 %60
+         %61 = OpLabel
                OpBranch %55
+         %60 = OpLabel
+         %62 = OpAccessChain %_ptr_Function_S %49 %56
+         %64 = OpLoad %S %62 None
+         %65 = OpCompositeConstruct %_arr_uint_uint_1 %56
+         %66 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %65 %64
+               OpBranch %53
+         %53 = OpLabel
+         %57 = OpIAdd %uint %56 %uint_1
+               OpBranch %54
          %55 = OpLabel
-         %61 = OpUGreaterThanEqual %bool %59 %uint_4
-               OpSelectionMerge %63 None
-               OpBranchConditional %61 %64 %63
-         %64 = OpLabel
-               OpBranch %58
-         %63 = OpLabel
-         %65 = OpAccessChain %_ptr_Function_S %52 %59
-         %67 = OpLoad %S %65 None
-         %68 = OpCompositeConstruct %_arr_uint_uint_1 %59
-         %69 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %68 %67
-               OpBranch %56
-         %56 = OpLabel
-         %60 = OpIAdd %uint %59 %uint_1
-               OpBranch %57
-         %58 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %72
+%tint_store_and_preserve_padding_0 = OpFunction %void None %69
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-         %73 = OpLabel
-         %74 = OpCompositeExtract %uint %target_indices 0
-         %75 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_0
-         %77 = OpCompositeExtract %int %value_param_0 0
-               OpStore %75 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %12 %uint_0 %74 %uint_1
-         %79 = OpCompositeExtract %mat3v4float %value_param_0 1
-               OpStore %78 %79 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_2
-         %82 = OpCompositeExtract %int %value_param_0 2
-               OpStore %80 %82 None
+         %70 = OpLabel
+         %71 = OpCompositeExtract %uint %target_indices 0
+         %72 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_0
+         %74 = OpCompositeExtract %int %value_param_0 0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %12 %uint_0 %71 %uint_1
+         %76 = OpCompositeExtract %mat3v4float %value_param_0 1
+               OpStore %75 %76 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_2
+         %78 = OpCompositeExtract %int %value_param_0 2
+               OpStore %77 %78 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.glsl
index 53f577f..6834dae 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.glsl
@@ -48,9 +48,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[3].m = v.inner[2].m;
-  w[1].m[0] = v.inner[0].m[1].ywxz;
+  w[1u] = v.inner[2u];
+  w[3u].m = v.inner[2u].m;
+  w[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 9616584..c527c98 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 9616584..c527c98 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(256u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(272u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(272u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
index 0b30ecf..c3c152c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -48,9 +52,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.msl
index 5dd1447..3425faa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -28,6 +31,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
index 2781de6..9cce73b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,16 +55,13 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat3v4float = OpTypePointer Workgroup %mat3v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %63 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -93,24 +90,24 @@
          %39 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %42 = OpLoad %_arr_S_uint_4 %39 None
                OpStore %w %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
-         %48 = OpLoad %S %45 None
-               OpStore %43 %48 None
-         %49 = OpAccessChain %_ptr_Workgroup_mat3v4float %w %int_3 %uint_1
-         %52 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %int_2 %uint_1
-         %54 = OpLoad %mat3v4float %52 None
-               OpStore %49 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %uint_1 %int_0
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %60 = OpLoad %v4float %58 None
-         %61 = OpVectorShuffle %v4float %60 %60 1 3 0 2
-               OpStore %55 %61 None
+         %43 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %44 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
+         %46 = OpLoad %S %44 None
+               OpStore %43 %46 None
+         %47 = OpAccessChain %_ptr_Workgroup_mat3v4float %w %uint_3 %uint_1
+         %50 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0 %uint_2 %uint_1
+         %52 = OpLoad %mat3v4float %50 None
+               OpStore %47 %52 None
+         %53 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_1 %uint_0
+         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %55 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+               OpStore %53 %58 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpLoad %uint %f_local_invocation_index_Input None
+         %63 = OpFunctionCall %void %f_inner %62
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 62a0236..49961db 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -65,18 +65,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 4, 2> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (4u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 4, 2> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (4u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   uint ubo_load_4 = a[scalar_offset_4 / 4][scalar_offset_4 % 4];
   vector<float16_t, 2> l_a_i_a_i_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_4 & 0xFFFF)), float16_t(f16tof32(ubo_load_4 >> 16)));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (4u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (4u * min(uint(tint_symbol_2), 3u))) + (2u * min(uint(tint_symbol_3), 1u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index aa115bf..cb35fb4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -66,10 +66,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat4x2 v_6 = f16mat4x2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2, v.inner[v_4].a[v_5].m_col3);
-  f16vec2 v_7 = v_6[i()];
+  f16vec2 v_7 = v_6[min(uint(i()), 3u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -110,5 +110,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat4x2 l_a_i_a_i_m = v_6;
   f16vec2 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index a2d7997..9df9a75 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -90,16 +90,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_21 = (256u * uint(i()));
-  uint v_22 = (64u * uint(i()));
-  uint v_23 = (4u * uint(i()));
+  uint v_21 = (256u * uint(min(uint(i()), 3u)));
+  uint v_22 = (64u * uint(min(uint(i()), 3u)));
+  uint v_23 = (4u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_16(0u);
   Outer l_a_i = v_13(v_21);
   Inner l_a_i_a[4] = v_8(v_21);
   Inner l_a_i_a_i = v_6((v_21 + v_22));
   matrix<float16_t, 4, 2> l_a_i_a_i_m = v_2((v_21 + v_22));
   vector<float16_t, 2> l_a_i_a_i_m_i = tint_bitcast_to_f16(a[(((v_21 + v_22) + v_23) / 16u)][((((v_21 + v_22) + v_23) % 16u) / 4u)]);
-  uint v_24 = (((v_21 + v_22) + v_23) + (uint(i()) * 2u));
+  uint v_24 = (((v_21 + v_22) + v_23) + (uint(min(uint(i()), 1u)) * 2u));
   uint v_25 = a[(v_24 / 16u)][((v_24 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_25 >> ((((v_24 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 5cf83ad..83621d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half4x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half4x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 2988fc5..cdacfc0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half4x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index e6ac7bd..9053993 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 157
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -76,13 +77,13 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_v2half = OpTypePointer Function %v2half
@@ -92,17 +93,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %67 = OpConstantNull %_arr_Outer_uint_4
+         %74 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %94 = OpConstantNull %_arr_Inner_uint_4
+        %101 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %118 = OpTypeFunction %Inner %Inner_std140
-        %127 = OpTypeFunction %Outer %Outer_std140
+        %127 = OpTypeFunction %Inner %Inner_std140
+        %136 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -113,135 +114,143 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %52 = OpVariable %_ptr_Function_mat4v2half Function
-         %59 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %61 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %67
-         %90 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %92 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
+         %57 = OpVariable %_ptr_Function_mat4v2half Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %68 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %74
+         %97 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %99 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_0
-         %40 = OpLoad %v2half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_1
-         %43 = OpLoad %v2half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_0
          %46 = OpLoad %v2half %44 None
-         %47 = OpAccessChain %_ptr_Uniform_v2half %36 %uint_3
+         %47 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_1
          %49 = OpLoad %v2half %47 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat4v2half %40 %43 %46 %49
-               OpStore %52 %l_a_i_a_i_m
-         %54 = OpFunctionCall %int %i
-         %55 = OpAccessChain %_ptr_Function_v2half %52 %54
-%l_a_i_a_i_m_i = OpLoad %v2half %55 None
-         %58 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %59 %58
-               OpBranch %68
-         %68 = OpLabel
-               OpBranch %71
-         %71 = OpLabel
-         %73 = OpPhi %uint %uint_0 %68 %74 %70
-               OpLoopMerge %72 %70 None
-               OpBranch %69
-         %69 = OpLabel
-         %75 = OpUGreaterThanEqual %bool %73 %uint_4
-               OpSelectionMerge %77 None
-               OpBranchConditional %75 %78 %77
+         %50 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_2
+         %52 = OpLoad %v2half %50 None
+         %53 = OpAccessChain %_ptr_Uniform_v2half %42 %uint_3
+         %54 = OpLoad %v2half %53 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat4v2half %46 %49 %52 %54
+               OpStore %57 %l_a_i_a_i_m
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %33 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Function_v2half %57 %61
+%l_a_i_a_i_m_i = OpLoad %v2half %62 None
+         %65 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %66 %65
+               OpBranch %75
+         %75 = OpLabel
+               OpBranch %78
          %78 = OpLabel
-               OpBranch %72
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %84 None
+               OpBranchConditional %82 %85 %84
+         %85 = OpLabel
+               OpBranch %79
+         %84 = OpLabel
+         %86 = OpAccessChain %_ptr_Function_Outer %68 %80
+         %88 = OpAccessChain %_ptr_Function_Outer_std140 %66 %80
+         %90 = OpLoad %Outer_std140 %88 None
+         %91 = OpFunctionCall %Outer %tint_convert_Outer %90
+               OpStore %86 %91 None
+               OpBranch %77
          %77 = OpLabel
-         %79 = OpAccessChain %_ptr_Function_Outer %61 %73
-         %81 = OpAccessChain %_ptr_Function_Outer_std140 %59 %73
-         %83 = OpLoad %Outer_std140 %81 None
-         %84 = OpFunctionCall %Outer %tint_convert_Outer %83
-               OpStore %79 %84 None
-               OpBranch %70
-         %70 = OpLabel
-         %74 = OpIAdd %uint %73 %uint_1
-               OpBranch %71
-         %72 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %61 None
-         %87 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %87
-         %89 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %90 %89
-               OpBranch %95
-         %95 = OpLabel
-               OpBranch %98
-         %98 = OpLabel
-        %100 = OpPhi %uint %uint_0 %95 %101 %97
-               OpLoopMerge %99 %97 None
-               OpBranch %96
-         %96 = OpLabel
-        %102 = OpUGreaterThanEqual %bool %100 %uint_4
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %103
-        %104 = OpLabel
-               OpBranch %99
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
+         %79 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %68 None
+         %94 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %94
+         %96 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %97 %96
+               OpBranch %102
+        %102 = OpLabel
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpPhi %uint %uint_0 %102 %108 %104
+               OpLoopMerge %106 %104 None
+               OpBranch %103
         %103 = OpLabel
-        %105 = OpAccessChain %_ptr_Function_Inner %92 %100
-        %107 = OpAccessChain %_ptr_Function_Inner_std140 %90 %100
-        %109 = OpLoad %Inner_std140 %107 None
-        %110 = OpFunctionCall %Inner %tint_convert_Inner %109
-               OpStore %105 %110 None
-               OpBranch %97
-         %97 = OpLabel
-        %101 = OpIAdd %uint %100 %uint_1
-               OpBranch %98
-         %99 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %92 None
-        %113 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %113
-        %115 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %115
+        %109 = OpUGreaterThanEqual %bool %107 %uint_4
+               OpSelectionMerge %110 None
+               OpBranchConditional %109 %111 %110
+        %111 = OpLabel
+               OpBranch %106
+        %110 = OpLabel
+        %112 = OpAccessChain %_ptr_Function_Inner %99 %107
+        %114 = OpAccessChain %_ptr_Function_Inner_std140 %97 %107
+        %116 = OpLoad %Inner_std140 %114 None
+        %117 = OpFunctionCall %Inner %tint_convert_Inner %116
+               OpStore %112 %117 None
+               OpBranch %104
+        %104 = OpLabel
+        %108 = OpIAdd %uint %107 %uint_1
+               OpBranch %105
+        %106 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %99 None
+        %120 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %120
+        %122 = OpFunctionCall %int %i
+        %123 = OpBitcast %uint %122
+        %124 = OpExtInst %uint %33 UMin %123 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %124
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %118
+%tint_convert_Inner = OpFunction %Inner None %127
  %tint_input = OpFunctionParameter %Inner_std140
-        %119 = OpLabel
-        %120 = OpCompositeExtract %v2half %tint_input 0
-        %121 = OpCompositeExtract %v2half %tint_input 1
-        %122 = OpCompositeExtract %v2half %tint_input 2
-        %123 = OpCompositeExtract %v2half %tint_input 3
-        %124 = OpCompositeConstruct %mat4v2half %120 %121 %122 %123
-        %125 = OpCompositeConstruct %Inner %124
-               OpReturnValue %125
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %127
-%tint_input_0 = OpFunctionParameter %Outer_std140
         %128 = OpLabel
-        %130 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %131 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
-        %129 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %130 %129
-               OpBranch %132
-        %132 = OpLabel
-               OpBranch %135
-        %135 = OpLabel
-        %137 = OpPhi %uint %uint_0 %132 %138 %134
-               OpLoopMerge %136 %134 None
-               OpBranch %133
-        %133 = OpLabel
-        %139 = OpUGreaterThanEqual %bool %137 %uint_4
-               OpSelectionMerge %140 None
-               OpBranchConditional %139 %141 %140
+        %129 = OpCompositeExtract %v2half %tint_input 0
+        %130 = OpCompositeExtract %v2half %tint_input 1
+        %131 = OpCompositeExtract %v2half %tint_input 2
+        %132 = OpCompositeExtract %v2half %tint_input 3
+        %133 = OpCompositeConstruct %mat4v2half %129 %130 %131 %132
+        %134 = OpCompositeConstruct %Inner %133
+               OpReturnValue %134
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %136
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %137 = OpLabel
+        %139 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %140 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
+        %138 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %139 %138
+               OpBranch %141
         %141 = OpLabel
-               OpBranch %136
-        %140 = OpLabel
-        %142 = OpAccessChain %_ptr_Function_Inner %131 %137
-        %143 = OpAccessChain %_ptr_Function_Inner_std140 %130 %137
-        %144 = OpLoad %Inner_std140 %143 None
-        %145 = OpFunctionCall %Inner %tint_convert_Inner %144
-               OpStore %142 %145 None
-               OpBranch %134
-        %134 = OpLabel
-        %138 = OpIAdd %uint %137 %uint_1
-               OpBranch %135
-        %136 = OpLabel
-        %146 = OpLoad %_arr_Inner_uint_4 %131 None
-        %147 = OpCompositeConstruct %Outer %146
-               OpReturnValue %147
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %uint_0 %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4
+               OpSelectionMerge %149 None
+               OpBranchConditional %148 %150 %149
+        %150 = OpLabel
+               OpBranch %145
+        %149 = OpLabel
+        %151 = OpAccessChain %_ptr_Function_Inner %140 %146
+        %152 = OpAccessChain %_ptr_Function_Inner_std140 %139 %146
+        %153 = OpLoad %Inner_std140 %152 None
+        %154 = OpFunctionCall %Inner %tint_convert_Inner %153
+               OpStore %151 %154 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_1
+               OpBranch %144
+        %145 = OpLabel
+        %155 = OpLoad %_arr_Inner_uint_4 %140 None
+        %156 = OpCompositeConstruct %Outer %155
+               OpReturnValue %156
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
index f9334ca..52e4821 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -61,7 +61,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x2 v_4 = f16mat4x2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2, v.inner[3].a[2].m_col3);
+  f16mat4x2 v_4 = f16mat4x2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2, v.inner[3u].a[2u].m_col3);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))), Outer(Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))))));
   {
@@ -80,8 +80,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))), Inner(f16mat4x2(f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf), f16vec2(0.0hf))));
   {
     uint v_11 = 0u;
@@ -99,8 +99,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat4x2 l_a_3_a_2_m = v_4;
-  f16vec2 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 435b6b2..0248de0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half4x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half4x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
index 6e9fbdd..47ecd58 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 132
+; Bound: 129
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -69,15 +69,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat4v2half
@@ -85,141 +82,141 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %52 = OpConstantNull %_arr_Outer_uint_4
+         %49 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %79 = OpConstantNull %_arr_Inner_uint_4
+         %76 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %102 = OpTypeFunction %Inner %Inner_std140
-        %111 = OpTypeFunction %Outer %Outer_std140
+         %99 = OpTypeFunction %Inner %Inner_std140
+        %108 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %44 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %46 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %52
-         %75 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %77 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
+         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
+         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_0
-         %30 = OpLoad %v2half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_1
-         %33 = OpLoad %v2half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_2
-         %36 = OpLoad %v2half %34 None
-         %37 = OpAccessChain %_ptr_Uniform_v2half %25 %uint_3
-         %39 = OpLoad %v2half %37 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat4v2half %30 %33 %36 %39
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_0
+         %29 = OpLoad %v2half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_1
+         %32 = OpLoad %v2half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_2
+         %34 = OpLoad %v2half %33 None
+         %35 = OpAccessChain %_ptr_Uniform_v2half %24 %uint_3
+         %36 = OpLoad %v2half %35 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat4v2half %29 %32 %34 %36
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2half %l_a_3_a_2_m 1
-         %43 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %44 %43
+         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %41 %40
+               OpBranch %50
+         %50 = OpLabel
                OpBranch %53
          %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
+         %55 = OpPhi %uint %uint_0 %50 %56 %52
+               OpLoopMerge %54 %52 None
+               OpBranch %51
+         %51 = OpLabel
+         %57 = OpUGreaterThanEqual %bool %55 %uint_4
+               OpSelectionMerge %59 None
+               OpBranchConditional %57 %60 %59
+         %60 = OpLabel
                OpBranch %54
+         %59 = OpLabel
+         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
+         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
+         %65 = OpLoad %Outer_std140 %63 None
+         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
+               OpStore %61 %66 None
+               OpBranch %52
+         %52 = OpLabel
+         %56 = OpIAdd %uint %55 %uint_1
+               OpBranch %53
          %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
-         %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_Outer %46 %58
-         %66 = OpAccessChain %_ptr_Function_Outer_std140 %44 %58
-         %68 = OpLoad %Outer_std140 %66 None
-         %69 = OpFunctionCall %Outer %tint_convert_Outer %68
-               OpStore %64 %69 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %46 None
-         %72 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %72
-         %74 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %75 %74
+        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
+         %69 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
+         %71 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %72 %71
+               OpBranch %77
+         %77 = OpLabel
                OpBranch %80
          %80 = OpLabel
-               OpBranch %83
-         %83 = OpLabel
-         %85 = OpPhi %uint %uint_0 %80 %86 %82
-               OpLoopMerge %84 %82 None
+         %82 = OpPhi %uint %uint_0 %77 %83 %79
+               OpLoopMerge %81 %79 None
+               OpBranch %78
+         %78 = OpLabel
+         %84 = OpUGreaterThanEqual %bool %82 %uint_4
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %85
+         %86 = OpLabel
                OpBranch %81
+         %85 = OpLabel
+         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
+         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
+         %91 = OpLoad %Inner_std140 %89 None
+         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
+               OpStore %87 %92 None
+               OpBranch %79
+         %79 = OpLabel
+         %83 = OpIAdd %uint %82 %uint_1
+               OpBranch %80
          %81 = OpLabel
-         %87 = OpUGreaterThanEqual %bool %85 %uint_4
-               OpSelectionMerge %88 None
-               OpBranchConditional %87 %89 %88
-         %89 = OpLabel
-               OpBranch %84
-         %88 = OpLabel
-         %90 = OpAccessChain %_ptr_Function_Inner %77 %85
-         %92 = OpAccessChain %_ptr_Function_Inner_std140 %75 %85
-         %94 = OpLoad %Inner_std140 %92 None
-         %95 = OpFunctionCall %Inner %tint_convert_Inner %94
-               OpStore %90 %95 None
-               OpBranch %82
-         %82 = OpLabel
-         %86 = OpIAdd %uint %85 %uint_1
-               OpBranch %83
-         %84 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %77 None
-         %98 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %98
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
+         %95 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %102
+%tint_convert_Inner = OpFunction %Inner None %99
  %tint_input = OpFunctionParameter %Inner_std140
-        %103 = OpLabel
-        %104 = OpCompositeExtract %v2half %tint_input 0
-        %105 = OpCompositeExtract %v2half %tint_input 1
-        %106 = OpCompositeExtract %v2half %tint_input 2
-        %107 = OpCompositeExtract %v2half %tint_input 3
-        %108 = OpCompositeConstruct %mat4v2half %104 %105 %106 %107
-        %109 = OpCompositeConstruct %Inner %108
-               OpReturnValue %109
+        %100 = OpLabel
+        %101 = OpCompositeExtract %v2half %tint_input 0
+        %102 = OpCompositeExtract %v2half %tint_input 1
+        %103 = OpCompositeExtract %v2half %tint_input 2
+        %104 = OpCompositeExtract %v2half %tint_input 3
+        %105 = OpCompositeConstruct %mat4v2half %101 %102 %103 %104
+        %106 = OpCompositeConstruct %Inner %105
+               OpReturnValue %106
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %111
+%tint_convert_Outer = OpFunction %Outer None %108
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %112 = OpLabel
-        %114 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %115 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
-        %113 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %114 %113
+        %109 = OpLabel
+        %111 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %112 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+        %110 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %111 %110
+               OpBranch %113
+        %113 = OpLabel
                OpBranch %116
         %116 = OpLabel
-               OpBranch %119
-        %119 = OpLabel
-        %121 = OpPhi %uint %uint_0 %116 %122 %118
-               OpLoopMerge %120 %118 None
+        %118 = OpPhi %uint %uint_0 %113 %119 %115
+               OpLoopMerge %117 %115 None
+               OpBranch %114
+        %114 = OpLabel
+        %120 = OpUGreaterThanEqual %bool %118 %uint_4
+               OpSelectionMerge %121 None
+               OpBranchConditional %120 %122 %121
+        %122 = OpLabel
                OpBranch %117
+        %121 = OpLabel
+        %123 = OpAccessChain %_ptr_Function_Inner %112 %118
+        %124 = OpAccessChain %_ptr_Function_Inner_std140 %111 %118
+        %125 = OpLoad %Inner_std140 %124 None
+        %126 = OpFunctionCall %Inner %tint_convert_Inner %125
+               OpStore %123 %126 None
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpIAdd %uint %118 %uint_1
+               OpBranch %116
         %117 = OpLabel
-        %123 = OpUGreaterThanEqual %bool %121 %uint_4
-               OpSelectionMerge %124 None
-               OpBranchConditional %123 %125 %124
-        %125 = OpLabel
-               OpBranch %120
-        %124 = OpLabel
-        %126 = OpAccessChain %_ptr_Function_Inner %115 %121
-        %127 = OpAccessChain %_ptr_Function_Inner_std140 %114 %121
-        %128 = OpLoad %Inner_std140 %127 None
-        %129 = OpFunctionCall %Inner %tint_convert_Inner %128
-               OpStore %126 %129 None
-               OpBranch %118
-        %118 = OpLabel
-        %122 = OpIAdd %uint %121 %uint_1
-               OpBranch %119
-        %120 = OpLabel
-        %130 = OpLoad %_arr_Inner_uint_4 %115 None
-        %131 = OpCompositeConstruct %Outer %130
-               OpReturnValue %131
+        %127 = OpLoad %_arr_Inner_uint_4 %112 None
+        %128 = OpCompositeConstruct %Outer %127
+               OpReturnValue %128
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.glsl
index e0ab6e0..fb6621e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.glsl
@@ -43,7 +43,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat2x4 t = transpose(f16mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3));
-  float16_t l = length(v.inner[0].m_col1.yx);
-  float16_t a = abs(v.inner[0].m_col1.yx[0u]);
+  f16mat2x4 t = transpose(f16mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3));
+  float16_t l = length(v.inner[0u].m_col1.yx);
+  float16_t a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
index 6606bc6..bdcd3e4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -27,7 +27,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half2x4 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].yx);
-  half const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  half2x4 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.spvasm
index 20ecd41..19e0f4d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %39 = OpExtInstImport "GLSL.std.450"
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,34 +50,32 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v2half = OpTypeMatrix %v2half 4
      %v4half = OpTypeVector %half 4
  %mat2v4half = OpTypeMatrix %v4half 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v2half %24 None
-         %27 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_4
-         %28 = OpLoad %v2half %27 None
-         %30 = OpCompositeConstruct %mat4v2half %20 %23 %26 %28
-          %t = OpTranspose %mat2v4half %30
-         %34 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v2half %34 None
-         %37 = OpVectorShuffle %v2half %36 %36 1 0
-          %l = OpExtInst %half %39 Length %37
-         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %41 = OpLoad %v2half %40 None
-         %42 = OpVectorShuffle %v2half %41 %41 1 0
-         %43 = OpCompositeExtract %half %42 0
-          %a = OpExtInst %half %39 FAbs %43
+         %21 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v2half %23 None
+         %26 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_4
+         %27 = OpLoad %v2half %26 None
+         %29 = OpCompositeConstruct %mat4v2half %20 %22 %25 %27
+          %t = OpTranspose %mat2v4half %29
+         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v2half %33 None
+         %35 = OpVectorShuffle %v2half %34 %34 1 0
+          %l = OpExtInst %half %37 Length %35
+         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %39 = OpLoad %v2half %38 None
+         %40 = OpVectorShuffle %v2half %39 %39 1 0
+         %41 = OpCompositeExtract %half %40 0
+          %a = OpExtInst %half %37 FAbs %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.glsl
index ea7adcb..c028b2c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.glsl
@@ -80,8 +80,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat4x2(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2, v_1.inner[2].m_col3));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat4x2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2, v_1.inner[2u].m_col3));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.ir.msl
index f007151..ab79b30 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.ir.msl
@@ -43,8 +43,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.spvasm
index 63bf5ed..f7c93e4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -84,12 +84,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %98 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -148,41 +146,41 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2half %80 None
-         %83 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_4
-         %84 = OpLoad %v2half %83 None
-         %85 = OpCompositeConstruct %mat4v2half %76 %79 %82 %84
-         %86 = OpFunctionCall %void %c %85
-         %87 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %89 = OpLoad %v2half %87 None
-         %90 = OpVectorShuffle %v2half %89 %89 1 0
-         %91 = OpFunctionCall %void %d %90
-         %92 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v2half %92 None
-         %94 = OpVectorShuffle %v2half %93 %93 1 0
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %void %e %95
+         %77 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v2half %79 None
+         %82 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_4
+         %83 = OpLoad %v2half %82 None
+         %84 = OpCompositeConstruct %mat4v2half %76 %78 %81 %83
+         %85 = OpFunctionCall %void %c %84
+         %86 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v2half %86 None
+         %88 = OpVectorShuffle %v2half %87 %87 1 0
+         %89 = OpFunctionCall %void %d %88
+         %90 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %91 = OpLoad %v2half %90 None
+         %92 = OpVectorShuffle %v2half %91 %91 1 0
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %void %e %93
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %98
+%tint_convert_S = OpFunction %S None %96
  %tint_input = OpFunctionParameter %S_std140
-         %99 = OpLabel
-        %100 = OpCompositeExtract %int %tint_input 0
-        %101 = OpCompositeExtract %v2half %tint_input 1
-        %102 = OpCompositeExtract %v2half %tint_input 2
-        %103 = OpCompositeExtract %v2half %tint_input 3
-        %104 = OpCompositeExtract %v2half %tint_input 4
-        %105 = OpCompositeConstruct %mat4v2half %101 %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 5
-        %107 = OpCompositeConstruct %S %100 %105 %106
-               OpReturnValue %107
+         %97 = OpLabel
+         %98 = OpCompositeExtract %int %tint_input 0
+         %99 = OpCompositeExtract %v2half %tint_input 1
+        %100 = OpCompositeExtract %v2half %tint_input 2
+        %101 = OpCompositeExtract %v2half %tint_input 3
+        %102 = OpCompositeExtract %v2half %tint_input 4
+        %103 = OpCompositeConstruct %mat4v2half %99 %100 %101 %102
+        %104 = OpCompositeExtract %int %tint_input 5
+        %105 = OpCompositeConstruct %S %98 %103 %104
+               OpReturnValue %105
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.glsl
index f2bd934..1bca3d6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.glsl
@@ -71,7 +71,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 0996879..8b21c20 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -59,8 +59,8 @@
   S v_15[4] = v_10(0u);
   p = v_15;
   S v_16 = v_6(256u);
-  p[int(1)] = v_16;
-  p[int(3)].m = v_2(260u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  p[1u] = v_16;
+  p[3u].m = v_2(260u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.msl
index c65d312..3f628b9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.spvasm
index fa49495..7ae505d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -72,17 +72,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v2half = OpTypePointer Private %mat4v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v2half = OpTypePointer Private %mat4v2half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-      %int_0 = OpConstant %int 0
-         %79 = OpTypeFunction %S %S_std140
+         %75 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -116,39 +112,39 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat4v2half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_4
-         %70 = OpLoad %v2half %69 None
-         %71 = OpCompositeConstruct %mat4v2half %62 %65 %68 %70
-               OpStore %57 %71 None
-         %72 = OpAccessChain %_ptr_Private_v2half %p %int_1 %uint_1 %int_0
-         %75 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %76 = OpLoad %v2half %75 None
-         %77 = OpVectorShuffle %v2half %76 %76 1 0
-               OpStore %72 %77 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat4v2half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v2half %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_4
+         %67 = OpLoad %v2half %66 None
+         %68 = OpCompositeConstruct %mat4v2half %61 %63 %65 %67
+               OpStore %56 %68 None
+         %69 = OpAccessChain %_ptr_Private_v2half %p %uint_1 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %72 = OpLoad %v2half %71 None
+         %73 = OpVectorShuffle %v2half %72 %72 1 0
+               OpStore %69 %73 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %79
+%tint_convert_S = OpFunction %S None %75
  %tint_input = OpFunctionParameter %S_std140
-         %80 = OpLabel
-         %81 = OpCompositeExtract %int %tint_input 0
-         %82 = OpCompositeExtract %v2half %tint_input 1
-         %83 = OpCompositeExtract %v2half %tint_input 2
-         %84 = OpCompositeExtract %v2half %tint_input 3
-         %85 = OpCompositeExtract %v2half %tint_input 4
-         %86 = OpCompositeConstruct %mat4v2half %82 %83 %84 %85
-         %87 = OpCompositeExtract %int %tint_input 5
-         %88 = OpCompositeConstruct %S %81 %86 %87
-               OpReturnValue %88
+         %76 = OpLabel
+         %77 = OpCompositeExtract %int %tint_input 0
+         %78 = OpCompositeExtract %v2half %tint_input 1
+         %79 = OpCompositeExtract %v2half %tint_input 2
+         %80 = OpCompositeExtract %v2half %tint_input 3
+         %81 = OpCompositeExtract %v2half %tint_input 4
+         %82 = OpCompositeConstruct %mat4v2half %78 %79 %80 %81
+         %83 = OpCompositeExtract %int %tint_input 5
+         %84 = OpCompositeConstruct %S %77 %82 %83
+               OpReturnValue %84
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.glsl
index 68d6765..542b54c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.glsl
@@ -122,8 +122,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.ir.msl
index 72c17d4..54a2314 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -37,6 +40,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -53,7 +57,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.msl
index b80bfe1..909ff81 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half4x2 m;
@@ -30,7 +33,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.spvasm
index 0f1b232..abdaa45 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 125
+; Bound: 120
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -85,20 +85,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-      %int_0 = OpConstant %int 0
-         %85 = OpTypeFunction %void %_arr_S_uint_4
-        %104 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %80 = OpTypeFunction %void %_arr_S_uint_4
+         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %115 = OpTypeFunction %S %S_std140
+        %110 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -132,86 +128,85 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2half %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v2half %72 None
-         %75 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_4
-         %76 = OpLoad %v2half %75 None
-         %77 = OpCompositeConstruct %mat4v2half %68 %71 %74 %76
-               OpStore %63 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %int_1 %uint_1 %int_0
-         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %82 = OpLoad %v2half %81 None
-         %83 = OpVectorShuffle %v2half %82 %82 1 0
-               OpStore %78 %83 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2half %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v2half %69 None
+         %71 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_4
+         %72 = OpLoad %v2half %71 None
+         %73 = OpCompositeConstruct %mat4v2half %66 %68 %70 %72
+               OpStore %61 %73 None
+         %74 = OpAccessChain %_ptr_StorageBuffer_v2half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %77 = OpLoad %v2half %76 None
+         %78 = OpVectorShuffle %v2half %77 %77 1 0
+               OpStore %74 %78 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %85
+%tint_store_and_preserve_padding = OpFunction %void None %80
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %81 = OpLabel
+         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %82 %value_param
+               OpBranch %83
+         %83 = OpLabel
+               OpBranch %86
          %86 = OpLabel
-         %87 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %87 %value_param
-               OpBranch %88
-         %88 = OpLabel
-               OpBranch %91
-         %91 = OpLabel
-         %93 = OpPhi %uint %uint_0 %88 %94 %90
-               OpLoopMerge %92 %90 None
-               OpBranch %89
-         %89 = OpLabel
-         %95 = OpUGreaterThanEqual %bool %93 %uint_4
-               OpSelectionMerge %96 None
-               OpBranchConditional %95 %97 %96
-         %97 = OpLabel
-               OpBranch %92
-         %96 = OpLabel
-         %98 = OpAccessChain %_ptr_Function_S %87 %93
-         %99 = OpLoad %S %98 None
-        %100 = OpCompositeConstruct %_arr_uint_uint_1 %93
-        %101 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %100 %99
-               OpBranch %90
-         %90 = OpLabel
-         %94 = OpIAdd %uint %93 %uint_1
-               OpBranch %91
+         %88 = OpPhi %uint %uint_0 %83 %89 %85
+               OpLoopMerge %87 %85 None
+               OpBranch %84
+         %84 = OpLabel
+         %90 = OpUGreaterThanEqual %bool %88 %uint_4
+               OpSelectionMerge %91 None
+               OpBranchConditional %90 %92 %91
          %92 = OpLabel
+               OpBranch %87
+         %91 = OpLabel
+         %93 = OpAccessChain %_ptr_Function_S %82 %88
+         %94 = OpLoad %S %93 None
+         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
+         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
+               OpBranch %85
+         %85 = OpLabel
+         %89 = OpIAdd %uint %88 %uint_1
+               OpBranch %86
+         %87 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %104
+%tint_store_and_preserve_padding_0 = OpFunction %void None %99
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %105 = OpLabel
-        %106 = OpCompositeExtract %uint %target_indices 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_0
-        %109 = OpCompositeExtract %int %value_param_0 0
-               OpStore %107 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %11 %uint_0 %106 %uint_1
-        %111 = OpCompositeExtract %mat4v2half %value_param_0 1
-               OpStore %110 %111 None
-        %112 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_2
-        %113 = OpCompositeExtract %int %value_param_0 2
-               OpStore %112 %113 None
+        %100 = OpLabel
+        %101 = OpCompositeExtract %uint %target_indices 0
+        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
+        %104 = OpCompositeExtract %int %value_param_0 0
+               OpStore %102 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %11 %uint_0 %101 %uint_1
+        %106 = OpCompositeExtract %mat4v2half %value_param_0 1
+               OpStore %105 %106 None
+        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
+        %108 = OpCompositeExtract %int %value_param_0 2
+               OpStore %107 %108 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %115
+%tint_convert_S = OpFunction %S None %110
  %tint_input = OpFunctionParameter %S_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %int %tint_input 0
-        %118 = OpCompositeExtract %v2half %tint_input 1
-        %119 = OpCompositeExtract %v2half %tint_input 2
-        %120 = OpCompositeExtract %v2half %tint_input 3
-        %121 = OpCompositeExtract %v2half %tint_input 4
-        %122 = OpCompositeConstruct %mat4v2half %118 %119 %120 %121
-        %123 = OpCompositeExtract %int %tint_input 5
-        %124 = OpCompositeConstruct %S %117 %122 %123
-               OpReturnValue %124
+        %111 = OpLabel
+        %112 = OpCompositeExtract %int %tint_input 0
+        %113 = OpCompositeExtract %v2half %tint_input 1
+        %114 = OpCompositeExtract %v2half %tint_input 2
+        %115 = OpCompositeExtract %v2half %tint_input 3
+        %116 = OpCompositeExtract %v2half %tint_input 4
+        %117 = OpCompositeConstruct %mat4v2half %113 %114 %115 %116
+        %118 = OpCompositeExtract %int %tint_input 5
+        %119 = OpCompositeConstruct %S %112 %117 %118
+               OpReturnValue %119
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.glsl
index c191da8..4fad295 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.glsl
@@ -86,9 +86,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 4af271d..e0920cd97 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -79,9 +79,9 @@
   S v_18[4] = v_10(0u);
   w = v_18;
   S v_19 = v_6(256u);
-  w[int(1)] = v_19;
-  w[int(3)].m = v_2(260u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[0u].z).yx;
+  w[1u] = v_19;
+  w[3u].m = v_2(260u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[0u].z).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
index 83dee0c..cacf69bb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -26,6 +26,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -35,6 +38,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -48,9 +52,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.msl
index 4854356..3c5a01a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ half4x2 m;
@@ -28,6 +31,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
index 07032fd..8a18338 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 107
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -81,17 +81,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v2half = OpTypePointer Workgroup %mat4v2half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %void
-        %101 = OpTypeFunction %S %S_std140
+         %92 = OpTypeFunction %void
+         %97 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -148,45 +144,45 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat4v2half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat4v2half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v2half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v2half %83 None
-         %86 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_2 %uint_4
-         %87 = OpLoad %v2half %86 None
-         %88 = OpCompositeConstruct %mat4v2half %80 %82 %85 %87
-               OpStore %75 %88 None
-         %89 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1 %uint_1 %int_0
-         %92 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v2half %92 None
-         %94 = OpVectorShuffle %v2half %93 %93 1 0
-               OpStore %89 %94 None
+         %83 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_2 %uint_4
+         %84 = OpLoad %v2half %83 None
+         %85 = OpCompositeConstruct %mat4v2half %78 %80 %82 %84
+               OpStore %73 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1 %uint_1 %uint_0
+         %88 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v2half %88 None
+         %90 = OpVectorShuffle %v2half %89 %89 1 0
+               OpStore %86 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %96
-         %97 = OpLabel
-         %98 = OpLoad %uint %f_local_invocation_index_Input None
-         %99 = OpFunctionCall %void %f_inner %98
+          %f = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %uint %f_local_invocation_index_Input None
+         %95 = OpFunctionCall %void %f_inner %94
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %101
+%tint_convert_S = OpFunction %S None %97
  %tint_input = OpFunctionParameter %S_std140
-        %102 = OpLabel
-        %103 = OpCompositeExtract %int %tint_input 0
-        %104 = OpCompositeExtract %v2half %tint_input 1
-        %105 = OpCompositeExtract %v2half %tint_input 2
-        %106 = OpCompositeExtract %v2half %tint_input 3
-        %107 = OpCompositeExtract %v2half %tint_input 4
-        %108 = OpCompositeConstruct %mat4v2half %104 %105 %106 %107
-        %109 = OpCompositeExtract %int %tint_input 5
-        %110 = OpCompositeConstruct %S %103 %108 %109
-               OpReturnValue %110
+         %98 = OpLabel
+         %99 = OpCompositeExtract %int %tint_input 0
+        %100 = OpCompositeExtract %v2half %tint_input 1
+        %101 = OpCompositeExtract %v2half %tint_input 2
+        %102 = OpCompositeExtract %v2half %tint_input 3
+        %103 = OpCompositeExtract %v2half %tint_input 4
+        %104 = OpCompositeConstruct %mat4v2half %100 %101 %102 %103
+        %105 = OpCompositeExtract %int %tint_input 5
+        %106 = OpCompositeConstruct %S %99 %104 %105
+               OpReturnValue %106
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 8ae6480..c31f40b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -65,18 +65,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   uint4 ubo_load_4 = a[scalar_offset_4 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 8ae6480..c31f40b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -65,18 +65,18 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x2 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x2 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   uint4 ubo_load_4 = a[scalar_offset_4 / 4];
   float2 l_a_i_a_i_m_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 1u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 09acd19..b59e62e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -61,10 +61,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat4x2 v_6 = mat4x2(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2, v.inner[v_4].a[v_5].m_col3);
-  vec2 v_7 = v_6[i()];
+  vec2 v_7 = v_6[min(uint(i()), 3u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))));
   {
@@ -105,5 +105,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat4x2 l_a_i_a_i_m = v_6;
   vec2 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 76c40e7..f9b3126 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -86,9 +86,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_23 = (256u * uint(i()));
-  uint v_24 = (64u * uint(i()));
-  uint v_25 = (8u * uint(i()));
+  uint v_23 = (256u * uint(min(uint(i()), 3u)));
+  uint v_24 = (64u * uint(min(uint(i()), 3u)));
+  uint v_25 = (8u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_18(0u);
   Outer l_a_i = v_15(v_23);
   Inner l_a_i_a[4] = v_10(v_23);
@@ -96,7 +96,7 @@
   float4x2 l_a_i_a_i_m = v((v_23 + v_24));
   uint4 v_26 = a[(((v_23 + v_24) + v_25) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_23 + v_24) + v_25) % 16u) / 4u) == 2u)) ? (v_26.zw) : (v_26.xy)));
-  uint v_27 = (((v_23 + v_24) + v_25) + (uint(i()) * 4u));
+  uint v_27 = (((v_23 + v_24) + v_25) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_27 / 16u)][((v_27 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 76c40e7..f9b3126 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -86,9 +86,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_23 = (256u * uint(i()));
-  uint v_24 = (64u * uint(i()));
-  uint v_25 = (8u * uint(i()));
+  uint v_23 = (256u * uint(min(uint(i()), 3u)));
+  uint v_24 = (64u * uint(min(uint(i()), 3u)));
+  uint v_25 = (8u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_18(0u);
   Outer l_a_i = v_15(v_23);
   Inner l_a_i_a[4] = v_10(v_23);
@@ -96,7 +96,7 @@
   float4x2 l_a_i_a_i_m = v((v_23 + v_24));
   uint4 v_26 = a[(((v_23 + v_24) + v_25) / 16u)];
   float2 l_a_i_a_i_m_i = asfloat((((((((v_23 + v_24) + v_25) % 16u) / 4u) == 2u)) ? (v_26.zw) : (v_26.xy)));
-  uint v_27 = (((v_23 + v_24) + v_25) + (uint(i()) * 4u));
+  uint v_27 = (((v_23 + v_24) + v_25) + (uint(min(uint(i()), 1u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_27 / 16u)][((v_27 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 216fe03..1679600 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float4x2* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float2* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float4x2 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float2 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index dfb5b40..6ac0fb6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   float4x2 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float2 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 1u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 79ce29a..3555189 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 157
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -73,13 +74,13 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
@@ -89,17 +90,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %67 = OpConstantNull %_arr_Outer_uint_4
+         %74 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %94 = OpConstantNull %_arr_Inner_uint_4
+        %101 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %118 = OpTypeFunction %Inner %Inner_std140
-        %127 = OpTypeFunction %Outer %Outer_std140
+        %127 = OpTypeFunction %Inner %Inner_std140
+        %136 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -110,135 +111,143 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %52 = OpVariable %_ptr_Function_mat4v2float Function
-         %59 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %61 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %67
-         %90 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %92 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
+         %57 = OpVariable %_ptr_Function_mat4v2float Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %68 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %74
+         %97 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %99 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_0
-         %40 = OpLoad %v2float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_1
-         %43 = OpLoad %v2float %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_0
          %46 = OpLoad %v2float %44 None
-         %47 = OpAccessChain %_ptr_Uniform_v2float %36 %uint_3
+         %47 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_1
          %49 = OpLoad %v2float %47 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat4v2float %40 %43 %46 %49
-               OpStore %52 %l_a_i_a_i_m
-         %54 = OpFunctionCall %int %i
-         %55 = OpAccessChain %_ptr_Function_v2float %52 %54
-%l_a_i_a_i_m_i = OpLoad %v2float %55 None
-         %58 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %59 %58
-               OpBranch %68
-         %68 = OpLabel
-               OpBranch %71
-         %71 = OpLabel
-         %73 = OpPhi %uint %uint_0 %68 %74 %70
-               OpLoopMerge %72 %70 None
-               OpBranch %69
-         %69 = OpLabel
-         %75 = OpUGreaterThanEqual %bool %73 %uint_4
-               OpSelectionMerge %77 None
-               OpBranchConditional %75 %78 %77
+         %50 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_2
+         %52 = OpLoad %v2float %50 None
+         %53 = OpAccessChain %_ptr_Uniform_v2float %42 %uint_3
+         %54 = OpLoad %v2float %53 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat4v2float %46 %49 %52 %54
+               OpStore %57 %l_a_i_a_i_m
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %33 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Function_v2float %57 %61
+%l_a_i_a_i_m_i = OpLoad %v2float %62 None
+         %65 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %66 %65
+               OpBranch %75
+         %75 = OpLabel
+               OpBranch %78
          %78 = OpLabel
-               OpBranch %72
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %84 None
+               OpBranchConditional %82 %85 %84
+         %85 = OpLabel
+               OpBranch %79
+         %84 = OpLabel
+         %86 = OpAccessChain %_ptr_Function_Outer %68 %80
+         %88 = OpAccessChain %_ptr_Function_Outer_std140 %66 %80
+         %90 = OpLoad %Outer_std140 %88 None
+         %91 = OpFunctionCall %Outer %tint_convert_Outer %90
+               OpStore %86 %91 None
+               OpBranch %77
          %77 = OpLabel
-         %79 = OpAccessChain %_ptr_Function_Outer %61 %73
-         %81 = OpAccessChain %_ptr_Function_Outer_std140 %59 %73
-         %83 = OpLoad %Outer_std140 %81 None
-         %84 = OpFunctionCall %Outer %tint_convert_Outer %83
-               OpStore %79 %84 None
-               OpBranch %70
-         %70 = OpLabel
-         %74 = OpIAdd %uint %73 %uint_1
-               OpBranch %71
-         %72 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %61 None
-         %87 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %87
-         %89 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %90 %89
-               OpBranch %95
-         %95 = OpLabel
-               OpBranch %98
-         %98 = OpLabel
-        %100 = OpPhi %uint %uint_0 %95 %101 %97
-               OpLoopMerge %99 %97 None
-               OpBranch %96
-         %96 = OpLabel
-        %102 = OpUGreaterThanEqual %bool %100 %uint_4
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %103
-        %104 = OpLabel
-               OpBranch %99
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
+         %79 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %68 None
+         %94 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %94
+         %96 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %97 %96
+               OpBranch %102
+        %102 = OpLabel
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpPhi %uint %uint_0 %102 %108 %104
+               OpLoopMerge %106 %104 None
+               OpBranch %103
         %103 = OpLabel
-        %105 = OpAccessChain %_ptr_Function_Inner %92 %100
-        %107 = OpAccessChain %_ptr_Function_Inner_std140 %90 %100
-        %109 = OpLoad %Inner_std140 %107 None
-        %110 = OpFunctionCall %Inner %tint_convert_Inner %109
-               OpStore %105 %110 None
-               OpBranch %97
-         %97 = OpLabel
-        %101 = OpIAdd %uint %100 %uint_1
-               OpBranch %98
-         %99 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %92 None
-        %113 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %113
-        %115 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %115
+        %109 = OpUGreaterThanEqual %bool %107 %uint_4
+               OpSelectionMerge %110 None
+               OpBranchConditional %109 %111 %110
+        %111 = OpLabel
+               OpBranch %106
+        %110 = OpLabel
+        %112 = OpAccessChain %_ptr_Function_Inner %99 %107
+        %114 = OpAccessChain %_ptr_Function_Inner_std140 %97 %107
+        %116 = OpLoad %Inner_std140 %114 None
+        %117 = OpFunctionCall %Inner %tint_convert_Inner %116
+               OpStore %112 %117 None
+               OpBranch %104
+        %104 = OpLabel
+        %108 = OpIAdd %uint %107 %uint_1
+               OpBranch %105
+        %106 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %99 None
+        %120 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %120
+        %122 = OpFunctionCall %int %i
+        %123 = OpBitcast %uint %122
+        %124 = OpExtInst %uint %33 UMin %123 %uint_1
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %124
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %118
+%tint_convert_Inner = OpFunction %Inner None %127
  %tint_input = OpFunctionParameter %Inner_std140
-        %119 = OpLabel
-        %120 = OpCompositeExtract %v2float %tint_input 0
-        %121 = OpCompositeExtract %v2float %tint_input 1
-        %122 = OpCompositeExtract %v2float %tint_input 2
-        %123 = OpCompositeExtract %v2float %tint_input 3
-        %124 = OpCompositeConstruct %mat4v2float %120 %121 %122 %123
-        %125 = OpCompositeConstruct %Inner %124
-               OpReturnValue %125
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %127
-%tint_input_0 = OpFunctionParameter %Outer_std140
         %128 = OpLabel
-        %130 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %131 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
-        %129 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %130 %129
-               OpBranch %132
-        %132 = OpLabel
-               OpBranch %135
-        %135 = OpLabel
-        %137 = OpPhi %uint %uint_0 %132 %138 %134
-               OpLoopMerge %136 %134 None
-               OpBranch %133
-        %133 = OpLabel
-        %139 = OpUGreaterThanEqual %bool %137 %uint_4
-               OpSelectionMerge %140 None
-               OpBranchConditional %139 %141 %140
+        %129 = OpCompositeExtract %v2float %tint_input 0
+        %130 = OpCompositeExtract %v2float %tint_input 1
+        %131 = OpCompositeExtract %v2float %tint_input 2
+        %132 = OpCompositeExtract %v2float %tint_input 3
+        %133 = OpCompositeConstruct %mat4v2float %129 %130 %131 %132
+        %134 = OpCompositeConstruct %Inner %133
+               OpReturnValue %134
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %136
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %137 = OpLabel
+        %139 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %140 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
+        %138 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %139 %138
+               OpBranch %141
         %141 = OpLabel
-               OpBranch %136
-        %140 = OpLabel
-        %142 = OpAccessChain %_ptr_Function_Inner %131 %137
-        %143 = OpAccessChain %_ptr_Function_Inner_std140 %130 %137
-        %144 = OpLoad %Inner_std140 %143 None
-        %145 = OpFunctionCall %Inner %tint_convert_Inner %144
-               OpStore %142 %145 None
-               OpBranch %134
-        %134 = OpLabel
-        %138 = OpIAdd %uint %137 %uint_1
-               OpBranch %135
-        %136 = OpLabel
-        %146 = OpLoad %_arr_Inner_uint_4 %131 None
-        %147 = OpCompositeConstruct %Outer %146
-               OpReturnValue %147
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %uint_0 %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4
+               OpSelectionMerge %149 None
+               OpBranchConditional %148 %150 %149
+        %150 = OpLabel
+               OpBranch %145
+        %149 = OpLabel
+        %151 = OpAccessChain %_ptr_Function_Inner %140 %146
+        %152 = OpAccessChain %_ptr_Function_Inner_std140 %139 %146
+        %153 = OpLoad %Inner_std140 %152 None
+        %154 = OpFunctionCall %Inner %tint_convert_Inner %153
+               OpStore %151 %154 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_1
+               OpBranch %144
+        %145 = OpLabel
+        %155 = OpLoad %_arr_Inner_uint_4 %140 None
+        %156 = OpCompositeConstruct %Outer %155
+               OpReturnValue %156
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
index 849ce31..8b2bbc9 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -56,7 +56,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x2 v_4 = mat4x2(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2, v.inner[3].a[2].m_col3);
+  mat4x2 v_4 = mat4x2(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2, v.inner[3u].a[2u].m_col3);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))), Outer(Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))))));
   {
@@ -75,8 +75,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))), Inner(mat4x2(vec2(0.0f), vec2(0.0f), vec2(0.0f), vec2(0.0f))));
   {
     uint v_11 = 0u;
@@ -94,8 +94,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat4x2 l_a_3_a_2_m = v_4;
-  vec2 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec2 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 22ca36c..e4bb5e5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float4x2* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float2* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float4x2 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float2 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
index 81ba1cd..6ae5d82 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 132
+; Bound: 129
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -66,15 +66,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat4v2float
@@ -82,141 +79,141 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %52 = OpConstantNull %_arr_Outer_uint_4
+         %49 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %79 = OpConstantNull %_arr_Inner_uint_4
+         %76 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %102 = OpTypeFunction %Inner %Inner_std140
-        %111 = OpTypeFunction %Outer %Outer_std140
+         %99 = OpTypeFunction %Inner %Inner_std140
+        %108 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %44 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %46 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %52
-         %75 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %77 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
+         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
+         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_0
-         %30 = OpLoad %v2float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_1
-         %33 = OpLoad %v2float %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_2
-         %36 = OpLoad %v2float %34 None
-         %37 = OpAccessChain %_ptr_Uniform_v2float %25 %uint_3
-         %39 = OpLoad %v2float %37 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat4v2float %30 %33 %36 %39
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_0
+         %29 = OpLoad %v2float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_1
+         %32 = OpLoad %v2float %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_2
+         %34 = OpLoad %v2float %33 None
+         %35 = OpAccessChain %_ptr_Uniform_v2float %24 %uint_3
+         %36 = OpLoad %v2float %35 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat4v2float %29 %32 %34 %36
 %l_a_3_a_2_m_1 = OpCompositeExtract %v2float %l_a_3_a_2_m 1
-         %43 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %44 %43
+         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %41 %40
+               OpBranch %50
+         %50 = OpLabel
                OpBranch %53
          %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
+         %55 = OpPhi %uint %uint_0 %50 %56 %52
+               OpLoopMerge %54 %52 None
+               OpBranch %51
+         %51 = OpLabel
+         %57 = OpUGreaterThanEqual %bool %55 %uint_4
+               OpSelectionMerge %59 None
+               OpBranchConditional %57 %60 %59
+         %60 = OpLabel
                OpBranch %54
+         %59 = OpLabel
+         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
+         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
+         %65 = OpLoad %Outer_std140 %63 None
+         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
+               OpStore %61 %66 None
+               OpBranch %52
+         %52 = OpLabel
+         %56 = OpIAdd %uint %55 %uint_1
+               OpBranch %53
          %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
-         %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_Outer %46 %58
-         %66 = OpAccessChain %_ptr_Function_Outer_std140 %44 %58
-         %68 = OpLoad %Outer_std140 %66 None
-         %69 = OpFunctionCall %Outer %tint_convert_Outer %68
-               OpStore %64 %69 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %46 None
-         %72 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %72
-         %74 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %75 %74
+        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
+         %69 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
+         %71 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %72 %71
+               OpBranch %77
+         %77 = OpLabel
                OpBranch %80
          %80 = OpLabel
-               OpBranch %83
-         %83 = OpLabel
-         %85 = OpPhi %uint %uint_0 %80 %86 %82
-               OpLoopMerge %84 %82 None
+         %82 = OpPhi %uint %uint_0 %77 %83 %79
+               OpLoopMerge %81 %79 None
+               OpBranch %78
+         %78 = OpLabel
+         %84 = OpUGreaterThanEqual %bool %82 %uint_4
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %85
+         %86 = OpLabel
                OpBranch %81
+         %85 = OpLabel
+         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
+         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
+         %91 = OpLoad %Inner_std140 %89 None
+         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
+               OpStore %87 %92 None
+               OpBranch %79
+         %79 = OpLabel
+         %83 = OpIAdd %uint %82 %uint_1
+               OpBranch %80
          %81 = OpLabel
-         %87 = OpUGreaterThanEqual %bool %85 %uint_4
-               OpSelectionMerge %88 None
-               OpBranchConditional %87 %89 %88
-         %89 = OpLabel
-               OpBranch %84
-         %88 = OpLabel
-         %90 = OpAccessChain %_ptr_Function_Inner %77 %85
-         %92 = OpAccessChain %_ptr_Function_Inner_std140 %75 %85
-         %94 = OpLoad %Inner_std140 %92 None
-         %95 = OpFunctionCall %Inner %tint_convert_Inner %94
-               OpStore %90 %95 None
-               OpBranch %82
-         %82 = OpLabel
-         %86 = OpIAdd %uint %85 %uint_1
-               OpBranch %83
-         %84 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %77 None
-         %98 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %98
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
+         %95 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %102
+%tint_convert_Inner = OpFunction %Inner None %99
  %tint_input = OpFunctionParameter %Inner_std140
-        %103 = OpLabel
-        %104 = OpCompositeExtract %v2float %tint_input 0
-        %105 = OpCompositeExtract %v2float %tint_input 1
-        %106 = OpCompositeExtract %v2float %tint_input 2
-        %107 = OpCompositeExtract %v2float %tint_input 3
-        %108 = OpCompositeConstruct %mat4v2float %104 %105 %106 %107
-        %109 = OpCompositeConstruct %Inner %108
-               OpReturnValue %109
+        %100 = OpLabel
+        %101 = OpCompositeExtract %v2float %tint_input 0
+        %102 = OpCompositeExtract %v2float %tint_input 1
+        %103 = OpCompositeExtract %v2float %tint_input 2
+        %104 = OpCompositeExtract %v2float %tint_input 3
+        %105 = OpCompositeConstruct %mat4v2float %101 %102 %103 %104
+        %106 = OpCompositeConstruct %Inner %105
+               OpReturnValue %106
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %111
+%tint_convert_Outer = OpFunction %Outer None %108
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %112 = OpLabel
-        %114 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %115 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
-        %113 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %114 %113
+        %109 = OpLabel
+        %111 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %112 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+        %110 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %111 %110
+               OpBranch %113
+        %113 = OpLabel
                OpBranch %116
         %116 = OpLabel
-               OpBranch %119
-        %119 = OpLabel
-        %121 = OpPhi %uint %uint_0 %116 %122 %118
-               OpLoopMerge %120 %118 None
+        %118 = OpPhi %uint %uint_0 %113 %119 %115
+               OpLoopMerge %117 %115 None
+               OpBranch %114
+        %114 = OpLabel
+        %120 = OpUGreaterThanEqual %bool %118 %uint_4
+               OpSelectionMerge %121 None
+               OpBranchConditional %120 %122 %121
+        %122 = OpLabel
                OpBranch %117
+        %121 = OpLabel
+        %123 = OpAccessChain %_ptr_Function_Inner %112 %118
+        %124 = OpAccessChain %_ptr_Function_Inner_std140 %111 %118
+        %125 = OpLoad %Inner_std140 %124 None
+        %126 = OpFunctionCall %Inner %tint_convert_Inner %125
+               OpStore %123 %126 None
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpIAdd %uint %118 %uint_1
+               OpBranch %116
         %117 = OpLabel
-        %123 = OpUGreaterThanEqual %bool %121 %uint_4
-               OpSelectionMerge %124 None
-               OpBranchConditional %123 %125 %124
-        %125 = OpLabel
-               OpBranch %120
-        %124 = OpLabel
-        %126 = OpAccessChain %_ptr_Function_Inner %115 %121
-        %127 = OpAccessChain %_ptr_Function_Inner_std140 %114 %121
-        %128 = OpLoad %Inner_std140 %127 None
-        %129 = OpFunctionCall %Inner %tint_convert_Inner %128
-               OpStore %126 %129 None
-               OpBranch %118
-        %118 = OpLabel
-        %122 = OpIAdd %uint %121 %uint_1
-               OpBranch %119
-        %120 = OpLabel
-        %130 = OpLoad %_arr_Inner_uint_4 %115 None
-        %131 = OpCompositeConstruct %Outer %130
-               OpReturnValue %131
+        %127 = OpLoad %_arr_Inner_uint_4 %112 None
+        %128 = OpCompositeConstruct %Outer %127
+               OpReturnValue %128
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.glsl
index 895ed9f..68ba147 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.glsl
@@ -38,7 +38,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat2x4 t = transpose(mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3));
-  float l = length(v.inner[0].m_col1.yx);
-  float a = abs(v.inner[0].m_col1.yx[0u]);
+  mat2x4 t = transpose(mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3));
+  float l = length(v.inner[0u].m_col1.yx);
+  float a = abs(v.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
index 64f2632..740b0b4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float2x4 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].yx);
-  float const a = abs((*tint_module_vars.u)[0].m[1].yx[0u]);
+  float2x4 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].yx);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.spvasm
index 4739e45..c039ed6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
-         %39 = OpExtInstImport "GLSL.std.450"
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -47,34 +47,32 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v2float = OpTypeMatrix %v2float 4
     %v4float = OpTypeVector %float 4
 %mat2v4float = OpTypeMatrix %v4float 2
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v2float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v2float %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v2float %24 None
-         %27 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_4
-         %28 = OpLoad %v2float %27 None
-         %30 = OpCompositeConstruct %mat4v2float %20 %23 %26 %28
-          %t = OpTranspose %mat2v4float %30
-         %34 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v2float %34 None
-         %37 = OpVectorShuffle %v2float %36 %36 1 0
-          %l = OpExtInst %float %39 Length %37
-         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %41 = OpLoad %v2float %40 None
-         %42 = OpVectorShuffle %v2float %41 %41 1 0
-         %43 = OpCompositeExtract %float %42 0
-          %a = OpExtInst %float %39 FAbs %43
+         %21 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v2float %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v2float %23 None
+         %26 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_4
+         %27 = OpLoad %v2float %26 None
+         %29 = OpCompositeConstruct %mat4v2float %20 %22 %25 %27
+          %t = OpTranspose %mat2v4float %29
+         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v2float %33 None
+         %35 = OpVectorShuffle %v2float %34 %34 1 0
+          %l = OpExtInst %float %37 Length %35
+         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %39 = OpLoad %v2float %38 None
+         %40 = OpVectorShuffle %v2float %39 %39 1 0
+         %41 = OpCompositeExtract %float %40 0
+          %a = OpExtInst %float %37 FAbs %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.glsl
index 8e3fd65..c54d3b0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.glsl
@@ -75,8 +75,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat4x2(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2, v_1.inner[2].m_col3));
-  d(v_1.inner[0].m_col1.yx);
-  e(v_1.inner[0].m_col1.yx[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat4x2(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2, v_1.inner[2u].m_col3));
+  d(v_1.inner[0u].m_col1.yx);
+  e(v_1.inner[0u].m_col1.yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.ir.msl
index e458897..4d80f9d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].yx);
-  e((*tint_module_vars.u)[0].m[1].yx[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].yx);
+  e((*tint_module_vars.u)[0u].m[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.spvasm
index 2258619..954ce1d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -81,12 +81,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %98 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -145,41 +143,41 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v2float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v2float %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v2float %80 None
-         %83 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_4
-         %84 = OpLoad %v2float %83 None
-         %85 = OpCompositeConstruct %mat4v2float %76 %79 %82 %84
-         %86 = OpFunctionCall %void %c %85
-         %87 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %89 = OpLoad %v2float %87 None
-         %90 = OpVectorShuffle %v2float %89 %89 1 0
-         %91 = OpFunctionCall %void %d %90
-         %92 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v2float %92 None
-         %94 = OpVectorShuffle %v2float %93 %93 1 0
-         %95 = OpCompositeExtract %float %94 0
-         %96 = OpFunctionCall %void %e %95
+         %77 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v2float %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v2float %79 None
+         %82 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_4
+         %83 = OpLoad %v2float %82 None
+         %84 = OpCompositeConstruct %mat4v2float %76 %78 %81 %83
+         %85 = OpFunctionCall %void %c %84
+         %86 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v2float %86 None
+         %88 = OpVectorShuffle %v2float %87 %87 1 0
+         %89 = OpFunctionCall %void %d %88
+         %90 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %91 = OpLoad %v2float %90 None
+         %92 = OpVectorShuffle %v2float %91 %91 1 0
+         %93 = OpCompositeExtract %float %92 0
+         %94 = OpFunctionCall %void %e %93
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %98
+%tint_convert_S = OpFunction %S None %96
  %tint_input = OpFunctionParameter %S_std140
-         %99 = OpLabel
-        %100 = OpCompositeExtract %int %tint_input 0
-        %101 = OpCompositeExtract %v2float %tint_input 1
-        %102 = OpCompositeExtract %v2float %tint_input 2
-        %103 = OpCompositeExtract %v2float %tint_input 3
-        %104 = OpCompositeExtract %v2float %tint_input 4
-        %105 = OpCompositeConstruct %mat4v2float %101 %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 5
-        %107 = OpCompositeConstruct %S %100 %105 %106
-               OpReturnValue %107
+         %97 = OpLabel
+         %98 = OpCompositeExtract %int %tint_input 0
+         %99 = OpCompositeExtract %v2float %tint_input 1
+        %100 = OpCompositeExtract %v2float %tint_input 2
+        %101 = OpCompositeExtract %v2float %tint_input 3
+        %102 = OpCompositeExtract %v2float %tint_input 4
+        %103 = OpCompositeConstruct %mat4v2float %99 %100 %101 %102
+        %104 = OpCompositeExtract %int %tint_input 5
+        %105 = OpCompositeConstruct %S %98 %103 %104
+               OpReturnValue %105
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.glsl
index ceb5290..23ff98b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.glsl
@@ -66,7 +66,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  p[1].m[0] = v.inner[0].m_col1.yx;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  p[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 53d19ea..346a5d6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -55,8 +55,8 @@
   S v_17[4] = v_12(0u);
   p = v_17;
   S v_18 = v_8(256u);
-  p[int(1)] = v_18;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_18;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 53d19ea..346a5d6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -55,8 +55,8 @@
   S v_17[4] = v_12(0u);
   p = v_17;
   S v_18 = v_8(256u);
-  p[int(1)] = v_18;
-  p[int(3)].m = v(264u);
-  p[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  p[1u] = v_18;
+  p[3u].m = v(264u);
+  p[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.msl
index cc27fbf..528836c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.spvasm
index 4e3cc0a..3a7aa04 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -69,17 +69,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v2float = OpTypePointer Private %mat4v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v2float = OpTypePointer Private %mat4v2float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-      %int_0 = OpConstant %int 0
-         %79 = OpTypeFunction %S %S_std140
+         %75 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -113,39 +109,39 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat4v2float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v2float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v2float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v2float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_4
-         %70 = OpLoad %v2float %69 None
-         %71 = OpCompositeConstruct %mat4v2float %62 %65 %68 %70
-               OpStore %57 %71 None
-         %72 = OpAccessChain %_ptr_Private_v2float %p %int_1 %uint_1 %int_0
-         %75 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %76 = OpLoad %v2float %75 None
-         %77 = OpVectorShuffle %v2float %76 %76 1 0
-               OpStore %72 %77 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat4v2float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v2float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v2float %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v2float %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_4
+         %67 = OpLoad %v2float %66 None
+         %68 = OpCompositeConstruct %mat4v2float %61 %63 %65 %67
+               OpStore %56 %68 None
+         %69 = OpAccessChain %_ptr_Private_v2float %p %uint_1 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %72 = OpLoad %v2float %71 None
+         %73 = OpVectorShuffle %v2float %72 %72 1 0
+               OpStore %69 %73 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %79
+%tint_convert_S = OpFunction %S None %75
  %tint_input = OpFunctionParameter %S_std140
-         %80 = OpLabel
-         %81 = OpCompositeExtract %int %tint_input 0
-         %82 = OpCompositeExtract %v2float %tint_input 1
-         %83 = OpCompositeExtract %v2float %tint_input 2
-         %84 = OpCompositeExtract %v2float %tint_input 3
-         %85 = OpCompositeExtract %v2float %tint_input 4
-         %86 = OpCompositeConstruct %mat4v2float %82 %83 %84 %85
-         %87 = OpCompositeExtract %int %tint_input 5
-         %88 = OpCompositeConstruct %S %81 %86 %87
-               OpReturnValue %88
+         %76 = OpLabel
+         %77 = OpCompositeExtract %int %tint_input 0
+         %78 = OpCompositeExtract %v2float %tint_input 1
+         %79 = OpCompositeExtract %v2float %tint_input 2
+         %80 = OpCompositeExtract %v2float %tint_input 3
+         %81 = OpCompositeExtract %v2float %tint_input 4
+         %82 = OpCompositeConstruct %mat4v2float %78 %79 %80 %81
+         %83 = OpCompositeExtract %int %tint_input 5
+         %84 = OpCompositeConstruct %S %77 %82 %83
+               OpReturnValue %84
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.glsl
index 5004795..b5afccd 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.glsl
@@ -113,8 +113,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.yx;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.ir.msl
index 5953e94..1bd34e4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.msl
index 16ec5d1..910132a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.spvasm
index 0069a27..83daa46 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 125
+; Bound: 120
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -82,20 +82,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-      %int_0 = OpConstant %int 0
-         %85 = OpTypeFunction %void %_arr_S_uint_4
-        %104 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %80 = OpTypeFunction %void %_arr_S_uint_4
+         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %115 = OpTypeFunction %S %S_std140
+        %110 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -129,86 +125,85 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v2float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v2float %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v2float %72 None
-         %75 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_4
-         %76 = OpLoad %v2float %75 None
-         %77 = OpCompositeConstruct %mat4v2float %68 %71 %74 %76
-               OpStore %63 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %int_1 %uint_1 %int_0
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %82 = OpLoad %v2float %81 None
-         %83 = OpVectorShuffle %v2float %82 %82 1 0
-               OpStore %78 %83 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v2float %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v2float %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v2float %69 None
+         %71 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_4
+         %72 = OpLoad %v2float %71 None
+         %73 = OpCompositeConstruct %mat4v2float %66 %68 %70 %72
+               OpStore %61 %73 None
+         %74 = OpAccessChain %_ptr_StorageBuffer_v2float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %77 = OpLoad %v2float %76 None
+         %78 = OpVectorShuffle %v2float %77 %77 1 0
+               OpStore %74 %78 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %85
+%tint_store_and_preserve_padding = OpFunction %void None %80
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %81 = OpLabel
+         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %82 %value_param
+               OpBranch %83
+         %83 = OpLabel
+               OpBranch %86
          %86 = OpLabel
-         %87 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %87 %value_param
-               OpBranch %88
-         %88 = OpLabel
-               OpBranch %91
-         %91 = OpLabel
-         %93 = OpPhi %uint %uint_0 %88 %94 %90
-               OpLoopMerge %92 %90 None
-               OpBranch %89
-         %89 = OpLabel
-         %95 = OpUGreaterThanEqual %bool %93 %uint_4
-               OpSelectionMerge %96 None
-               OpBranchConditional %95 %97 %96
-         %97 = OpLabel
-               OpBranch %92
-         %96 = OpLabel
-         %98 = OpAccessChain %_ptr_Function_S %87 %93
-         %99 = OpLoad %S %98 None
-        %100 = OpCompositeConstruct %_arr_uint_uint_1 %93
-        %101 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %100 %99
-               OpBranch %90
-         %90 = OpLabel
-         %94 = OpIAdd %uint %93 %uint_1
-               OpBranch %91
+         %88 = OpPhi %uint %uint_0 %83 %89 %85
+               OpLoopMerge %87 %85 None
+               OpBranch %84
+         %84 = OpLabel
+         %90 = OpUGreaterThanEqual %bool %88 %uint_4
+               OpSelectionMerge %91 None
+               OpBranchConditional %90 %92 %91
          %92 = OpLabel
+               OpBranch %87
+         %91 = OpLabel
+         %93 = OpAccessChain %_ptr_Function_S %82 %88
+         %94 = OpLoad %S %93 None
+         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
+         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
+               OpBranch %85
+         %85 = OpLabel
+         %89 = OpIAdd %uint %88 %uint_1
+               OpBranch %86
+         %87 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %104
+%tint_store_and_preserve_padding_0 = OpFunction %void None %99
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %105 = OpLabel
-        %106 = OpCompositeExtract %uint %target_indices 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_0
-        %109 = OpCompositeExtract %int %value_param_0 0
-               OpStore %107 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %11 %uint_0 %106 %uint_1
-        %111 = OpCompositeExtract %mat4v2float %value_param_0 1
-               OpStore %110 %111 None
-        %112 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_2
-        %113 = OpCompositeExtract %int %value_param_0 2
-               OpStore %112 %113 None
+        %100 = OpLabel
+        %101 = OpCompositeExtract %uint %target_indices 0
+        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
+        %104 = OpCompositeExtract %int %value_param_0 0
+               OpStore %102 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %11 %uint_0 %101 %uint_1
+        %106 = OpCompositeExtract %mat4v2float %value_param_0 1
+               OpStore %105 %106 None
+        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
+        %108 = OpCompositeExtract %int %value_param_0 2
+               OpStore %107 %108 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %115
+%tint_convert_S = OpFunction %S None %110
  %tint_input = OpFunctionParameter %S_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %int %tint_input 0
-        %118 = OpCompositeExtract %v2float %tint_input 1
-        %119 = OpCompositeExtract %v2float %tint_input 2
-        %120 = OpCompositeExtract %v2float %tint_input 3
-        %121 = OpCompositeExtract %v2float %tint_input 4
-        %122 = OpCompositeConstruct %mat4v2float %118 %119 %120 %121
-        %123 = OpCompositeExtract %int %tint_input 5
-        %124 = OpCompositeConstruct %S %117 %122 %123
-               OpReturnValue %124
+        %111 = OpLabel
+        %112 = OpCompositeExtract %int %tint_input 0
+        %113 = OpCompositeExtract %v2float %tint_input 1
+        %114 = OpCompositeExtract %v2float %tint_input 2
+        %115 = OpCompositeExtract %v2float %tint_input 3
+        %116 = OpCompositeExtract %v2float %tint_input 4
+        %117 = OpCompositeConstruct %mat4v2float %113 %114 %115 %116
+        %118 = OpCompositeExtract %int %tint_input 5
+        %119 = OpCompositeConstruct %S %112 %117 %118
+               OpReturnValue %119
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.glsl
index 07f81bb..0283d2c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.glsl
@@ -81,9 +81,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat4x2(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  w[1].m[0] = v.inner[0].m_col1.yx;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat4x2(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  w[1u].m[0u] = v.inner[0u].m_col1.yx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 571bf38..dacba94 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -75,9 +75,9 @@
   S v_20[4] = v_12(0u);
   w = v_20;
   S v_21 = v_8(256u);
-  w[int(1)] = v_21;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_21;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 571bf38..dacba94 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -75,9 +75,9 @@
   S v_20[4] = v_12(0u);
   w = v_20;
   S v_21 = v_8(256u);
-  w[int(1)] = v_21;
-  w[int(3)].m = v(264u);
-  w[int(1)].m[int(0)] = asfloat(u[1u].xy).yx;
+  w[1u] = v_21;
+  w[3u].m = v(264u);
+  w[1u].m[0u] = asfloat(u[1u].xy).yx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
index 4a0d100..9d4b9ea 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].yx;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].yx;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.msl
index ffe4ddc..a1a2e9d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
index 2bc5a26..3d4480f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 107
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -78,17 +78,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v2float = OpTypePointer Workgroup %mat4v2float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %void
-        %101 = OpTypeFunction %S %S_std140
+         %92 = OpTypeFunction %void
+         %97 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -145,45 +141,45 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat4v2float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v2float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat4v2float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v2float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v2float %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v2float %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v2float %83 None
-         %86 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_2 %uint_4
-         %87 = OpLoad %v2float %86 None
-         %88 = OpCompositeConstruct %mat4v2float %80 %82 %85 %87
-               OpStore %75 %88 None
-         %89 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1 %uint_1 %int_0
-         %92 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v2float %92 None
-         %94 = OpVectorShuffle %v2float %93 %93 1 0
-               OpStore %89 %94 None
+         %83 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_2 %uint_4
+         %84 = OpLoad %v2float %83 None
+         %85 = OpCompositeConstruct %mat4v2float %78 %80 %82 %84
+               OpStore %73 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1 %uint_1 %uint_0
+         %88 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v2float %88 None
+         %90 = OpVectorShuffle %v2float %89 %89 1 0
+               OpStore %86 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %96
-         %97 = OpLabel
-         %98 = OpLoad %uint %f_local_invocation_index_Input None
-         %99 = OpFunctionCall %void %f_inner %98
+          %f = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %uint %f_local_invocation_index_Input None
+         %95 = OpFunctionCall %void %f_inner %94
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %101
+%tint_convert_S = OpFunction %S None %97
  %tint_input = OpFunctionParameter %S_std140
-        %102 = OpLabel
-        %103 = OpCompositeExtract %int %tint_input 0
-        %104 = OpCompositeExtract %v2float %tint_input 1
-        %105 = OpCompositeExtract %v2float %tint_input 2
-        %106 = OpCompositeExtract %v2float %tint_input 3
-        %107 = OpCompositeExtract %v2float %tint_input 4
-        %108 = OpCompositeConstruct %mat4v2float %104 %105 %106 %107
-        %109 = OpCompositeExtract %int %tint_input 5
-        %110 = OpCompositeConstruct %S %103 %108 %109
-               OpReturnValue %110
+         %98 = OpLabel
+         %99 = OpCompositeExtract %int %tint_input 0
+        %100 = OpCompositeExtract %v2float %tint_input 1
+        %101 = OpCompositeExtract %v2float %tint_input 2
+        %102 = OpCompositeExtract %v2float %tint_input 3
+        %103 = OpCompositeExtract %v2float %tint_input 4
+        %104 = OpCompositeConstruct %mat4v2float %100 %101 %102 %103
+        %105 = OpCompositeExtract %int %tint_input 5
+        %106 = OpCompositeConstruct %S %99 %104 %105
+               OpReturnValue %106
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 1d3a5ec..aadbea0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -77,11 +77,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 4, 3> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 4, 3> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   uint4 ubo_load_9 = a[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
@@ -91,7 +91,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 3u))) + (2u * min(uint(tint_symbol_3), 2u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 95f8b41..b700b3a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -62,10 +62,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat4x3 v_6 = f16mat4x3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2, v.inner[v_4].a[v_5].m_col3);
-  f16vec3 v_7 = v_6[i()];
+  f16vec3 v_7 = v_6[min(uint(i()), 3u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -106,5 +106,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat4x3 l_a_i_a_i_m = v_6;
   f16vec3 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index c025f59..10a41cb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -98,9 +98,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_27 = (256u * uint(i()));
-  uint v_28 = (64u * uint(i()));
-  uint v_29 = (8u * uint(i()));
+  uint v_27 = (256u * uint(min(uint(i()), 3u)));
+  uint v_28 = (64u * uint(min(uint(i()), 3u)));
+  uint v_29 = (8u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_22(0u);
   Outer l_a_i = v_19(v_27);
   Inner l_a_i_a[4] = v_14(v_27);
@@ -108,7 +108,7 @@
   matrix<float16_t, 4, 3> l_a_i_a_i_m = v_4((v_27 + v_28));
   uint4 v_30 = a[(((v_27 + v_28) + v_29) / 16u)];
   vector<float16_t, 3> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_27 + v_28) + v_29) % 16u) / 4u) == 2u)) ? (v_30.zw) : (v_30.xy))).xyz;
-  uint v_31 = (((v_27 + v_28) + v_29) + (uint(i()) * 2u));
+  uint v_31 = (((v_27 + v_28) + v_29) + (uint(min(uint(i()), 2u)) * 2u));
   uint v_32 = a[(v_31 / 16u)][((v_31 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_32 >> ((((v_31 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 4c23dec..3dd8fee 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -75,11 +75,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -90,5 +90,5 @@
   half3 const v_13 = half3(v_10[2u].packed);
   half4x3 const l_a_i_a_i_m = half4x3(v_11, v_12, v_13, half3(v_10[3u].packed));
   half3 const l_a_i_a_i_m_i = half3((*p_a_i_a_i_m_i));
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index e3d1ef1..97c8f33 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -76,11 +76,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -88,7 +88,7 @@
   half4x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   half3 const l_a_i_a_i_m_i = half3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index c70ba45..d99ff6e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 157
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -76,13 +77,13 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
 %_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
 %_ptr_Function_v3half = OpTypePointer Function %v3half
@@ -92,17 +93,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %67 = OpConstantNull %_arr_Outer_uint_4
+         %74 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %94 = OpConstantNull %_arr_Inner_uint_4
+        %101 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %118 = OpTypeFunction %Inner %Inner_std140
-        %127 = OpTypeFunction %Outer %Outer_std140
+        %127 = OpTypeFunction %Inner %Inner_std140
+        %136 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -113,135 +114,143 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %52 = OpVariable %_ptr_Function_mat4v3half Function
-         %59 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %61 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %67
-         %90 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %92 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
+         %57 = OpVariable %_ptr_Function_mat4v3half Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %68 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %74
+         %97 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %99 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_0
-         %40 = OpLoad %v3half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_1
-         %43 = OpLoad %v3half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_0
          %46 = OpLoad %v3half %44 None
-         %47 = OpAccessChain %_ptr_Uniform_v3half %36 %uint_3
+         %47 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_1
          %49 = OpLoad %v3half %47 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat4v3half %40 %43 %46 %49
-               OpStore %52 %l_a_i_a_i_m
-         %54 = OpFunctionCall %int %i
-         %55 = OpAccessChain %_ptr_Function_v3half %52 %54
-%l_a_i_a_i_m_i = OpLoad %v3half %55 None
-         %58 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %59 %58
-               OpBranch %68
-         %68 = OpLabel
-               OpBranch %71
-         %71 = OpLabel
-         %73 = OpPhi %uint %uint_0 %68 %74 %70
-               OpLoopMerge %72 %70 None
-               OpBranch %69
-         %69 = OpLabel
-         %75 = OpUGreaterThanEqual %bool %73 %uint_4
-               OpSelectionMerge %77 None
-               OpBranchConditional %75 %78 %77
+         %50 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_2
+         %52 = OpLoad %v3half %50 None
+         %53 = OpAccessChain %_ptr_Uniform_v3half %42 %uint_3
+         %54 = OpLoad %v3half %53 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat4v3half %46 %49 %52 %54
+               OpStore %57 %l_a_i_a_i_m
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %33 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Function_v3half %57 %61
+%l_a_i_a_i_m_i = OpLoad %v3half %62 None
+         %65 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %66 %65
+               OpBranch %75
+         %75 = OpLabel
+               OpBranch %78
          %78 = OpLabel
-               OpBranch %72
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %84 None
+               OpBranchConditional %82 %85 %84
+         %85 = OpLabel
+               OpBranch %79
+         %84 = OpLabel
+         %86 = OpAccessChain %_ptr_Function_Outer %68 %80
+         %88 = OpAccessChain %_ptr_Function_Outer_std140 %66 %80
+         %90 = OpLoad %Outer_std140 %88 None
+         %91 = OpFunctionCall %Outer %tint_convert_Outer %90
+               OpStore %86 %91 None
+               OpBranch %77
          %77 = OpLabel
-         %79 = OpAccessChain %_ptr_Function_Outer %61 %73
-         %81 = OpAccessChain %_ptr_Function_Outer_std140 %59 %73
-         %83 = OpLoad %Outer_std140 %81 None
-         %84 = OpFunctionCall %Outer %tint_convert_Outer %83
-               OpStore %79 %84 None
-               OpBranch %70
-         %70 = OpLabel
-         %74 = OpIAdd %uint %73 %uint_1
-               OpBranch %71
-         %72 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %61 None
-         %87 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %87
-         %89 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %90 %89
-               OpBranch %95
-         %95 = OpLabel
-               OpBranch %98
-         %98 = OpLabel
-        %100 = OpPhi %uint %uint_0 %95 %101 %97
-               OpLoopMerge %99 %97 None
-               OpBranch %96
-         %96 = OpLabel
-        %102 = OpUGreaterThanEqual %bool %100 %uint_4
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %103
-        %104 = OpLabel
-               OpBranch %99
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
+         %79 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %68 None
+         %94 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %94
+         %96 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %97 %96
+               OpBranch %102
+        %102 = OpLabel
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpPhi %uint %uint_0 %102 %108 %104
+               OpLoopMerge %106 %104 None
+               OpBranch %103
         %103 = OpLabel
-        %105 = OpAccessChain %_ptr_Function_Inner %92 %100
-        %107 = OpAccessChain %_ptr_Function_Inner_std140 %90 %100
-        %109 = OpLoad %Inner_std140 %107 None
-        %110 = OpFunctionCall %Inner %tint_convert_Inner %109
-               OpStore %105 %110 None
-               OpBranch %97
-         %97 = OpLabel
-        %101 = OpIAdd %uint %100 %uint_1
-               OpBranch %98
-         %99 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %92 None
-        %113 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %113
-        %115 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %115
+        %109 = OpUGreaterThanEqual %bool %107 %uint_4
+               OpSelectionMerge %110 None
+               OpBranchConditional %109 %111 %110
+        %111 = OpLabel
+               OpBranch %106
+        %110 = OpLabel
+        %112 = OpAccessChain %_ptr_Function_Inner %99 %107
+        %114 = OpAccessChain %_ptr_Function_Inner_std140 %97 %107
+        %116 = OpLoad %Inner_std140 %114 None
+        %117 = OpFunctionCall %Inner %tint_convert_Inner %116
+               OpStore %112 %117 None
+               OpBranch %104
+        %104 = OpLabel
+        %108 = OpIAdd %uint %107 %uint_1
+               OpBranch %105
+        %106 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %99 None
+        %120 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %120
+        %122 = OpFunctionCall %int %i
+        %123 = OpBitcast %uint %122
+        %124 = OpExtInst %uint %33 UMin %123 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %124
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %118
+%tint_convert_Inner = OpFunction %Inner None %127
  %tint_input = OpFunctionParameter %Inner_std140
-        %119 = OpLabel
-        %120 = OpCompositeExtract %v3half %tint_input 0
-        %121 = OpCompositeExtract %v3half %tint_input 1
-        %122 = OpCompositeExtract %v3half %tint_input 2
-        %123 = OpCompositeExtract %v3half %tint_input 3
-        %124 = OpCompositeConstruct %mat4v3half %120 %121 %122 %123
-        %125 = OpCompositeConstruct %Inner %124
-               OpReturnValue %125
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %127
-%tint_input_0 = OpFunctionParameter %Outer_std140
         %128 = OpLabel
-        %130 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %131 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
-        %129 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %130 %129
-               OpBranch %132
-        %132 = OpLabel
-               OpBranch %135
-        %135 = OpLabel
-        %137 = OpPhi %uint %uint_0 %132 %138 %134
-               OpLoopMerge %136 %134 None
-               OpBranch %133
-        %133 = OpLabel
-        %139 = OpUGreaterThanEqual %bool %137 %uint_4
-               OpSelectionMerge %140 None
-               OpBranchConditional %139 %141 %140
+        %129 = OpCompositeExtract %v3half %tint_input 0
+        %130 = OpCompositeExtract %v3half %tint_input 1
+        %131 = OpCompositeExtract %v3half %tint_input 2
+        %132 = OpCompositeExtract %v3half %tint_input 3
+        %133 = OpCompositeConstruct %mat4v3half %129 %130 %131 %132
+        %134 = OpCompositeConstruct %Inner %133
+               OpReturnValue %134
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %136
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %137 = OpLabel
+        %139 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %140 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
+        %138 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %139 %138
+               OpBranch %141
         %141 = OpLabel
-               OpBranch %136
-        %140 = OpLabel
-        %142 = OpAccessChain %_ptr_Function_Inner %131 %137
-        %143 = OpAccessChain %_ptr_Function_Inner_std140 %130 %137
-        %144 = OpLoad %Inner_std140 %143 None
-        %145 = OpFunctionCall %Inner %tint_convert_Inner %144
-               OpStore %142 %145 None
-               OpBranch %134
-        %134 = OpLabel
-        %138 = OpIAdd %uint %137 %uint_1
-               OpBranch %135
-        %136 = OpLabel
-        %146 = OpLoad %_arr_Inner_uint_4 %131 None
-        %147 = OpCompositeConstruct %Outer %146
-               OpReturnValue %147
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %uint_0 %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4
+               OpSelectionMerge %149 None
+               OpBranchConditional %148 %150 %149
+        %150 = OpLabel
+               OpBranch %145
+        %149 = OpLabel
+        %151 = OpAccessChain %_ptr_Function_Inner %140 %146
+        %152 = OpAccessChain %_ptr_Function_Inner_std140 %139 %146
+        %153 = OpLoad %Inner_std140 %152 None
+        %154 = OpFunctionCall %Inner %tint_convert_Inner %153
+               OpStore %151 %154 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_1
+               OpBranch %144
+        %145 = OpLabel
+        %155 = OpLoad %_arr_Inner_uint_4 %140 None
+        %156 = OpCompositeConstruct %Outer %155
+               OpReturnValue %156
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
index 9f94fc9..48637ac 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -57,7 +57,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4x3 v_4 = f16mat4x3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2, v.inner[3].a[2].m_col3);
+  f16mat4x3 v_4 = f16mat4x3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2, v.inner[3u].a[2u].m_col3);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))), Outer(Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))))));
   {
@@ -76,8 +76,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))), Inner(f16mat4x3(f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf), f16vec3(0.0hf))));
   {
     uint v_11 = 0u;
@@ -95,8 +95,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat4x3 l_a_3_a_2_m = v_4;
-  f16vec3 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index b9d5bbc..c9aa963 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -68,11 +68,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_half3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -83,5 +83,5 @@
   half3 const v_13 = half3(v_10[2u].packed);
   half4x3 const l_a_3_a_2_m = half4x3(v_11, v_12, v_13, half3(v_10[3u].packed));
   half3 const l_a_3_a_2_m_1 = half3((*p_a_3_a_2_m_1));
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
index 77b49f8..dcdff30 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 132
+; Bound: 129
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -69,15 +69,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat4v3half
@@ -85,141 +82,141 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %52 = OpConstantNull %_arr_Outer_uint_4
+         %49 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %79 = OpConstantNull %_arr_Inner_uint_4
+         %76 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %102 = OpTypeFunction %Inner %Inner_std140
-        %111 = OpTypeFunction %Outer %Outer_std140
+         %99 = OpTypeFunction %Inner %Inner_std140
+        %108 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %44 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %46 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %52
-         %75 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %77 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
+         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
+         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_0
-         %30 = OpLoad %v3half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_1
-         %33 = OpLoad %v3half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_2
-         %36 = OpLoad %v3half %34 None
-         %37 = OpAccessChain %_ptr_Uniform_v3half %25 %uint_3
-         %39 = OpLoad %v3half %37 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat4v3half %30 %33 %36 %39
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_0
+         %29 = OpLoad %v3half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_1
+         %32 = OpLoad %v3half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_2
+         %34 = OpLoad %v3half %33 None
+         %35 = OpAccessChain %_ptr_Uniform_v3half %24 %uint_3
+         %36 = OpLoad %v3half %35 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat4v3half %29 %32 %34 %36
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3half %l_a_3_a_2_m 1
-         %43 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %44 %43
+         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %41 %40
+               OpBranch %50
+         %50 = OpLabel
                OpBranch %53
          %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
+         %55 = OpPhi %uint %uint_0 %50 %56 %52
+               OpLoopMerge %54 %52 None
+               OpBranch %51
+         %51 = OpLabel
+         %57 = OpUGreaterThanEqual %bool %55 %uint_4
+               OpSelectionMerge %59 None
+               OpBranchConditional %57 %60 %59
+         %60 = OpLabel
                OpBranch %54
+         %59 = OpLabel
+         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
+         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
+         %65 = OpLoad %Outer_std140 %63 None
+         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
+               OpStore %61 %66 None
+               OpBranch %52
+         %52 = OpLabel
+         %56 = OpIAdd %uint %55 %uint_1
+               OpBranch %53
          %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
-         %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_Outer %46 %58
-         %66 = OpAccessChain %_ptr_Function_Outer_std140 %44 %58
-         %68 = OpLoad %Outer_std140 %66 None
-         %69 = OpFunctionCall %Outer %tint_convert_Outer %68
-               OpStore %64 %69 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %46 None
-         %72 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %72
-         %74 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %75 %74
+        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
+         %69 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
+         %71 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %72 %71
+               OpBranch %77
+         %77 = OpLabel
                OpBranch %80
          %80 = OpLabel
-               OpBranch %83
-         %83 = OpLabel
-         %85 = OpPhi %uint %uint_0 %80 %86 %82
-               OpLoopMerge %84 %82 None
+         %82 = OpPhi %uint %uint_0 %77 %83 %79
+               OpLoopMerge %81 %79 None
+               OpBranch %78
+         %78 = OpLabel
+         %84 = OpUGreaterThanEqual %bool %82 %uint_4
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %85
+         %86 = OpLabel
                OpBranch %81
+         %85 = OpLabel
+         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
+         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
+         %91 = OpLoad %Inner_std140 %89 None
+         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
+               OpStore %87 %92 None
+               OpBranch %79
+         %79 = OpLabel
+         %83 = OpIAdd %uint %82 %uint_1
+               OpBranch %80
          %81 = OpLabel
-         %87 = OpUGreaterThanEqual %bool %85 %uint_4
-               OpSelectionMerge %88 None
-               OpBranchConditional %87 %89 %88
-         %89 = OpLabel
-               OpBranch %84
-         %88 = OpLabel
-         %90 = OpAccessChain %_ptr_Function_Inner %77 %85
-         %92 = OpAccessChain %_ptr_Function_Inner_std140 %75 %85
-         %94 = OpLoad %Inner_std140 %92 None
-         %95 = OpFunctionCall %Inner %tint_convert_Inner %94
-               OpStore %90 %95 None
-               OpBranch %82
-         %82 = OpLabel
-         %86 = OpIAdd %uint %85 %uint_1
-               OpBranch %83
-         %84 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %77 None
-         %98 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %98
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
+         %95 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %102
+%tint_convert_Inner = OpFunction %Inner None %99
  %tint_input = OpFunctionParameter %Inner_std140
-        %103 = OpLabel
-        %104 = OpCompositeExtract %v3half %tint_input 0
-        %105 = OpCompositeExtract %v3half %tint_input 1
-        %106 = OpCompositeExtract %v3half %tint_input 2
-        %107 = OpCompositeExtract %v3half %tint_input 3
-        %108 = OpCompositeConstruct %mat4v3half %104 %105 %106 %107
-        %109 = OpCompositeConstruct %Inner %108
-               OpReturnValue %109
+        %100 = OpLabel
+        %101 = OpCompositeExtract %v3half %tint_input 0
+        %102 = OpCompositeExtract %v3half %tint_input 1
+        %103 = OpCompositeExtract %v3half %tint_input 2
+        %104 = OpCompositeExtract %v3half %tint_input 3
+        %105 = OpCompositeConstruct %mat4v3half %101 %102 %103 %104
+        %106 = OpCompositeConstruct %Inner %105
+               OpReturnValue %106
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %111
+%tint_convert_Outer = OpFunction %Outer None %108
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %112 = OpLabel
-        %114 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %115 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
-        %113 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %114 %113
+        %109 = OpLabel
+        %111 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %112 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+        %110 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %111 %110
+               OpBranch %113
+        %113 = OpLabel
                OpBranch %116
         %116 = OpLabel
-               OpBranch %119
-        %119 = OpLabel
-        %121 = OpPhi %uint %uint_0 %116 %122 %118
-               OpLoopMerge %120 %118 None
+        %118 = OpPhi %uint %uint_0 %113 %119 %115
+               OpLoopMerge %117 %115 None
+               OpBranch %114
+        %114 = OpLabel
+        %120 = OpUGreaterThanEqual %bool %118 %uint_4
+               OpSelectionMerge %121 None
+               OpBranchConditional %120 %122 %121
+        %122 = OpLabel
                OpBranch %117
+        %121 = OpLabel
+        %123 = OpAccessChain %_ptr_Function_Inner %112 %118
+        %124 = OpAccessChain %_ptr_Function_Inner_std140 %111 %118
+        %125 = OpLoad %Inner_std140 %124 None
+        %126 = OpFunctionCall %Inner %tint_convert_Inner %125
+               OpStore %123 %126 None
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpIAdd %uint %118 %uint_1
+               OpBranch %116
         %117 = OpLabel
-        %123 = OpUGreaterThanEqual %bool %121 %uint_4
-               OpSelectionMerge %124 None
-               OpBranchConditional %123 %125 %124
-        %125 = OpLabel
-               OpBranch %120
-        %124 = OpLabel
-        %126 = OpAccessChain %_ptr_Function_Inner %115 %121
-        %127 = OpAccessChain %_ptr_Function_Inner_std140 %114 %121
-        %128 = OpLoad %Inner_std140 %127 None
-        %129 = OpFunctionCall %Inner %tint_convert_Inner %128
-               OpStore %126 %129 None
-               OpBranch %118
-        %118 = OpLabel
-        %122 = OpIAdd %uint %121 %uint_1
-               OpBranch %119
-        %120 = OpLabel
-        %130 = OpLoad %_arr_Inner_uint_4 %115 None
-        %131 = OpCompositeConstruct %Outer %130
-               OpReturnValue %131
+        %127 = OpLoad %_arr_Inner_uint_4 %112 None
+        %128 = OpCompositeConstruct %Outer %127
+               OpReturnValue %128
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.glsl
index 0814a93..055edc4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.glsl
@@ -39,7 +39,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat3x4 t = transpose(f16mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3));
-  float16_t l = length(v.inner[0].m_col1.zxy);
-  float16_t a = abs(v.inner[0].m_col1.zxy[0u]);
+  f16mat3x4 t = transpose(f16mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3));
+  float16_t l = length(v.inner[0u].m_col1.zxy);
+  float16_t a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
index 94933e5..efceda3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -33,11 +33,11 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*tint_module_vars.u)[2u].m;
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   half3 const v_3 = half3(v[2u].packed);
   half3x4 const t = transpose(half4x3(v_1, v_2, v_3, half3(v[3u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  half const a = abs(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  half const a = abs(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.spvasm
index fecdac3..dde30d7 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %39 = OpExtInstImport "GLSL.std.450"
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,34 +50,32 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v3half = OpTypeMatrix %v3half 4
      %v4half = OpTypeVector %half 4
  %mat3v4half = OpTypeMatrix %v4half 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v3half %24 None
-         %27 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_4
-         %28 = OpLoad %v3half %27 None
-         %30 = OpCompositeConstruct %mat4v3half %20 %23 %26 %28
-          %t = OpTranspose %mat3v4half %30
-         %34 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v3half %34 None
-         %37 = OpVectorShuffle %v3half %36 %36 2 0 1
-          %l = OpExtInst %half %39 Length %37
-         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %41 = OpLoad %v3half %40 None
-         %42 = OpVectorShuffle %v3half %41 %41 2 0 1
-         %43 = OpCompositeExtract %half %42 0
-          %a = OpExtInst %half %39 FAbs %43
+         %21 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v3half %23 None
+         %26 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_4
+         %27 = OpLoad %v3half %26 None
+         %29 = OpCompositeConstruct %mat4v3half %20 %22 %25 %27
+          %t = OpTranspose %mat3v4half %29
+         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v3half %33 None
+         %35 = OpVectorShuffle %v3half %34 %34 2 0 1
+          %l = OpExtInst %half %37 Length %35
+         %38 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %39 = OpLoad %v3half %38 None
+         %40 = OpVectorShuffle %v3half %39 %39 2 0 1
+         %41 = OpCompositeExtract %half %40 0
+          %a = OpExtInst %half %37 FAbs %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.glsl
index d5784d4..3783dd2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.glsl
@@ -76,8 +76,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat4x3(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2, v_1.inner[2].m_col3));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat4x3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2, v_1.inner[2u].m_col3));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.ir.msl
index cfdc82c..24f41a2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.ir.msl
@@ -72,12 +72,12 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_10 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_10 = (*tint_module_vars.u)[2u].m;
   half3 const v_11 = half3(v_10[0u].packed);
   half3 const v_12 = half3(v_10[1u].packed);
   half3 const v_13 = half3(v_10[2u].packed);
   c(half4x3(v_11, v_12, v_13, half3(v_10[3u].packed)));
-  d(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(half3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.spvasm
index 3cbb723..38dbc98 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -84,12 +84,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %98 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -148,41 +146,41 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3half %80 None
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_4
-         %84 = OpLoad %v3half %83 None
-         %85 = OpCompositeConstruct %mat4v3half %76 %79 %82 %84
-         %86 = OpFunctionCall %void %c %85
-         %87 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %89 = OpLoad %v3half %87 None
-         %90 = OpVectorShuffle %v3half %89 %89 2 0 1
-         %91 = OpFunctionCall %void %d %90
-         %92 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v3half %92 None
-         %94 = OpVectorShuffle %v3half %93 %93 2 0 1
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %void %e %95
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v3half %79 None
+         %82 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_4
+         %83 = OpLoad %v3half %82 None
+         %84 = OpCompositeConstruct %mat4v3half %76 %78 %81 %83
+         %85 = OpFunctionCall %void %c %84
+         %86 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v3half %86 None
+         %88 = OpVectorShuffle %v3half %87 %87 2 0 1
+         %89 = OpFunctionCall %void %d %88
+         %90 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %91 = OpLoad %v3half %90 None
+         %92 = OpVectorShuffle %v3half %91 %91 2 0 1
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %void %e %93
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %98
+%tint_convert_S = OpFunction %S None %96
  %tint_input = OpFunctionParameter %S_std140
-         %99 = OpLabel
-        %100 = OpCompositeExtract %int %tint_input 0
-        %101 = OpCompositeExtract %v3half %tint_input 1
-        %102 = OpCompositeExtract %v3half %tint_input 2
-        %103 = OpCompositeExtract %v3half %tint_input 3
-        %104 = OpCompositeExtract %v3half %tint_input 4
-        %105 = OpCompositeConstruct %mat4v3half %101 %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 5
-        %107 = OpCompositeConstruct %S %100 %105 %106
-               OpReturnValue %107
+         %97 = OpLabel
+         %98 = OpCompositeExtract %int %tint_input 0
+         %99 = OpCompositeExtract %v3half %tint_input 1
+        %100 = OpCompositeExtract %v3half %tint_input 2
+        %101 = OpCompositeExtract %v3half %tint_input 3
+        %102 = OpCompositeExtract %v3half %tint_input 4
+        %103 = OpCompositeConstruct %mat4v3half %99 %100 %101 %102
+        %104 = OpCompositeExtract %int %tint_input 5
+        %105 = OpCompositeConstruct %S %98 %103 %104
+               OpReturnValue %105
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.glsl
index c59bd07..f139d1c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.glsl
@@ -67,7 +67,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index cb72f9e..ba1a8dc 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -67,8 +67,8 @@
   S v_21[4] = v_16(0u);
   p = v_21;
   S v_22 = v_12(256u);
-  p[int(1)] = v_22;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  p[1u] = v_22;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.msl
index 288972a..cfe5008 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.ir.msl
@@ -59,11 +59,11 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_9 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_9 = (*tint_module_vars.u)[2u].m;
   half3 const v_10 = half3(v_9[0u].packed);
   half3 const v_11 = half3(v_9[1u].packed);
   half3 const v_12 = half3(v_9[2u].packed);
-  (*tint_module_vars.p)[3].m = half4x3(v_10, v_11, v_12, half3(v_9[3u].packed));
-  (*tint_module_vars.p)[1].m[0] = half3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = half4x3(v_10, v_11, v_12, half3(v_9[3u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = half3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.spvasm
index 16495a1..c768507 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -72,17 +72,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v3half = OpTypePointer Private %mat4v3half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v3half = OpTypePointer Private %mat4v3half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-      %int_0 = OpConstant %int 0
-         %79 = OpTypeFunction %S %S_std140
+         %75 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -116,39 +112,39 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat4v3half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_4
-         %70 = OpLoad %v3half %69 None
-         %71 = OpCompositeConstruct %mat4v3half %62 %65 %68 %70
-               OpStore %57 %71 None
-         %72 = OpAccessChain %_ptr_Private_v3half %p %int_1 %uint_1 %int_0
-         %75 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %76 = OpLoad %v3half %75 None
-         %77 = OpVectorShuffle %v3half %76 %76 2 0 1
-               OpStore %72 %77 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat4v3half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v3half %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_4
+         %67 = OpLoad %v3half %66 None
+         %68 = OpCompositeConstruct %mat4v3half %61 %63 %65 %67
+               OpStore %56 %68 None
+         %69 = OpAccessChain %_ptr_Private_v3half %p %uint_1 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %72 = OpLoad %v3half %71 None
+         %73 = OpVectorShuffle %v3half %72 %72 2 0 1
+               OpStore %69 %73 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %79
+%tint_convert_S = OpFunction %S None %75
  %tint_input = OpFunctionParameter %S_std140
-         %80 = OpLabel
-         %81 = OpCompositeExtract %int %tint_input 0
-         %82 = OpCompositeExtract %v3half %tint_input 1
-         %83 = OpCompositeExtract %v3half %tint_input 2
-         %84 = OpCompositeExtract %v3half %tint_input 3
-         %85 = OpCompositeExtract %v3half %tint_input 4
-         %86 = OpCompositeConstruct %mat4v3half %82 %83 %84 %85
-         %87 = OpCompositeExtract %int %tint_input 5
-         %88 = OpCompositeConstruct %S %81 %86 %87
-               OpReturnValue %88
+         %76 = OpLabel
+         %77 = OpCompositeExtract %int %tint_input 0
+         %78 = OpCompositeExtract %v3half %tint_input 1
+         %79 = OpCompositeExtract %v3half %tint_input 2
+         %80 = OpCompositeExtract %v3half %tint_input 3
+         %81 = OpCompositeExtract %v3half %tint_input 4
+         %82 = OpCompositeConstruct %mat4v3half %78 %79 %80 %81
+         %83 = OpCompositeExtract %int %tint_input 5
+         %84 = OpCompositeConstruct %S %77 %82 %83
+               OpReturnValue %84
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
index 4739065..fc165e6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -120,9 +120,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  f16mat4x3 v_9 = f16mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  f16mat4x3 v_9 = f16mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.ir.msl
index 9dec492..eb14cf6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.ir.msl
@@ -33,6 +33,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -66,6 +69,7 @@
     uint v_6 = 0u;
     v_6 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_7 = v_6;
       if ((v_7 >= 4u)) {
         break;
@@ -89,11 +93,11 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_11 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_11 = (*tint_module_vars.u)[2u].m;
   half3 const v_12 = half3(v_11[0u].packed);
   half3 const v_13 = half3(v_11[1u].packed);
   half3 const v_14 = half3(v_11[2u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), half4x3(v_12, v_13, v_14, half3(v_11[3u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), half4x3(v_12, v_13, v_14, half3(v_11[3u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
index 4defbd8..10e6906 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -67,7 +70,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
index 44539e5..d11f5d2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 141
+; Bound: 135
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -88,20 +88,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_3 = OpConstant %int 3
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-      %int_0 = OpConstant %int 0
-         %87 = OpTypeFunction %void %_arr_S_uint_4
-        %106 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %81 = OpTypeFunction %void %_arr_S_uint_4
+        %100 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %119 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
-        %131 = OpTypeFunction %S %S_std140
+        %113 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3half
+        %125 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -135,106 +131,104 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3half %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3half %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
          %68 = OpLoad %v3half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %71 = OpLoad %v3half %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_4
-         %73 = OpLoad %v3half %72 None
-         %74 = OpCompositeConstruct %mat4v3half %65 %68 %71 %73
-         %75 = OpBitcast %uint %int_3
-         %77 = OpCompositeConstruct %_arr_uint_uint_1 %75
-         %78 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %77 %74
-         %80 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %int_1 %uint_1 %int_0
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v3half %83 None
-         %85 = OpVectorShuffle %v3half %84 %84 2 0 1
-               OpStore %80 %85 None
+         %69 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_4
+         %70 = OpLoad %v3half %69 None
+         %71 = OpCompositeConstruct %mat4v3half %63 %65 %68 %70
+         %72 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %73 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %72 %71
+         %75 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %77 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %78 = OpLoad %v3half %77 None
+         %79 = OpVectorShuffle %v3half %78 %78 2 0 1
+               OpStore %75 %79 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %87
+%tint_store_and_preserve_padding = OpFunction %void None %81
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %88 = OpLabel
-         %89 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %89 %value_param
-               OpBranch %90
-         %90 = OpLabel
-               OpBranch %93
+         %82 = OpLabel
+         %83 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %83 %value_param
+               OpBranch %84
+         %84 = OpLabel
+               OpBranch %87
+         %87 = OpLabel
+         %89 = OpPhi %uint %uint_0 %84 %90 %86
+               OpLoopMerge %88 %86 None
+               OpBranch %85
+         %85 = OpLabel
+         %91 = OpUGreaterThanEqual %bool %89 %uint_4
+               OpSelectionMerge %92 None
+               OpBranchConditional %91 %93 %92
          %93 = OpLabel
-         %95 = OpPhi %uint %uint_0 %90 %96 %92
-               OpLoopMerge %94 %92 None
-               OpBranch %91
-         %91 = OpLabel
-         %97 = OpUGreaterThanEqual %bool %95 %uint_4
-               OpSelectionMerge %98 None
-               OpBranchConditional %97 %99 %98
-         %99 = OpLabel
-               OpBranch %94
-         %98 = OpLabel
-        %100 = OpAccessChain %_ptr_Function_S %89 %95
-        %101 = OpLoad %S %100 None
-        %102 = OpCompositeConstruct %_arr_uint_uint_1 %95
-        %103 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %102 %101
-               OpBranch %92
+               OpBranch %88
          %92 = OpLabel
-         %96 = OpIAdd %uint %95 %uint_1
-               OpBranch %93
-         %94 = OpLabel
+         %94 = OpAccessChain %_ptr_Function_S %83 %89
+         %95 = OpLoad %S %94 None
+         %96 = OpCompositeConstruct %_arr_uint_uint_1 %89
+         %97 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %96 %95
+               OpBranch %86
+         %86 = OpLabel
+         %90 = OpIAdd %uint %89 %uint_1
+               OpBranch %87
+         %88 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %106
+%tint_store_and_preserve_padding_0 = OpFunction %void None %100
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %107 = OpLabel
-        %108 = OpCompositeExtract %uint %target_indices 0
-        %109 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %108 %uint_0
-        %111 = OpCompositeExtract %int %value_param_0 0
-               OpStore %109 %111 None
-        %112 = OpCompositeExtract %mat4v3half %value_param_0 1
-        %113 = OpCompositeConstruct %_arr_uint_uint_1 %108
-        %114 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %113 %112
-        %115 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %108 %uint_2
-        %116 = OpCompositeExtract %int %value_param_0 2
-               OpStore %115 %116 None
+        %101 = OpLabel
+        %102 = OpCompositeExtract %uint %target_indices 0
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %102 %uint_0
+        %105 = OpCompositeExtract %int %value_param_0 0
+               OpStore %103 %105 None
+        %106 = OpCompositeExtract %mat4v3half %value_param_0 1
+        %107 = OpCompositeConstruct %_arr_uint_uint_1 %102
+        %108 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %107 %106
+        %109 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %102 %uint_2
+        %110 = OpCompositeExtract %int %value_param_0 2
+               OpStore %109 %110 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %119
+%tint_store_and_preserve_padding_1 = OpFunction %void None %113
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat4v3half
-        %120 = OpLabel
-        %121 = OpCompositeExtract %uint %target_indices_0 0
-        %122 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %121 %uint_1 %uint_0
-        %123 = OpCompositeExtract %v3half %value_param_1 0
+        %114 = OpLabel
+        %115 = OpCompositeExtract %uint %target_indices_0 0
+        %116 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %115 %uint_1 %uint_0
+        %117 = OpCompositeExtract %v3half %value_param_1 0
+               OpStore %116 %117 None
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %115 %uint_1 %uint_1
+        %119 = OpCompositeExtract %v3half %value_param_1 1
+               OpStore %118 %119 None
+        %120 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %115 %uint_1 %uint_2
+        %121 = OpCompositeExtract %v3half %value_param_1 2
+               OpStore %120 %121 None
+        %122 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %115 %uint_1 %uint_3
+        %123 = OpCompositeExtract %v3half %value_param_1 3
                OpStore %122 %123 None
-        %124 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %121 %uint_1 %uint_1
-        %125 = OpCompositeExtract %v3half %value_param_1 1
-               OpStore %124 %125 None
-        %126 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %121 %uint_1 %uint_2
-        %127 = OpCompositeExtract %v3half %value_param_1 2
-               OpStore %126 %127 None
-        %128 = OpAccessChain %_ptr_StorageBuffer_v3half %11 %uint_0 %121 %uint_1 %uint_3
-        %129 = OpCompositeExtract %v3half %value_param_1 3
-               OpStore %128 %129 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %131
+%tint_convert_S = OpFunction %S None %125
  %tint_input = OpFunctionParameter %S_std140
-        %132 = OpLabel
-        %133 = OpCompositeExtract %int %tint_input 0
-        %134 = OpCompositeExtract %v3half %tint_input 1
-        %135 = OpCompositeExtract %v3half %tint_input 2
-        %136 = OpCompositeExtract %v3half %tint_input 3
-        %137 = OpCompositeExtract %v3half %tint_input 4
-        %138 = OpCompositeConstruct %mat4v3half %134 %135 %136 %137
-        %139 = OpCompositeExtract %int %tint_input 5
-        %140 = OpCompositeConstruct %S %133 %138 %139
-               OpReturnValue %140
+        %126 = OpLabel
+        %127 = OpCompositeExtract %int %tint_input 0
+        %128 = OpCompositeExtract %v3half %tint_input 1
+        %129 = OpCompositeExtract %v3half %tint_input 2
+        %130 = OpCompositeExtract %v3half %tint_input 3
+        %131 = OpCompositeExtract %v3half %tint_input 4
+        %132 = OpCompositeConstruct %mat4v3half %128 %129 %130 %131
+        %133 = OpCompositeExtract %int %tint_input 5
+        %134 = OpCompositeConstruct %S %127 %132 %133
+               OpReturnValue %134
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.glsl
index 9757e8b..4f84256 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.glsl
@@ -82,9 +82,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 1bafc47..7748d4e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -87,9 +87,9 @@
   S v_24[4] = v_16(0u);
   w = v_24;
   S v_25 = v_12(256u);
-  w[int(1)] = v_25;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
+  w[1u] = v_25;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).xyz.zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
index 8545ef0..502bdc2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -38,6 +38,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -80,6 +83,7 @@
     uint v_9 = 0u;
     v_9 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_10 = v_9;
       if ((v_10 >= 4u)) {
         break;
@@ -93,17 +97,17 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f16_array_element, 4> const v_11 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f16_array_element, 4> const v_11 = (*tint_module_vars.u)[2u].m;
   half3 const v_12 = half3(v_11[0u].packed);
   half3 const v_13 = half3(v_11[1u].packed);
   half3 const v_14 = half3(v_11[2u].packed);
   half4x3 const v_15 = half4x3(v_12, v_13, v_14, half3(v_11[3u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_half3(v_15[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_half3(v_15[1u]);
-  (*tint_module_vars.w)[3].m[2u].packed = packed_half3(v_15[2u]);
-  (*tint_module_vars.w)[3].m[3u].packed = packed_half3(v_15[3u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_half3(half3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_half3(v_15[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_half3(v_15[1u]);
+  (*tint_module_vars.w)[3u].m[2u].packed = packed_half3(v_15[2u]);
+  (*tint_module_vars.w)[3u].m[3u].packed = packed_half3(v_15[3u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_half3(half3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_16 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.msl
index b803141..813e55b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f16_array_element {
   /* 0x0000 */ packed_half3 elements;
   /* 0x0006 */ tint_array<int8_t, 2> tint_pad;
@@ -49,6 +52,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
index ab3cc9e..7a7c026 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 107
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -81,17 +81,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v3half = OpTypePointer Workgroup %mat4v3half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %void
-        %101 = OpTypeFunction %S %S_std140
+         %92 = OpTypeFunction %void
+         %97 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -148,45 +144,45 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat4v3half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat4v3half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v3half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v3half %83 None
-         %86 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_2 %uint_4
-         %87 = OpLoad %v3half %86 None
-         %88 = OpCompositeConstruct %mat4v3half %80 %82 %85 %87
-               OpStore %75 %88 None
-         %89 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1 %uint_1 %int_0
-         %92 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v3half %92 None
-         %94 = OpVectorShuffle %v3half %93 %93 2 0 1
-               OpStore %89 %94 None
+         %83 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_2 %uint_4
+         %84 = OpLoad %v3half %83 None
+         %85 = OpCompositeConstruct %mat4v3half %78 %80 %82 %84
+               OpStore %73 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1 %uint_1 %uint_0
+         %88 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v3half %88 None
+         %90 = OpVectorShuffle %v3half %89 %89 2 0 1
+               OpStore %86 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %96
-         %97 = OpLabel
-         %98 = OpLoad %uint %f_local_invocation_index_Input None
-         %99 = OpFunctionCall %void %f_inner %98
+          %f = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %uint %f_local_invocation_index_Input None
+         %95 = OpFunctionCall %void %f_inner %94
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %101
+%tint_convert_S = OpFunction %S None %97
  %tint_input = OpFunctionParameter %S_std140
-        %102 = OpLabel
-        %103 = OpCompositeExtract %int %tint_input 0
-        %104 = OpCompositeExtract %v3half %tint_input 1
-        %105 = OpCompositeExtract %v3half %tint_input 2
-        %106 = OpCompositeExtract %v3half %tint_input 3
-        %107 = OpCompositeExtract %v3half %tint_input 4
-        %108 = OpCompositeConstruct %mat4v3half %104 %105 %106 %107
-        %109 = OpCompositeExtract %int %tint_input 5
-        %110 = OpCompositeConstruct %S %103 %108 %109
-               OpReturnValue %110
+         %98 = OpLabel
+         %99 = OpCompositeExtract %int %tint_input 0
+        %100 = OpCompositeExtract %v3half %tint_input 1
+        %101 = OpCompositeExtract %v3half %tint_input 2
+        %102 = OpCompositeExtract %v3half %tint_input 3
+        %103 = OpCompositeExtract %v3half %tint_input 4
+        %104 = OpCompositeConstruct %mat4v3half %100 %101 %102 %103
+        %105 = OpCompositeExtract %int %tint_input 5
+        %106 = OpCompositeConstruct %S %99 %104 %105
+               OpReturnValue %106
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 1d51e7a..c18da82 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -61,17 +61,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_4 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 1d51e7a..c18da82 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -61,17 +61,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x3 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x3 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   float3 l_a_i_a_i_m_i = asfloat(a[scalar_offset_4 / 4].xyz);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 2u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index aa45997..dba0ad4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -57,10 +57,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   mat4x3 v_6 = mat4x3(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2, v.inner[v_4].a[v_5].m_col3);
-  vec3 v_7 = v_6[i()];
+  vec3 v_7 = v_6[min(uint(i()), 3u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))));
   {
@@ -101,5 +101,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   mat4x3 l_a_i_a_i_m = v_6;
   vec3 l_a_i_a_i_m_i = v_7;
-  float l_a_i_a_i_m_i_i = v_7[i()];
+  float l_a_i_a_i_m_i_i = v_7[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index e9d463d..ff210b0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float4x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index e9d463d..ff210b0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float4x3 l_a_i_a_i_m = v((v_16 + v_17));
   float3 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)].xyz);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 2u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 7adeaff..f799f19 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -74,11 +74,11 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer_packed_vec3* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner_packed_vec3* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_i = tint_load_struct_packed_vec3_1(p_a_i);
   tint_array<Inner, 4> const l_a_i_a = tint_load_array_packed_vec3(p_a_i_a);
@@ -89,5 +89,5 @@
   float3 const v_13 = float3(v_10[2u].packed);
   float4x3 const l_a_i_a_i_m = float4x3(v_11, v_12, v_13, float3(v_10[3u].packed));
   float3 const l_a_i_a_i_m_i = float3((*p_a_i_a_i_m_i));
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index c37d597..96c563e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -75,11 +75,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = tint_unpack_vec3_in_composite_4(*(tint_symbol_4));
   Outer const l_a_i = tint_unpack_vec3_in_composite_3((*(tint_symbol_4))[p_a_i_save]);
   tint_array<Inner, 4> const l_a_i_a = tint_unpack_vec3_in_composite_2((*(tint_symbol_4))[p_a_i_save].a);
@@ -87,7 +87,7 @@
   float4x3 const l_a_i_a_i_m = tint_unpack_vec3_in_composite((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m);
   float3 const l_a_i_a_i_m_i = float3((*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements);
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save].elements[min(uint(tint_symbol_3), 2u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index a903552..06b842b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 157
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -73,13 +74,13 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
@@ -89,17 +90,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %67 = OpConstantNull %_arr_Outer_uint_4
+         %74 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %94 = OpConstantNull %_arr_Inner_uint_4
+        %101 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %118 = OpTypeFunction %Inner %Inner_std140
-        %127 = OpTypeFunction %Outer %Outer_std140
+        %127 = OpTypeFunction %Inner %Inner_std140
+        %136 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -110,135 +111,143 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %52 = OpVariable %_ptr_Function_mat4v3float Function
-         %59 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %61 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %67
-         %90 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %92 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
+         %57 = OpVariable %_ptr_Function_mat4v3float Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %68 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %74
+         %97 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %99 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_0
-         %40 = OpLoad %v3float %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_1
-         %43 = OpLoad %v3float %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_0
          %46 = OpLoad %v3float %44 None
-         %47 = OpAccessChain %_ptr_Uniform_v3float %36 %uint_3
+         %47 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_1
          %49 = OpLoad %v3float %47 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat4v3float %40 %43 %46 %49
-               OpStore %52 %l_a_i_a_i_m
-         %54 = OpFunctionCall %int %i
-         %55 = OpAccessChain %_ptr_Function_v3float %52 %54
-%l_a_i_a_i_m_i = OpLoad %v3float %55 None
-         %58 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %59 %58
-               OpBranch %68
-         %68 = OpLabel
-               OpBranch %71
-         %71 = OpLabel
-         %73 = OpPhi %uint %uint_0 %68 %74 %70
-               OpLoopMerge %72 %70 None
-               OpBranch %69
-         %69 = OpLabel
-         %75 = OpUGreaterThanEqual %bool %73 %uint_4
-               OpSelectionMerge %77 None
-               OpBranchConditional %75 %78 %77
+         %50 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_2
+         %52 = OpLoad %v3float %50 None
+         %53 = OpAccessChain %_ptr_Uniform_v3float %42 %uint_3
+         %54 = OpLoad %v3float %53 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat4v3float %46 %49 %52 %54
+               OpStore %57 %l_a_i_a_i_m
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %33 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Function_v3float %57 %61
+%l_a_i_a_i_m_i = OpLoad %v3float %62 None
+         %65 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %66 %65
+               OpBranch %75
+         %75 = OpLabel
+               OpBranch %78
          %78 = OpLabel
-               OpBranch %72
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %84 None
+               OpBranchConditional %82 %85 %84
+         %85 = OpLabel
+               OpBranch %79
+         %84 = OpLabel
+         %86 = OpAccessChain %_ptr_Function_Outer %68 %80
+         %88 = OpAccessChain %_ptr_Function_Outer_std140 %66 %80
+         %90 = OpLoad %Outer_std140 %88 None
+         %91 = OpFunctionCall %Outer %tint_convert_Outer %90
+               OpStore %86 %91 None
+               OpBranch %77
          %77 = OpLabel
-         %79 = OpAccessChain %_ptr_Function_Outer %61 %73
-         %81 = OpAccessChain %_ptr_Function_Outer_std140 %59 %73
-         %83 = OpLoad %Outer_std140 %81 None
-         %84 = OpFunctionCall %Outer %tint_convert_Outer %83
-               OpStore %79 %84 None
-               OpBranch %70
-         %70 = OpLabel
-         %74 = OpIAdd %uint %73 %uint_1
-               OpBranch %71
-         %72 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %61 None
-         %87 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %87
-         %89 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %90 %89
-               OpBranch %95
-         %95 = OpLabel
-               OpBranch %98
-         %98 = OpLabel
-        %100 = OpPhi %uint %uint_0 %95 %101 %97
-               OpLoopMerge %99 %97 None
-               OpBranch %96
-         %96 = OpLabel
-        %102 = OpUGreaterThanEqual %bool %100 %uint_4
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %103
-        %104 = OpLabel
-               OpBranch %99
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
+         %79 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %68 None
+         %94 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %94
+         %96 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %97 %96
+               OpBranch %102
+        %102 = OpLabel
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpPhi %uint %uint_0 %102 %108 %104
+               OpLoopMerge %106 %104 None
+               OpBranch %103
         %103 = OpLabel
-        %105 = OpAccessChain %_ptr_Function_Inner %92 %100
-        %107 = OpAccessChain %_ptr_Function_Inner_std140 %90 %100
-        %109 = OpLoad %Inner_std140 %107 None
-        %110 = OpFunctionCall %Inner %tint_convert_Inner %109
-               OpStore %105 %110 None
-               OpBranch %97
-         %97 = OpLabel
-        %101 = OpIAdd %uint %100 %uint_1
-               OpBranch %98
-         %99 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %92 None
-        %113 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %113
-        %115 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %115
+        %109 = OpUGreaterThanEqual %bool %107 %uint_4
+               OpSelectionMerge %110 None
+               OpBranchConditional %109 %111 %110
+        %111 = OpLabel
+               OpBranch %106
+        %110 = OpLabel
+        %112 = OpAccessChain %_ptr_Function_Inner %99 %107
+        %114 = OpAccessChain %_ptr_Function_Inner_std140 %97 %107
+        %116 = OpLoad %Inner_std140 %114 None
+        %117 = OpFunctionCall %Inner %tint_convert_Inner %116
+               OpStore %112 %117 None
+               OpBranch %104
+        %104 = OpLabel
+        %108 = OpIAdd %uint %107 %uint_1
+               OpBranch %105
+        %106 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %99 None
+        %120 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %120
+        %122 = OpFunctionCall %int %i
+        %123 = OpBitcast %uint %122
+        %124 = OpExtInst %uint %33 UMin %123 %uint_2
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %float %l_a_i_a_i_m_i %124
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %118
+%tint_convert_Inner = OpFunction %Inner None %127
  %tint_input = OpFunctionParameter %Inner_std140
-        %119 = OpLabel
-        %120 = OpCompositeExtract %v3float %tint_input 0
-        %121 = OpCompositeExtract %v3float %tint_input 1
-        %122 = OpCompositeExtract %v3float %tint_input 2
-        %123 = OpCompositeExtract %v3float %tint_input 3
-        %124 = OpCompositeConstruct %mat4v3float %120 %121 %122 %123
-        %125 = OpCompositeConstruct %Inner %124
-               OpReturnValue %125
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %127
-%tint_input_0 = OpFunctionParameter %Outer_std140
         %128 = OpLabel
-        %130 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %131 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
-        %129 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %130 %129
-               OpBranch %132
-        %132 = OpLabel
-               OpBranch %135
-        %135 = OpLabel
-        %137 = OpPhi %uint %uint_0 %132 %138 %134
-               OpLoopMerge %136 %134 None
-               OpBranch %133
-        %133 = OpLabel
-        %139 = OpUGreaterThanEqual %bool %137 %uint_4
-               OpSelectionMerge %140 None
-               OpBranchConditional %139 %141 %140
+        %129 = OpCompositeExtract %v3float %tint_input 0
+        %130 = OpCompositeExtract %v3float %tint_input 1
+        %131 = OpCompositeExtract %v3float %tint_input 2
+        %132 = OpCompositeExtract %v3float %tint_input 3
+        %133 = OpCompositeConstruct %mat4v3float %129 %130 %131 %132
+        %134 = OpCompositeConstruct %Inner %133
+               OpReturnValue %134
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %136
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %137 = OpLabel
+        %139 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %140 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
+        %138 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %139 %138
+               OpBranch %141
         %141 = OpLabel
-               OpBranch %136
-        %140 = OpLabel
-        %142 = OpAccessChain %_ptr_Function_Inner %131 %137
-        %143 = OpAccessChain %_ptr_Function_Inner_std140 %130 %137
-        %144 = OpLoad %Inner_std140 %143 None
-        %145 = OpFunctionCall %Inner %tint_convert_Inner %144
-               OpStore %142 %145 None
-               OpBranch %134
-        %134 = OpLabel
-        %138 = OpIAdd %uint %137 %uint_1
-               OpBranch %135
-        %136 = OpLabel
-        %146 = OpLoad %_arr_Inner_uint_4 %131 None
-        %147 = OpCompositeConstruct %Outer %146
-               OpReturnValue %147
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %uint_0 %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4
+               OpSelectionMerge %149 None
+               OpBranchConditional %148 %150 %149
+        %150 = OpLabel
+               OpBranch %145
+        %149 = OpLabel
+        %151 = OpAccessChain %_ptr_Function_Inner %140 %146
+        %152 = OpAccessChain %_ptr_Function_Inner_std140 %139 %146
+        %153 = OpLoad %Inner_std140 %152 None
+        %154 = OpFunctionCall %Inner %tint_convert_Inner %153
+               OpStore %151 %154 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_1
+               OpBranch %144
+        %145 = OpLabel
+        %155 = OpLoad %_arr_Inner_uint_4 %140 None
+        %156 = OpCompositeConstruct %Outer %155
+               OpReturnValue %156
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 95226bd..0c8b13f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -52,7 +52,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4x3 v_4 = mat4x3(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2, v.inner[3].a[2].m_col3);
+  mat4x3 v_4 = mat4x3(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2, v.inner[3u].a[2u].m_col3);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))), Outer(Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))))));
   {
@@ -71,8 +71,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))), Inner(mat4x3(vec3(0.0f), vec3(0.0f), vec3(0.0f), vec3(0.0f))));
   {
     uint v_11 = 0u;
@@ -90,8 +90,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   mat4x3 l_a_3_a_2_m = v_4;
-  vec3 l_a_3_a_2_m_1 = v_4[1];
-  float l_a_3_a_2_m_1_0 = v_4[1][0];
+  vec3 l_a_3_a_2_m_1 = v_4[1u];
+  float l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 9c44ae6..aaee511 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -67,11 +67,11 @@
 kernel void f(const constant tint_array<Outer_packed_vec3, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer_packed_vec3, 4>* const p_a = tint_module_vars.a;
-  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer_packed_vec3* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner_packed_vec3, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner_packed_vec3* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1].packed);
+  const constant packed_float3* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u].packed);
   tint_array<Outer, 4> const l_a = tint_load_array_packed_vec3_1(p_a);
   Outer const l_a_3 = tint_load_struct_packed_vec3_1(p_a_3);
   tint_array<Inner, 4> const l_a_3_a = tint_load_array_packed_vec3(p_a_3_a);
@@ -82,5 +82,5 @@
   float3 const v_13 = float3(v_10[2u].packed);
   float4x3 const l_a_3_a_2_m = float4x3(v_11, v_12, v_13, float3(v_10[3u].packed));
   float3 const l_a_3_a_2_m_1 = float3((*p_a_3_a_2_m_1));
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
index 818b3ba..a12389b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 132
+; Bound: 129
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -66,15 +66,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat4v3float
@@ -82,141 +79,141 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %52 = OpConstantNull %_arr_Outer_uint_4
+         %49 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %79 = OpConstantNull %_arr_Inner_uint_4
+         %76 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %102 = OpTypeFunction %Inner %Inner_std140
-        %111 = OpTypeFunction %Outer %Outer_std140
+         %99 = OpTypeFunction %Inner %Inner_std140
+        %108 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %44 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %46 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %52
-         %75 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %77 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
+         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
+         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_0
-         %30 = OpLoad %v3float %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_1
-         %33 = OpLoad %v3float %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_2
-         %36 = OpLoad %v3float %34 None
-         %37 = OpAccessChain %_ptr_Uniform_v3float %25 %uint_3
-         %39 = OpLoad %v3float %37 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat4v3float %30 %33 %36 %39
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_0
+         %29 = OpLoad %v3float %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_1
+         %32 = OpLoad %v3float %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_2
+         %34 = OpLoad %v3float %33 None
+         %35 = OpAccessChain %_ptr_Uniform_v3float %24 %uint_3
+         %36 = OpLoad %v3float %35 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat4v3float %29 %32 %34 %36
 %l_a_3_a_2_m_1 = OpCompositeExtract %v3float %l_a_3_a_2_m 1
-         %43 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %44 %43
+         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %41 %40
+               OpBranch %50
+         %50 = OpLabel
                OpBranch %53
          %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
+         %55 = OpPhi %uint %uint_0 %50 %56 %52
+               OpLoopMerge %54 %52 None
+               OpBranch %51
+         %51 = OpLabel
+         %57 = OpUGreaterThanEqual %bool %55 %uint_4
+               OpSelectionMerge %59 None
+               OpBranchConditional %57 %60 %59
+         %60 = OpLabel
                OpBranch %54
+         %59 = OpLabel
+         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
+         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
+         %65 = OpLoad %Outer_std140 %63 None
+         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
+               OpStore %61 %66 None
+               OpBranch %52
+         %52 = OpLabel
+         %56 = OpIAdd %uint %55 %uint_1
+               OpBranch %53
          %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
-         %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_Outer %46 %58
-         %66 = OpAccessChain %_ptr_Function_Outer_std140 %44 %58
-         %68 = OpLoad %Outer_std140 %66 None
-         %69 = OpFunctionCall %Outer %tint_convert_Outer %68
-               OpStore %64 %69 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %46 None
-         %72 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %72
-         %74 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %75 %74
+        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
+         %69 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
+         %71 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %72 %71
+               OpBranch %77
+         %77 = OpLabel
                OpBranch %80
          %80 = OpLabel
-               OpBranch %83
-         %83 = OpLabel
-         %85 = OpPhi %uint %uint_0 %80 %86 %82
-               OpLoopMerge %84 %82 None
+         %82 = OpPhi %uint %uint_0 %77 %83 %79
+               OpLoopMerge %81 %79 None
+               OpBranch %78
+         %78 = OpLabel
+         %84 = OpUGreaterThanEqual %bool %82 %uint_4
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %85
+         %86 = OpLabel
                OpBranch %81
+         %85 = OpLabel
+         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
+         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
+         %91 = OpLoad %Inner_std140 %89 None
+         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
+               OpStore %87 %92 None
+               OpBranch %79
+         %79 = OpLabel
+         %83 = OpIAdd %uint %82 %uint_1
+               OpBranch %80
          %81 = OpLabel
-         %87 = OpUGreaterThanEqual %bool %85 %uint_4
-               OpSelectionMerge %88 None
-               OpBranchConditional %87 %89 %88
-         %89 = OpLabel
-               OpBranch %84
-         %88 = OpLabel
-         %90 = OpAccessChain %_ptr_Function_Inner %77 %85
-         %92 = OpAccessChain %_ptr_Function_Inner_std140 %75 %85
-         %94 = OpLoad %Inner_std140 %92 None
-         %95 = OpFunctionCall %Inner %tint_convert_Inner %94
-               OpStore %90 %95 None
-               OpBranch %82
-         %82 = OpLabel
-         %86 = OpIAdd %uint %85 %uint_1
-               OpBranch %83
-         %84 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %77 None
-         %98 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %98
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
+         %95 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %float %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %102
+%tint_convert_Inner = OpFunction %Inner None %99
  %tint_input = OpFunctionParameter %Inner_std140
-        %103 = OpLabel
-        %104 = OpCompositeExtract %v3float %tint_input 0
-        %105 = OpCompositeExtract %v3float %tint_input 1
-        %106 = OpCompositeExtract %v3float %tint_input 2
-        %107 = OpCompositeExtract %v3float %tint_input 3
-        %108 = OpCompositeConstruct %mat4v3float %104 %105 %106 %107
-        %109 = OpCompositeConstruct %Inner %108
-               OpReturnValue %109
+        %100 = OpLabel
+        %101 = OpCompositeExtract %v3float %tint_input 0
+        %102 = OpCompositeExtract %v3float %tint_input 1
+        %103 = OpCompositeExtract %v3float %tint_input 2
+        %104 = OpCompositeExtract %v3float %tint_input 3
+        %105 = OpCompositeConstruct %mat4v3float %101 %102 %103 %104
+        %106 = OpCompositeConstruct %Inner %105
+               OpReturnValue %106
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %111
+%tint_convert_Outer = OpFunction %Outer None %108
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %112 = OpLabel
-        %114 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %115 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
-        %113 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %114 %113
+        %109 = OpLabel
+        %111 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %112 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+        %110 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %111 %110
+               OpBranch %113
+        %113 = OpLabel
                OpBranch %116
         %116 = OpLabel
-               OpBranch %119
-        %119 = OpLabel
-        %121 = OpPhi %uint %uint_0 %116 %122 %118
-               OpLoopMerge %120 %118 None
+        %118 = OpPhi %uint %uint_0 %113 %119 %115
+               OpLoopMerge %117 %115 None
+               OpBranch %114
+        %114 = OpLabel
+        %120 = OpUGreaterThanEqual %bool %118 %uint_4
+               OpSelectionMerge %121 None
+               OpBranchConditional %120 %122 %121
+        %122 = OpLabel
                OpBranch %117
+        %121 = OpLabel
+        %123 = OpAccessChain %_ptr_Function_Inner %112 %118
+        %124 = OpAccessChain %_ptr_Function_Inner_std140 %111 %118
+        %125 = OpLoad %Inner_std140 %124 None
+        %126 = OpFunctionCall %Inner %tint_convert_Inner %125
+               OpStore %123 %126 None
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpIAdd %uint %118 %uint_1
+               OpBranch %116
         %117 = OpLabel
-        %123 = OpUGreaterThanEqual %bool %121 %uint_4
-               OpSelectionMerge %124 None
-               OpBranchConditional %123 %125 %124
-        %125 = OpLabel
-               OpBranch %120
-        %124 = OpLabel
-        %126 = OpAccessChain %_ptr_Function_Inner %115 %121
-        %127 = OpAccessChain %_ptr_Function_Inner_std140 %114 %121
-        %128 = OpLoad %Inner_std140 %127 None
-        %129 = OpFunctionCall %Inner %tint_convert_Inner %128
-               OpStore %126 %129 None
-               OpBranch %118
-        %118 = OpLabel
-        %122 = OpIAdd %uint %121 %uint_1
-               OpBranch %119
-        %120 = OpLabel
-        %130 = OpLoad %_arr_Inner_uint_4 %115 None
-        %131 = OpCompositeConstruct %Outer %130
-               OpReturnValue %131
+        %127 = OpLoad %_arr_Inner_uint_4 %112 None
+        %128 = OpCompositeConstruct %Outer %127
+               OpReturnValue %128
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.glsl
index 81aeeae..9739201 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.glsl
@@ -50,7 +50,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat3x4 t = transpose(mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3));
-  float l = length(v.inner[0].m_col1.zxy);
-  float a = abs(v.inner[0].m_col1.zxy[0u]);
+  mat3x4 t = transpose(mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3));
+  float l = length(v.inner[0u].m_col1.zxy);
+  float a = abs(v.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
index aec93be..e76178f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -33,11 +33,11 @@
 
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*tint_module_vars.u)[2].m;
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*tint_module_vars.u)[2u].m;
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   float3 const v_3 = float3(v[2u].packed);
   float3x4 const t = transpose(float4x3(v_1, v_2, v_3, float3(v[3u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  float const a = abs(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  float const a = abs(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.spvasm
index b7f2e8a..e3ef120 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
-         %39 = OpExtInstImport "GLSL.std.450"
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -47,34 +47,32 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
 %mat4v3float = OpTypeMatrix %v3float 4
     %v4float = OpTypeVector %float 4
 %mat3v4float = OpTypeMatrix %v4float 3
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v3float %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v3float %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v3float %24 None
-         %27 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_4
-         %28 = OpLoad %v3float %27 None
-         %30 = OpCompositeConstruct %mat4v3float %20 %23 %26 %28
-          %t = OpTranspose %mat3v4float %30
-         %34 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %36 = OpLoad %v3float %34 None
-         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
-          %l = OpExtInst %float %39 Length %37
-         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %41 = OpLoad %v3float %40 None
-         %42 = OpVectorShuffle %v3float %41 %41 2 0 1
-         %43 = OpCompositeExtract %float %42 0
-          %a = OpExtInst %float %39 FAbs %43
+         %21 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v3float %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v3float %23 None
+         %26 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_4
+         %27 = OpLoad %v3float %26 None
+         %29 = OpCompositeConstruct %mat4v3float %20 %22 %25 %27
+          %t = OpTranspose %mat3v4float %29
+         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %34 = OpLoad %v3float %33 None
+         %35 = OpVectorShuffle %v3float %34 %34 2 0 1
+          %l = OpExtInst %float %37 Length %35
+         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %39 = OpLoad %v3float %38 None
+         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
+         %41 = OpCompositeExtract %float %40 0
+          %a = OpExtInst %float %37 FAbs %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.glsl
index a7d8fd7..c9fbc1d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.glsl
@@ -87,8 +87,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(mat4x3(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2, v_1.inner[2].m_col3));
-  d(v_1.inner[0].m_col1.zxy);
-  e(v_1.inner[0].m_col1.zxy[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(mat4x3(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2, v_1.inner[2u].m_col3));
+  d(v_1.inner[0u].m_col1.zxy);
+  e(v_1.inner[0u].m_col1.zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.ir.msl
index c5b6564..4332733 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.ir.msl
@@ -72,12 +72,12 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a(tint_load_array_packed_vec3(tint_module_vars.u));
-  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_10 = (*tint_module_vars.u)[2].m;
+  b(tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_10 = (*tint_module_vars.u)[2u].m;
   float3 const v_11 = float3(v_10[0u].packed);
   float3 const v_12 = float3(v_10[1u].packed);
   float3 const v_13 = float3(v_10[2u].packed);
   c(float4x3(v_11, v_12, v_13, float3(v_10[3u].packed)));
-  d(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
-  e(float3((*tint_module_vars.u)[0].m[1].packed).zxy[0u]);
+  d(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
+  e(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.spvasm
index 8be09cb..88c6535 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -81,12 +81,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %98 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -145,41 +143,41 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v3float %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v3float %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v3float %80 None
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_4
-         %84 = OpLoad %v3float %83 None
-         %85 = OpCompositeConstruct %mat4v3float %76 %79 %82 %84
-         %86 = OpFunctionCall %void %c %85
-         %87 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %89 = OpLoad %v3float %87 None
-         %90 = OpVectorShuffle %v3float %89 %89 2 0 1
-         %91 = OpFunctionCall %void %d %90
-         %92 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v3float %92 None
-         %94 = OpVectorShuffle %v3float %93 %93 2 0 1
-         %95 = OpCompositeExtract %float %94 0
-         %96 = OpFunctionCall %void %e %95
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v3float %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v3float %79 None
+         %82 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_4
+         %83 = OpLoad %v3float %82 None
+         %84 = OpCompositeConstruct %mat4v3float %76 %78 %81 %83
+         %85 = OpFunctionCall %void %c %84
+         %86 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v3float %86 None
+         %88 = OpVectorShuffle %v3float %87 %87 2 0 1
+         %89 = OpFunctionCall %void %d %88
+         %90 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %91 = OpLoad %v3float %90 None
+         %92 = OpVectorShuffle %v3float %91 %91 2 0 1
+         %93 = OpCompositeExtract %float %92 0
+         %94 = OpFunctionCall %void %e %93
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %98
+%tint_convert_S = OpFunction %S None %96
  %tint_input = OpFunctionParameter %S_std140
-         %99 = OpLabel
-        %100 = OpCompositeExtract %int %tint_input 0
-        %101 = OpCompositeExtract %v3float %tint_input 1
-        %102 = OpCompositeExtract %v3float %tint_input 2
-        %103 = OpCompositeExtract %v3float %tint_input 3
-        %104 = OpCompositeExtract %v3float %tint_input 4
-        %105 = OpCompositeConstruct %mat4v3float %101 %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 5
-        %107 = OpCompositeConstruct %S %100 %105 %106
-               OpReturnValue %107
+         %97 = OpLabel
+         %98 = OpCompositeExtract %int %tint_input 0
+         %99 = OpCompositeExtract %v3float %tint_input 1
+        %100 = OpCompositeExtract %v3float %tint_input 2
+        %101 = OpCompositeExtract %v3float %tint_input 3
+        %102 = OpCompositeExtract %v3float %tint_input 4
+        %103 = OpCompositeConstruct %mat4v3float %99 %100 %101 %102
+        %104 = OpCompositeExtract %int %tint_input 5
+        %105 = OpCompositeConstruct %S %98 %103 %104
+               OpReturnValue %105
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.glsl
index 16f6722..5935762 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.glsl
@@ -78,7 +78,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  p[1].m[0] = v.inner[0].m_col1.zxy;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  p[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 973dbfe..1ae69b4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(384u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(400u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(400u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 973dbfe..1ae69b4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(384u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(400u);
-  p[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  p[1u] = v_11;
+  p[3u].m = v(400u);
+  p[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.msl
index d0f7e76..7b1177a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.ir.msl
@@ -59,11 +59,11 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = tint_load_array_packed_vec3(tint_module_vars.u);
-  (*tint_module_vars.p)[1] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2]));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_9 = (*tint_module_vars.u)[2].m;
+  (*tint_module_vars.p)[1u] = tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u]));
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_9 = (*tint_module_vars.u)[2u].m;
   float3 const v_10 = float3(v_9[0u].packed);
   float3 const v_11 = float3(v_9[1u].packed);
   float3 const v_12 = float3(v_9[2u].packed);
-  (*tint_module_vars.p)[3].m = float4x3(v_10, v_11, v_12, float3(v_9[3u].packed));
-  (*tint_module_vars.p)[1].m[0] = float3((*tint_module_vars.u)[0].m[1].packed).zxy;
+  (*tint_module_vars.p)[3u].m = float4x3(v_10, v_11, v_12, float3(v_9[3u].packed));
+  (*tint_module_vars.p)[1u].m[0u] = float3((*tint_module_vars.u)[0u].m[1u].packed).zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.spvasm
index 7531ffb..4e66752 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -69,17 +69,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v3float = OpTypePointer Private %mat4v3float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v3float = OpTypePointer Private %mat4v3float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-      %int_0 = OpConstant %int 0
-         %79 = OpTypeFunction %S %S_std140
+         %75 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -113,39 +109,39 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat4v3float %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v3float %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v3float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_4
-         %70 = OpLoad %v3float %69 None
-         %71 = OpCompositeConstruct %mat4v3float %62 %65 %68 %70
-               OpStore %57 %71 None
-         %72 = OpAccessChain %_ptr_Private_v3float %p %int_1 %uint_1 %int_0
-         %75 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %76 = OpLoad %v3float %75 None
-         %77 = OpVectorShuffle %v3float %76 %76 2 0 1
-               OpStore %72 %77 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat4v3float %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v3float %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v3float %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v3float %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_4
+         %67 = OpLoad %v3float %66 None
+         %68 = OpCompositeConstruct %mat4v3float %61 %63 %65 %67
+               OpStore %56 %68 None
+         %69 = OpAccessChain %_ptr_Private_v3float %p %uint_1 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %72 = OpLoad %v3float %71 None
+         %73 = OpVectorShuffle %v3float %72 %72 2 0 1
+               OpStore %69 %73 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %79
+%tint_convert_S = OpFunction %S None %75
  %tint_input = OpFunctionParameter %S_std140
-         %80 = OpLabel
-         %81 = OpCompositeExtract %int %tint_input 0
-         %82 = OpCompositeExtract %v3float %tint_input 1
-         %83 = OpCompositeExtract %v3float %tint_input 2
-         %84 = OpCompositeExtract %v3float %tint_input 3
-         %85 = OpCompositeExtract %v3float %tint_input 4
-         %86 = OpCompositeConstruct %mat4v3float %82 %83 %84 %85
-         %87 = OpCompositeExtract %int %tint_input 5
-         %88 = OpCompositeConstruct %S %81 %86 %87
-               OpReturnValue %88
+         %76 = OpLabel
+         %77 = OpCompositeExtract %int %tint_input 0
+         %78 = OpCompositeExtract %v3float %tint_input 1
+         %79 = OpCompositeExtract %v3float %tint_input 2
+         %80 = OpCompositeExtract %v3float %tint_input 3
+         %81 = OpCompositeExtract %v3float %tint_input 4
+         %82 = OpCompositeConstruct %mat4v3float %78 %79 %80 %81
+         %83 = OpCompositeExtract %int %tint_input 5
+         %84 = OpCompositeConstruct %S %77 %82 %83
+               OpReturnValue %84
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
index 66fe932..1e6322e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -139,9 +139,9 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  mat4x3 v_9 = mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  tint_store_and_preserve_padding_2(uint[1](uint(3)), v_9);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.zxy;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  mat4x3 v_9 = mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  tint_store_and_preserve_padding_2(uint[1](3u), v_9);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.ir.msl
index d57a1fc..931f4ef 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.ir.msl
@@ -33,6 +33,9 @@
   int after;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S_packed_vec3, 4>* u;
   device tint_array<S_packed_vec3, 4>* s;
@@ -66,6 +69,7 @@
     uint v_6 = 0u;
     v_6 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_7 = v_6;
       if ((v_7 >= 4u)) {
         break;
@@ -89,11 +93,11 @@
 kernel void f(const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], device tint_array<S_packed_vec3, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_11 = (*tint_module_vars.u)[2].m;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_11 = (*tint_module_vars.u)[2u].m;
   float3 const v_12 = float3(v_11[0u].packed);
   float3 const v_13 = float3(v_11[1u].packed);
   float3 const v_14 = float3(v_11[2u].packed);
-  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3].m), float4x3(v_12, v_13, v_14, float3(v_11[3u].packed)));
-  (*tint_module_vars.s)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  tint_store_and_preserve_padding_2((&(*tint_module_vars.s)[3u].m), float4x3(v_12, v_13, v_14, float3(v_11[3u].packed)));
+  (*tint_module_vars.s)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
index 2b11545..9a6813c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -67,7 +70,8 @@
 
 void assign_and_preserve_padding(device tint_array<S_tint_packed_vec3, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
index 7ae3e0a..d1da6ff 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 141
+; Bound: 135
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -85,20 +85,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-      %int_3 = OpConstant %int 3
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-      %int_0 = OpConstant %int 0
-         %87 = OpTypeFunction %void %_arr_S_uint_4
-        %106 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %81 = OpTypeFunction %void %_arr_S_uint_4
+        %100 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %119 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
-        %131 = OpTypeFunction %S %S_std140
+        %113 = OpTypeFunction %void %_arr_uint_uint_1 %mat4v3float
+        %125 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -132,106 +128,104 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %65 = OpLoad %v3float %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %63 = OpLoad %v3float %61 None
+         %64 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %65 = OpLoad %v3float %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
          %68 = OpLoad %v3float %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %71 = OpLoad %v3float %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_4
-         %73 = OpLoad %v3float %72 None
-         %74 = OpCompositeConstruct %mat4v3float %65 %68 %71 %73
-         %75 = OpBitcast %uint %int_3
-         %77 = OpCompositeConstruct %_arr_uint_uint_1 %75
-         %78 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %77 %74
-         %80 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %int_1 %uint_1 %int_0
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %84 = OpLoad %v3float %83 None
-         %85 = OpVectorShuffle %v3float %84 %84 2 0 1
-               OpStore %80 %85 None
+         %69 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_4
+         %70 = OpLoad %v3float %69 None
+         %71 = OpCompositeConstruct %mat4v3float %63 %65 %68 %70
+         %72 = OpCompositeConstruct %_arr_uint_uint_1 %uint_3
+         %73 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %72 %71
+         %75 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %77 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %78 = OpLoad %v3float %77 None
+         %79 = OpVectorShuffle %v3float %78 %78 2 0 1
+               OpStore %75 %79 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %87
+%tint_store_and_preserve_padding = OpFunction %void None %81
 %value_param = OpFunctionParameter %_arr_S_uint_4
-         %88 = OpLabel
-         %89 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %89 %value_param
-               OpBranch %90
-         %90 = OpLabel
-               OpBranch %93
+         %82 = OpLabel
+         %83 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %83 %value_param
+               OpBranch %84
+         %84 = OpLabel
+               OpBranch %87
+         %87 = OpLabel
+         %89 = OpPhi %uint %uint_0 %84 %90 %86
+               OpLoopMerge %88 %86 None
+               OpBranch %85
+         %85 = OpLabel
+         %91 = OpUGreaterThanEqual %bool %89 %uint_4
+               OpSelectionMerge %92 None
+               OpBranchConditional %91 %93 %92
          %93 = OpLabel
-         %95 = OpPhi %uint %uint_0 %90 %96 %92
-               OpLoopMerge %94 %92 None
-               OpBranch %91
-         %91 = OpLabel
-         %97 = OpUGreaterThanEqual %bool %95 %uint_4
-               OpSelectionMerge %98 None
-               OpBranchConditional %97 %99 %98
-         %99 = OpLabel
-               OpBranch %94
-         %98 = OpLabel
-        %100 = OpAccessChain %_ptr_Function_S %89 %95
-        %101 = OpLoad %S %100 None
-        %102 = OpCompositeConstruct %_arr_uint_uint_1 %95
-        %103 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %102 %101
-               OpBranch %92
+               OpBranch %88
          %92 = OpLabel
-         %96 = OpIAdd %uint %95 %uint_1
-               OpBranch %93
-         %94 = OpLabel
+         %94 = OpAccessChain %_ptr_Function_S %83 %89
+         %95 = OpLoad %S %94 None
+         %96 = OpCompositeConstruct %_arr_uint_uint_1 %89
+         %97 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %96 %95
+               OpBranch %86
+         %86 = OpLabel
+         %90 = OpIAdd %uint %89 %uint_1
+               OpBranch %87
+         %88 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %106
+%tint_store_and_preserve_padding_0 = OpFunction %void None %100
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %107 = OpLabel
-        %108 = OpCompositeExtract %uint %target_indices 0
-        %109 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %108 %uint_0
-        %111 = OpCompositeExtract %int %value_param_0 0
-               OpStore %109 %111 None
-        %112 = OpCompositeExtract %mat4v3float %value_param_0 1
-        %113 = OpCompositeConstruct %_arr_uint_uint_1 %108
-        %114 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %113 %112
-        %115 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %108 %uint_2
-        %116 = OpCompositeExtract %int %value_param_0 2
-               OpStore %115 %116 None
+        %101 = OpLabel
+        %102 = OpCompositeExtract %uint %target_indices 0
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %102 %uint_0
+        %105 = OpCompositeExtract %int %value_param_0 0
+               OpStore %103 %105 None
+        %106 = OpCompositeExtract %mat4v3float %value_param_0 1
+        %107 = OpCompositeConstruct %_arr_uint_uint_1 %102
+        %108 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %107 %106
+        %109 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %102 %uint_2
+        %110 = OpCompositeExtract %int %value_param_0 2
+               OpStore %109 %110 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %119
+%tint_store_and_preserve_padding_1 = OpFunction %void None %113
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat4v3float
-        %120 = OpLabel
-        %121 = OpCompositeExtract %uint %target_indices_0 0
-        %122 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %121 %uint_1 %uint_0
-        %123 = OpCompositeExtract %v3float %value_param_1 0
+        %114 = OpLabel
+        %115 = OpCompositeExtract %uint %target_indices_0 0
+        %116 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %115 %uint_1 %uint_0
+        %117 = OpCompositeExtract %v3float %value_param_1 0
+               OpStore %116 %117 None
+        %118 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %115 %uint_1 %uint_1
+        %119 = OpCompositeExtract %v3float %value_param_1 1
+               OpStore %118 %119 None
+        %120 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %115 %uint_1 %uint_2
+        %121 = OpCompositeExtract %v3float %value_param_1 2
+               OpStore %120 %121 None
+        %122 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %115 %uint_1 %uint_3
+        %123 = OpCompositeExtract %v3float %value_param_1 3
                OpStore %122 %123 None
-        %124 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %121 %uint_1 %uint_1
-        %125 = OpCompositeExtract %v3float %value_param_1 1
-               OpStore %124 %125 None
-        %126 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %121 %uint_1 %uint_2
-        %127 = OpCompositeExtract %v3float %value_param_1 2
-               OpStore %126 %127 None
-        %128 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %121 %uint_1 %uint_3
-        %129 = OpCompositeExtract %v3float %value_param_1 3
-               OpStore %128 %129 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %131
+%tint_convert_S = OpFunction %S None %125
  %tint_input = OpFunctionParameter %S_std140
-        %132 = OpLabel
-        %133 = OpCompositeExtract %int %tint_input 0
-        %134 = OpCompositeExtract %v3float %tint_input 1
-        %135 = OpCompositeExtract %v3float %tint_input 2
-        %136 = OpCompositeExtract %v3float %tint_input 3
-        %137 = OpCompositeExtract %v3float %tint_input 4
-        %138 = OpCompositeConstruct %mat4v3float %134 %135 %136 %137
-        %139 = OpCompositeExtract %int %tint_input 5
-        %140 = OpCompositeConstruct %S %133 %138 %139
-               OpReturnValue %140
+        %126 = OpLabel
+        %127 = OpCompositeExtract %int %tint_input 0
+        %128 = OpCompositeExtract %v3float %tint_input 1
+        %129 = OpCompositeExtract %v3float %tint_input 2
+        %130 = OpCompositeExtract %v3float %tint_input 3
+        %131 = OpCompositeExtract %v3float %tint_input 4
+        %132 = OpCompositeConstruct %mat4v3float %128 %129 %130 %131
+        %133 = OpCompositeExtract %int %tint_input 5
+        %134 = OpCompositeConstruct %S %127 %132 %133
+               OpReturnValue %134
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.glsl
index bf9ad96..f251ab1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.glsl
@@ -93,9 +93,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = mat4x3(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  w[1].m[0] = v.inner[0].m_col1.zxy;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = mat4x3(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  w[1u].m[0u] = v.inner[0u].m_col1.zxy;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 0edb429d..d257173 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(384u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(400u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(400u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 0edb429d..d257173 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(384u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(400u);
-  w[int(1)].m[int(0)] = asfloat(u[2u].xyz).zxy;
+  w[1u] = v_14;
+  w[3u].m = v(400u);
+  w[1u].m[0u] = asfloat(u[2u].xyz).zxy;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
index 7af8107..4a34690 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -38,6 +38,9 @@
   threadgroup tint_array<S_packed_vec3, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_packed_vec3, 4> tint_symbol;
 };
@@ -80,6 +83,7 @@
     uint v_9 = 0u;
     v_9 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_10 = v_9;
       if ((v_10 >= 4u)) {
         break;
@@ -93,17 +97,17 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_store_array_packed_vec3(tint_module_vars.w, tint_load_array_packed_vec3(tint_module_vars.u));
-  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2])));
-  tint_array<tint_packed_vec3_f32_array_element, 4> const v_11 = (*tint_module_vars.u)[2].m;
+  tint_store_array_packed_vec3_1((&(*tint_module_vars.w)[1u]), tint_load_struct_packed_vec3((&(*tint_module_vars.u)[2u])));
+  tint_array<tint_packed_vec3_f32_array_element, 4> const v_11 = (*tint_module_vars.u)[2u].m;
   float3 const v_12 = float3(v_11[0u].packed);
   float3 const v_13 = float3(v_11[1u].packed);
   float3 const v_14 = float3(v_11[2u].packed);
   float4x3 const v_15 = float4x3(v_12, v_13, v_14, float3(v_11[3u].packed));
-  (*tint_module_vars.w)[3].m[0u].packed = packed_float3(v_15[0u]);
-  (*tint_module_vars.w)[3].m[1u].packed = packed_float3(v_15[1u]);
-  (*tint_module_vars.w)[3].m[2u].packed = packed_float3(v_15[2u]);
-  (*tint_module_vars.w)[3].m[3u].packed = packed_float3(v_15[3u]);
-  (*tint_module_vars.w)[1].m[0].packed = packed_float3(float3((*tint_module_vars.u)[0].m[1].packed).zxy);
+  (*tint_module_vars.w)[3u].m[0u].packed = packed_float3(v_15[0u]);
+  (*tint_module_vars.w)[3u].m[1u].packed = packed_float3(v_15[1u]);
+  (*tint_module_vars.w)[3u].m[2u].packed = packed_float3(v_15[2u]);
+  (*tint_module_vars.w)[3u].m[3u].packed = packed_float3(v_15[3u]);
+  (*tint_module_vars.w)[1u].m[0u].packed = packed_float3(float3((*tint_module_vars.u)[0u].m[1u].packed).zxy);
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S_packed_vec3, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_16 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.msl
index 18e7ce1..881302d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -49,6 +52,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_tint_packed_vec3, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_pack_vec3_in_composite_1(tint_symbol);
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
index e73d819..849abfa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 107
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -78,17 +78,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v3float = OpTypePointer Workgroup %mat4v3float
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %void
-        %101 = OpTypeFunction %S %S_std140
+         %92 = OpTypeFunction %void
+         %97 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -145,45 +141,45 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat4v3float %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v3float %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat4v3float %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v3float %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v3float %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v3float %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v3float %83 None
-         %86 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_2 %uint_4
-         %87 = OpLoad %v3float %86 None
-         %88 = OpCompositeConstruct %mat4v3float %80 %82 %85 %87
-               OpStore %75 %88 None
-         %89 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1 %uint_1 %int_0
-         %92 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v3float %92 None
-         %94 = OpVectorShuffle %v3float %93 %93 2 0 1
-               OpStore %89 %94 None
+         %83 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_2 %uint_4
+         %84 = OpLoad %v3float %83 None
+         %85 = OpCompositeConstruct %mat4v3float %78 %80 %82 %84
+               OpStore %73 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1 %uint_1 %uint_0
+         %88 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v3float %88 None
+         %90 = OpVectorShuffle %v3float %89 %89 2 0 1
+               OpStore %86 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %96
-         %97 = OpLabel
-         %98 = OpLoad %uint %f_local_invocation_index_Input None
-         %99 = OpFunctionCall %void %f_inner %98
+          %f = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %uint %f_local_invocation_index_Input None
+         %95 = OpFunctionCall %void %f_inner %94
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %101
+%tint_convert_S = OpFunction %S None %97
  %tint_input = OpFunctionParameter %S_std140
-        %102 = OpLabel
-        %103 = OpCompositeExtract %int %tint_input 0
-        %104 = OpCompositeExtract %v3float %tint_input 1
-        %105 = OpCompositeExtract %v3float %tint_input 2
-        %106 = OpCompositeExtract %v3float %tint_input 3
-        %107 = OpCompositeExtract %v3float %tint_input 4
-        %108 = OpCompositeConstruct %mat4v3float %104 %105 %106 %107
-        %109 = OpCompositeExtract %int %tint_input 5
-        %110 = OpCompositeConstruct %S %103 %108 %109
-               OpReturnValue %110
+         %98 = OpLabel
+         %99 = OpCompositeExtract %int %tint_input 0
+        %100 = OpCompositeExtract %v3float %tint_input 1
+        %101 = OpCompositeExtract %v3float %tint_input 2
+        %102 = OpCompositeExtract %v3float %tint_input 3
+        %103 = OpCompositeExtract %v3float %tint_input 4
+        %104 = OpCompositeConstruct %mat4v3float %100 %101 %102 %103
+        %105 = OpCompositeExtract %int %tint_input 5
+        %106 = OpCompositeConstruct %S %99 %104 %105
+               OpReturnValue %106
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 1f246d9..d9bbe48 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -77,11 +77,11 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  matrix<float16_t, 4, 4> l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (8u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  matrix<float16_t, 4, 4> l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (8u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   uint4 ubo_load_9 = a[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
@@ -91,7 +91,7 @@
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_bytes = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (8u * uint(tint_symbol_2))) + (2u * uint(tint_symbol_3))));
+  const uint scalar_offset_bytes = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (8u * min(uint(tint_symbol_2), 3u))) + (2u * min(uint(tint_symbol_3), 3u))));
   const uint scalar_offset_index = scalar_offset_bytes / 4;
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32(((a[scalar_offset_index / 4][scalar_offset_index % 4] >> (scalar_offset_bytes % 4 == 0 ? 0 : 16)) & 0xFFFF)));
   return;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 27fbfa0..01358a2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -62,10 +62,10 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_4 = i();
-  int v_5 = i();
+  uint v_4 = min(uint(i()), 3u);
+  uint v_5 = min(uint(i()), 3u);
   f16mat4 v_6 = f16mat4(v.inner[v_4].a[v_5].m_col0, v.inner[v_4].a[v_5].m_col1, v.inner[v_4].a[v_5].m_col2, v.inner[v_4].a[v_5].m_col3);
-  f16vec4 v_7 = v_6[i()];
+  f16vec4 v_7 = v_6[min(uint(i()), 3u)];
   Outer_std140 v_8[4] = v.inner;
   Outer v_9[4] = Outer[4](Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -106,5 +106,5 @@
   Inner l_a_i_a_i = tint_convert_Inner(v.inner[v_4].a[v_5]);
   f16mat4 l_a_i_a_i_m = v_6;
   f16vec4 l_a_i_a_i_m_i = v_7;
-  float16_t l_a_i_a_i_m_i_i = v_7[i()];
+  float16_t l_a_i_a_i_m_i_i = v_7[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 0cc994b..e47b3e2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -98,9 +98,9 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_27 = (256u * uint(i()));
-  uint v_28 = (64u * uint(i()));
-  uint v_29 = (8u * uint(i()));
+  uint v_27 = (256u * uint(min(uint(i()), 3u)));
+  uint v_28 = (64u * uint(min(uint(i()), 3u)));
+  uint v_29 = (8u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_22(0u);
   Outer l_a_i = v_19(v_27);
   Inner l_a_i_a[4] = v_14(v_27);
@@ -108,7 +108,7 @@
   matrix<float16_t, 4, 4> l_a_i_a_i_m = v_4((v_27 + v_28));
   uint4 v_30 = a[(((v_27 + v_28) + v_29) / 16u)];
   vector<float16_t, 4> l_a_i_a_i_m_i = tint_bitcast_to_f16((((((((v_27 + v_28) + v_29) % 16u) / 4u) == 2u)) ? (v_30.zw) : (v_30.xy)));
-  uint v_31 = (((v_27 + v_28) + v_29) + (uint(i()) * 2u));
+  uint v_31 = (((v_27 + v_28) + v_29) + (uint(min(uint(i()), 3u)) * 2u));
   uint v_32 = a[(v_31 / 16u)][((v_31 % 16u) / 4u)];
   float16_t l_a_i_a_i_m_i_i = float16_t(f16tof32((v_32 >> ((((v_31 % 4u) == 0u)) ? (0u) : (16u)))));
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 6ef00d4..dee2cbd 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -36,16 +36,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant half4x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant half4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   half4x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   half4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  half const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 6af3608..823dad6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -36,11 +36,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -48,7 +48,7 @@
   half4x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   half4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  half const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index c9b6420..8912b92 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 157
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -76,13 +77,13 @@
          %25 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
 %_ptr_Function_mat4v4half = OpTypePointer Function %mat4v4half
 %_ptr_Function_v4half = OpTypePointer Function %v4half
@@ -92,17 +93,17 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %67 = OpConstantNull %_arr_Outer_uint_4
+         %74 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %94 = OpConstantNull %_arr_Inner_uint_4
+        %101 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %118 = OpTypeFunction %Inner %Inner_std140
-        %127 = OpTypeFunction %Outer %Outer_std140
+        %127 = OpTypeFunction %Inner %Inner_std140
+        %136 = OpTypeFunction %Outer %Outer_std140
           %i = OpFunction %int None %17
          %18 = OpLabel
          %19 = OpLoad %int %counter None
@@ -113,135 +114,143 @@
                OpFunctionEnd
           %f = OpFunction %void None %25
          %26 = OpLabel
-         %52 = OpVariable %_ptr_Function_mat4v4half Function
-         %59 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %61 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %67
-         %90 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %92 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
+         %57 = OpVariable %_ptr_Function_mat4v4half Function
+         %66 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %68 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %74
+         %97 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %99 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
          %27 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
          %30 = OpFunctionCall %int %i
-         %31 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %30
-         %33 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %31 %uint_0
-         %35 = OpFunctionCall %int %i
-         %36 = OpAccessChain %_ptr_Uniform_Inner_std140 %33 %35
-         %38 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_0
-         %40 = OpLoad %v4half %38 None
-         %41 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_1
-         %43 = OpLoad %v4half %41 None
-         %44 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_2
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Uniform_Outer_std140 %27 %32
+         %37 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %35 %uint_0
+         %39 = OpFunctionCall %int %i
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %33 UMin %40 %uint_3
+         %42 = OpAccessChain %_ptr_Uniform_Inner_std140 %37 %41
+         %44 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_0
          %46 = OpLoad %v4half %44 None
-         %47 = OpAccessChain %_ptr_Uniform_v4half %36 %uint_3
+         %47 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_1
          %49 = OpLoad %v4half %47 None
-%l_a_i_a_i_m = OpCompositeConstruct %mat4v4half %40 %43 %46 %49
-               OpStore %52 %l_a_i_a_i_m
-         %54 = OpFunctionCall %int %i
-         %55 = OpAccessChain %_ptr_Function_v4half %52 %54
-%l_a_i_a_i_m_i = OpLoad %v4half %55 None
-         %58 = OpLoad %_arr_Outer_std140_uint_4 %27 None
-               OpStore %59 %58
-               OpBranch %68
-         %68 = OpLabel
-               OpBranch %71
-         %71 = OpLabel
-         %73 = OpPhi %uint %uint_0 %68 %74 %70
-               OpLoopMerge %72 %70 None
-               OpBranch %69
-         %69 = OpLabel
-         %75 = OpUGreaterThanEqual %bool %73 %uint_4
-               OpSelectionMerge %77 None
-               OpBranchConditional %75 %78 %77
+         %50 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_2
+         %52 = OpLoad %v4half %50 None
+         %53 = OpAccessChain %_ptr_Uniform_v4half %42 %uint_3
+         %54 = OpLoad %v4half %53 None
+%l_a_i_a_i_m = OpCompositeConstruct %mat4v4half %46 %49 %52 %54
+               OpStore %57 %l_a_i_a_i_m
+         %59 = OpFunctionCall %int %i
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %33 UMin %60 %uint_3
+         %62 = OpAccessChain %_ptr_Function_v4half %57 %61
+%l_a_i_a_i_m_i = OpLoad %v4half %62 None
+         %65 = OpLoad %_arr_Outer_std140_uint_4 %27 None
+               OpStore %66 %65
+               OpBranch %75
+         %75 = OpLabel
+               OpBranch %78
          %78 = OpLabel
-               OpBranch %72
+         %80 = OpPhi %uint %uint_0 %75 %81 %77
+               OpLoopMerge %79 %77 None
+               OpBranch %76
+         %76 = OpLabel
+         %82 = OpUGreaterThanEqual %bool %80 %uint_4
+               OpSelectionMerge %84 None
+               OpBranchConditional %82 %85 %84
+         %85 = OpLabel
+               OpBranch %79
+         %84 = OpLabel
+         %86 = OpAccessChain %_ptr_Function_Outer %68 %80
+         %88 = OpAccessChain %_ptr_Function_Outer_std140 %66 %80
+         %90 = OpLoad %Outer_std140 %88 None
+         %91 = OpFunctionCall %Outer %tint_convert_Outer %90
+               OpStore %86 %91 None
+               OpBranch %77
          %77 = OpLabel
-         %79 = OpAccessChain %_ptr_Function_Outer %61 %73
-         %81 = OpAccessChain %_ptr_Function_Outer_std140 %59 %73
-         %83 = OpLoad %Outer_std140 %81 None
-         %84 = OpFunctionCall %Outer %tint_convert_Outer %83
-               OpStore %79 %84 None
-               OpBranch %70
-         %70 = OpLabel
-         %74 = OpIAdd %uint %73 %uint_1
-               OpBranch %71
-         %72 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %61 None
-         %87 = OpLoad %Outer_std140 %31 None
-      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %87
-         %89 = OpLoad %_arr_Inner_std140_uint_4 %33 None
-               OpStore %90 %89
-               OpBranch %95
-         %95 = OpLabel
-               OpBranch %98
-         %98 = OpLabel
-        %100 = OpPhi %uint %uint_0 %95 %101 %97
-               OpLoopMerge %99 %97 None
-               OpBranch %96
-         %96 = OpLabel
-        %102 = OpUGreaterThanEqual %bool %100 %uint_4
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %103
-        %104 = OpLabel
-               OpBranch %99
+         %81 = OpIAdd %uint %80 %uint_1
+               OpBranch %78
+         %79 = OpLabel
+        %l_a = OpLoad %_arr_Outer_uint_4 %68 None
+         %94 = OpLoad %Outer_std140 %35 None
+      %l_a_i = OpFunctionCall %Outer %tint_convert_Outer %94
+         %96 = OpLoad %_arr_Inner_std140_uint_4 %37 None
+               OpStore %97 %96
+               OpBranch %102
+        %102 = OpLabel
+               OpBranch %105
+        %105 = OpLabel
+        %107 = OpPhi %uint %uint_0 %102 %108 %104
+               OpLoopMerge %106 %104 None
+               OpBranch %103
         %103 = OpLabel
-        %105 = OpAccessChain %_ptr_Function_Inner %92 %100
-        %107 = OpAccessChain %_ptr_Function_Inner_std140 %90 %100
-        %109 = OpLoad %Inner_std140 %107 None
-        %110 = OpFunctionCall %Inner %tint_convert_Inner %109
-               OpStore %105 %110 None
-               OpBranch %97
-         %97 = OpLabel
-        %101 = OpIAdd %uint %100 %uint_1
-               OpBranch %98
-         %99 = OpLabel
-    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %92 None
-        %113 = OpLoad %Inner_std140 %36 None
-  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %113
-        %115 = OpFunctionCall %int %i
-%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %115
+        %109 = OpUGreaterThanEqual %bool %107 %uint_4
+               OpSelectionMerge %110 None
+               OpBranchConditional %109 %111 %110
+        %111 = OpLabel
+               OpBranch %106
+        %110 = OpLabel
+        %112 = OpAccessChain %_ptr_Function_Inner %99 %107
+        %114 = OpAccessChain %_ptr_Function_Inner_std140 %97 %107
+        %116 = OpLoad %Inner_std140 %114 None
+        %117 = OpFunctionCall %Inner %tint_convert_Inner %116
+               OpStore %112 %117 None
+               OpBranch %104
+        %104 = OpLabel
+        %108 = OpIAdd %uint %107 %uint_1
+               OpBranch %105
+        %106 = OpLabel
+    %l_a_i_a = OpLoad %_arr_Inner_uint_4 %99 None
+        %120 = OpLoad %Inner_std140 %42 None
+  %l_a_i_a_i = OpFunctionCall %Inner %tint_convert_Inner %120
+        %122 = OpFunctionCall %int %i
+        %123 = OpBitcast %uint %122
+        %124 = OpExtInst %uint %33 UMin %123 %uint_3
+%l_a_i_a_i_m_i_i = OpVectorExtractDynamic %half %l_a_i_a_i_m_i %124
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %118
+%tint_convert_Inner = OpFunction %Inner None %127
  %tint_input = OpFunctionParameter %Inner_std140
-        %119 = OpLabel
-        %120 = OpCompositeExtract %v4half %tint_input 0
-        %121 = OpCompositeExtract %v4half %tint_input 1
-        %122 = OpCompositeExtract %v4half %tint_input 2
-        %123 = OpCompositeExtract %v4half %tint_input 3
-        %124 = OpCompositeConstruct %mat4v4half %120 %121 %122 %123
-        %125 = OpCompositeConstruct %Inner %124
-               OpReturnValue %125
-               OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %127
-%tint_input_0 = OpFunctionParameter %Outer_std140
         %128 = OpLabel
-        %130 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %131 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %94
-        %129 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %130 %129
-               OpBranch %132
-        %132 = OpLabel
-               OpBranch %135
-        %135 = OpLabel
-        %137 = OpPhi %uint %uint_0 %132 %138 %134
-               OpLoopMerge %136 %134 None
-               OpBranch %133
-        %133 = OpLabel
-        %139 = OpUGreaterThanEqual %bool %137 %uint_4
-               OpSelectionMerge %140 None
-               OpBranchConditional %139 %141 %140
+        %129 = OpCompositeExtract %v4half %tint_input 0
+        %130 = OpCompositeExtract %v4half %tint_input 1
+        %131 = OpCompositeExtract %v4half %tint_input 2
+        %132 = OpCompositeExtract %v4half %tint_input 3
+        %133 = OpCompositeConstruct %mat4v4half %129 %130 %131 %132
+        %134 = OpCompositeConstruct %Inner %133
+               OpReturnValue %134
+               OpFunctionEnd
+%tint_convert_Outer = OpFunction %Outer None %136
+%tint_input_0 = OpFunctionParameter %Outer_std140
+        %137 = OpLabel
+        %139 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %140 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %101
+        %138 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %139 %138
+               OpBranch %141
         %141 = OpLabel
-               OpBranch %136
-        %140 = OpLabel
-        %142 = OpAccessChain %_ptr_Function_Inner %131 %137
-        %143 = OpAccessChain %_ptr_Function_Inner_std140 %130 %137
-        %144 = OpLoad %Inner_std140 %143 None
-        %145 = OpFunctionCall %Inner %tint_convert_Inner %144
-               OpStore %142 %145 None
-               OpBranch %134
-        %134 = OpLabel
-        %138 = OpIAdd %uint %137 %uint_1
-               OpBranch %135
-        %136 = OpLabel
-        %146 = OpLoad %_arr_Inner_uint_4 %131 None
-        %147 = OpCompositeConstruct %Outer %146
-               OpReturnValue %147
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %uint_0 %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4
+               OpSelectionMerge %149 None
+               OpBranchConditional %148 %150 %149
+        %150 = OpLabel
+               OpBranch %145
+        %149 = OpLabel
+        %151 = OpAccessChain %_ptr_Function_Inner %140 %146
+        %152 = OpAccessChain %_ptr_Function_Inner_std140 %139 %146
+        %153 = OpLoad %Inner_std140 %152 None
+        %154 = OpFunctionCall %Inner %tint_convert_Inner %153
+               OpStore %151 %154 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_1
+               OpBranch %144
+        %145 = OpLabel
+        %155 = OpLoad %_arr_Inner_uint_4 %140 None
+        %156 = OpCompositeConstruct %Outer %155
+               OpReturnValue %156
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
index fd9333e..310d279 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -57,7 +57,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4 v_4 = f16mat4(v.inner[3].a[2].m_col0, v.inner[3].a[2].m_col1, v.inner[3].a[2].m_col2, v.inner[3].a[2].m_col3);
+  f16mat4 v_4 = f16mat4(v.inner[3u].a[2u].m_col0, v.inner[3u].a[2u].m_col1, v.inner[3u].a[2u].m_col2, v.inner[3u].a[2u].m_col3);
   Outer_std140 v_5[4] = v.inner;
   Outer v_6[4] = Outer[4](Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))), Outer(Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))))));
   {
@@ -76,8 +76,8 @@
     }
   }
   Outer l_a[4] = v_6;
-  Outer l_a_3 = tint_convert_Outer(v.inner[3]);
-  Inner_std140 v_9[4] = v.inner[3].a;
+  Outer l_a_3 = tint_convert_Outer(v.inner[3u]);
+  Inner_std140 v_9[4] = v.inner[3u].a;
   Inner v_10[4] = Inner[4](Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))), Inner(f16mat4(f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf), f16vec4(0.0hf))));
   {
     uint v_11 = 0u;
@@ -95,8 +95,8 @@
     }
   }
   Inner l_a_3_a[4] = v_10;
-  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3].a[2]);
+  Inner l_a_3_a_2 = tint_convert_Inner(v.inner[3u].a[2u]);
   f16mat4 l_a_3_a_2_m = v_4;
-  f16vec4 l_a_3_a_2_m_1 = v_4[1];
-  float16_t l_a_3_a_2_m_1_0 = v_4[1][0];
+  f16vec4 l_a_3_a_2_m_1 = v_4[1u];
+  float16_t l_a_3_a_2_m_1_0 = v_4[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 2c98d30..c143dfc 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -29,16 +29,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant half4x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant half4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   half4x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   half4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  half const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
index b7c579f..efa8f95 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 132
+; Bound: 129
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -69,15 +69,12 @@
 %_ptr_Uniform__arr_Outer_std140_uint_4 = OpTypePointer Uniform %_arr_Outer_std140_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer_std140 = OpTypePointer Uniform %Outer_std140
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_std140_uint_4 = OpTypePointer Uniform %_arr_Inner_std140_uint_4
 %_ptr_Uniform_Inner_std140 = OpTypePointer Uniform %Inner_std140
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_1 = OpConstant %uint 1
-     %uint_2 = OpConstant %uint 2
-     %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
 %_ptr_Function__arr_Outer_std140_uint_4 = OpTypePointer Function %_arr_Outer_std140_uint_4
       %Inner = OpTypeStruct %mat4v4half
@@ -85,141 +82,141 @@
       %Outer = OpTypeStruct %_arr_Inner_uint_4
 %_arr_Outer_uint_4 = OpTypeArray %Outer %uint_4
 %_ptr_Function__arr_Outer_uint_4 = OpTypePointer Function %_arr_Outer_uint_4
-         %52 = OpConstantNull %_arr_Outer_uint_4
+         %49 = OpConstantNull %_arr_Outer_uint_4
        %bool = OpTypeBool
 %_ptr_Function_Outer = OpTypePointer Function %Outer
 %_ptr_Function_Outer_std140 = OpTypePointer Function %Outer_std140
 %_ptr_Function__arr_Inner_std140_uint_4 = OpTypePointer Function %_arr_Inner_std140_uint_4
 %_ptr_Function__arr_Inner_uint_4 = OpTypePointer Function %_arr_Inner_uint_4
-         %79 = OpConstantNull %_arr_Inner_uint_4
+         %76 = OpConstantNull %_arr_Inner_uint_4
 %_ptr_Function_Inner = OpTypePointer Function %Inner
 %_ptr_Function_Inner_std140 = OpTypePointer Function %Inner_std140
-        %102 = OpTypeFunction %Inner %Inner_std140
-        %111 = OpTypeFunction %Outer %Outer_std140
+         %99 = OpTypeFunction %Inner %Inner_std140
+        %108 = OpTypeFunction %Outer %Outer_std140
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %44 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
-         %46 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %52
-         %75 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-         %77 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
+         %41 = OpVariable %_ptr_Function__arr_Outer_std140_uint_4 Function
+         %43 = OpVariable %_ptr_Function__arr_Outer_uint_4 Function %49
+         %72 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+         %74 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
          %16 = OpAccessChain %_ptr_Uniform__arr_Outer_std140_uint_4 %1 %uint_0
-         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %int_3
-         %23 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
-         %25 = OpAccessChain %_ptr_Uniform_Inner_std140 %23 %int_2
-         %28 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_0
-         %30 = OpLoad %v4half %28 None
-         %31 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_1
-         %33 = OpLoad %v4half %31 None
-         %34 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_2
-         %36 = OpLoad %v4half %34 None
-         %37 = OpAccessChain %_ptr_Uniform_v4half %25 %uint_3
-         %39 = OpLoad %v4half %37 None
-%l_a_3_a_2_m = OpCompositeConstruct %mat4v4half %30 %33 %36 %39
+         %19 = OpAccessChain %_ptr_Uniform_Outer_std140 %16 %uint_3
+         %22 = OpAccessChain %_ptr_Uniform__arr_Inner_std140_uint_4 %19 %uint_0
+         %24 = OpAccessChain %_ptr_Uniform_Inner_std140 %22 %uint_2
+         %27 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_0
+         %29 = OpLoad %v4half %27 None
+         %30 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_1
+         %32 = OpLoad %v4half %30 None
+         %33 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_2
+         %34 = OpLoad %v4half %33 None
+         %35 = OpAccessChain %_ptr_Uniform_v4half %24 %uint_3
+         %36 = OpLoad %v4half %35 None
+%l_a_3_a_2_m = OpCompositeConstruct %mat4v4half %29 %32 %34 %36
 %l_a_3_a_2_m_1 = OpCompositeExtract %v4half %l_a_3_a_2_m 1
-         %43 = OpLoad %_arr_Outer_std140_uint_4 %16 None
-               OpStore %44 %43
+         %40 = OpLoad %_arr_Outer_std140_uint_4 %16 None
+               OpStore %41 %40
+               OpBranch %50
+         %50 = OpLabel
                OpBranch %53
          %53 = OpLabel
-               OpBranch %56
-         %56 = OpLabel
-         %58 = OpPhi %uint %uint_0 %53 %59 %55
-               OpLoopMerge %57 %55 None
+         %55 = OpPhi %uint %uint_0 %50 %56 %52
+               OpLoopMerge %54 %52 None
+               OpBranch %51
+         %51 = OpLabel
+         %57 = OpUGreaterThanEqual %bool %55 %uint_4
+               OpSelectionMerge %59 None
+               OpBranchConditional %57 %60 %59
+         %60 = OpLabel
                OpBranch %54
+         %59 = OpLabel
+         %61 = OpAccessChain %_ptr_Function_Outer %43 %55
+         %63 = OpAccessChain %_ptr_Function_Outer_std140 %41 %55
+         %65 = OpLoad %Outer_std140 %63 None
+         %66 = OpFunctionCall %Outer %tint_convert_Outer %65
+               OpStore %61 %66 None
+               OpBranch %52
+         %52 = OpLabel
+         %56 = OpIAdd %uint %55 %uint_1
+               OpBranch %53
          %54 = OpLabel
-         %60 = OpUGreaterThanEqual %bool %58 %uint_4
-               OpSelectionMerge %62 None
-               OpBranchConditional %60 %63 %62
-         %63 = OpLabel
-               OpBranch %57
-         %62 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_Outer %46 %58
-         %66 = OpAccessChain %_ptr_Function_Outer_std140 %44 %58
-         %68 = OpLoad %Outer_std140 %66 None
-         %69 = OpFunctionCall %Outer %tint_convert_Outer %68
-               OpStore %64 %69 None
-               OpBranch %55
-         %55 = OpLabel
-         %59 = OpIAdd %uint %58 %uint_1
-               OpBranch %56
-         %57 = OpLabel
-        %l_a = OpLoad %_arr_Outer_uint_4 %46 None
-         %72 = OpLoad %Outer_std140 %19 None
-      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %72
-         %74 = OpLoad %_arr_Inner_std140_uint_4 %23 None
-               OpStore %75 %74
+        %l_a = OpLoad %_arr_Outer_uint_4 %43 None
+         %69 = OpLoad %Outer_std140 %19 None
+      %l_a_3 = OpFunctionCall %Outer %tint_convert_Outer %69
+         %71 = OpLoad %_arr_Inner_std140_uint_4 %22 None
+               OpStore %72 %71
+               OpBranch %77
+         %77 = OpLabel
                OpBranch %80
          %80 = OpLabel
-               OpBranch %83
-         %83 = OpLabel
-         %85 = OpPhi %uint %uint_0 %80 %86 %82
-               OpLoopMerge %84 %82 None
+         %82 = OpPhi %uint %uint_0 %77 %83 %79
+               OpLoopMerge %81 %79 None
+               OpBranch %78
+         %78 = OpLabel
+         %84 = OpUGreaterThanEqual %bool %82 %uint_4
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %85
+         %86 = OpLabel
                OpBranch %81
+         %85 = OpLabel
+         %87 = OpAccessChain %_ptr_Function_Inner %74 %82
+         %89 = OpAccessChain %_ptr_Function_Inner_std140 %72 %82
+         %91 = OpLoad %Inner_std140 %89 None
+         %92 = OpFunctionCall %Inner %tint_convert_Inner %91
+               OpStore %87 %92 None
+               OpBranch %79
+         %79 = OpLabel
+         %83 = OpIAdd %uint %82 %uint_1
+               OpBranch %80
          %81 = OpLabel
-         %87 = OpUGreaterThanEqual %bool %85 %uint_4
-               OpSelectionMerge %88 None
-               OpBranchConditional %87 %89 %88
-         %89 = OpLabel
-               OpBranch %84
-         %88 = OpLabel
-         %90 = OpAccessChain %_ptr_Function_Inner %77 %85
-         %92 = OpAccessChain %_ptr_Function_Inner_std140 %75 %85
-         %94 = OpLoad %Inner_std140 %92 None
-         %95 = OpFunctionCall %Inner %tint_convert_Inner %94
-               OpStore %90 %95 None
-               OpBranch %82
-         %82 = OpLabel
-         %86 = OpIAdd %uint %85 %uint_1
-               OpBranch %83
-         %84 = OpLabel
-    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %77 None
-         %98 = OpLoad %Inner_std140 %25 None
-  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %98
+    %l_a_3_a = OpLoad %_arr_Inner_uint_4 %74 None
+         %95 = OpLoad %Inner_std140 %24 None
+  %l_a_3_a_2 = OpFunctionCall %Inner %tint_convert_Inner %95
 %l_a_3_a_2_m_1_0 = OpCompositeExtract %half %l_a_3_a_2_m_1 0
                OpReturn
                OpFunctionEnd
-%tint_convert_Inner = OpFunction %Inner None %102
+%tint_convert_Inner = OpFunction %Inner None %99
  %tint_input = OpFunctionParameter %Inner_std140
-        %103 = OpLabel
-        %104 = OpCompositeExtract %v4half %tint_input 0
-        %105 = OpCompositeExtract %v4half %tint_input 1
-        %106 = OpCompositeExtract %v4half %tint_input 2
-        %107 = OpCompositeExtract %v4half %tint_input 3
-        %108 = OpCompositeConstruct %mat4v4half %104 %105 %106 %107
-        %109 = OpCompositeConstruct %Inner %108
-               OpReturnValue %109
+        %100 = OpLabel
+        %101 = OpCompositeExtract %v4half %tint_input 0
+        %102 = OpCompositeExtract %v4half %tint_input 1
+        %103 = OpCompositeExtract %v4half %tint_input 2
+        %104 = OpCompositeExtract %v4half %tint_input 3
+        %105 = OpCompositeConstruct %mat4v4half %101 %102 %103 %104
+        %106 = OpCompositeConstruct %Inner %105
+               OpReturnValue %106
                OpFunctionEnd
-%tint_convert_Outer = OpFunction %Outer None %111
+%tint_convert_Outer = OpFunction %Outer None %108
 %tint_input_0 = OpFunctionParameter %Outer_std140
-        %112 = OpLabel
-        %114 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
-        %115 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %79
-        %113 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
-               OpStore %114 %113
+        %109 = OpLabel
+        %111 = OpVariable %_ptr_Function__arr_Inner_std140_uint_4 Function
+        %112 = OpVariable %_ptr_Function__arr_Inner_uint_4 Function %76
+        %110 = OpCompositeExtract %_arr_Inner_std140_uint_4 %tint_input_0 0
+               OpStore %111 %110
+               OpBranch %113
+        %113 = OpLabel
                OpBranch %116
         %116 = OpLabel
-               OpBranch %119
-        %119 = OpLabel
-        %121 = OpPhi %uint %uint_0 %116 %122 %118
-               OpLoopMerge %120 %118 None
+        %118 = OpPhi %uint %uint_0 %113 %119 %115
+               OpLoopMerge %117 %115 None
+               OpBranch %114
+        %114 = OpLabel
+        %120 = OpUGreaterThanEqual %bool %118 %uint_4
+               OpSelectionMerge %121 None
+               OpBranchConditional %120 %122 %121
+        %122 = OpLabel
                OpBranch %117
+        %121 = OpLabel
+        %123 = OpAccessChain %_ptr_Function_Inner %112 %118
+        %124 = OpAccessChain %_ptr_Function_Inner_std140 %111 %118
+        %125 = OpLoad %Inner_std140 %124 None
+        %126 = OpFunctionCall %Inner %tint_convert_Inner %125
+               OpStore %123 %126 None
+               OpBranch %115
+        %115 = OpLabel
+        %119 = OpIAdd %uint %118 %uint_1
+               OpBranch %116
         %117 = OpLabel
-        %123 = OpUGreaterThanEqual %bool %121 %uint_4
-               OpSelectionMerge %124 None
-               OpBranchConditional %123 %125 %124
-        %125 = OpLabel
-               OpBranch %120
-        %124 = OpLabel
-        %126 = OpAccessChain %_ptr_Function_Inner %115 %121
-        %127 = OpAccessChain %_ptr_Function_Inner_std140 %114 %121
-        %128 = OpLoad %Inner_std140 %127 None
-        %129 = OpFunctionCall %Inner %tint_convert_Inner %128
-               OpStore %126 %129 None
-               OpBranch %118
-        %118 = OpLabel
-        %122 = OpIAdd %uint %121 %uint_1
-               OpBranch %119
-        %120 = OpLabel
-        %130 = OpLoad %_arr_Inner_uint_4 %115 None
-        %131 = OpCompositeConstruct %Outer %130
-               OpReturnValue %131
+        %127 = OpLoad %_arr_Inner_uint_4 %112 None
+        %128 = OpCompositeConstruct %Outer %127
+               OpReturnValue %128
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.glsl
index 176798f..747f6e2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.glsl
@@ -39,7 +39,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  f16mat4 t = transpose(f16mat4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3));
-  float16_t l = length(v.inner[0].m_col1.ywxz);
-  float16_t a = abs(v.inner[0].m_col1.ywxz[0u]);
+  f16mat4 t = transpose(f16mat4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3));
+  float16_t l = length(v.inner[0u].m_col1.ywxz);
+  float16_t a = abs(v.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
index cb1bf53..7854343 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  half4x4 const t = transpose((*tint_module_vars.u)[2].m);
-  half const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  half const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  half4x4 const t = transpose((*tint_module_vars.u)[2u].m);
+  half const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  half const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.spvasm
index 1019aae..b5d68f8 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_builtin.wgsl.expected.spvasm
@@ -1,13 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
-         %37 = OpExtInstImport "GLSL.std.450"
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,32 +50,30 @@
          %13 = OpTypeFunction %void
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
-     %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
+     %uint_1 = OpConstant %uint 1
      %uint_3 = OpConstant %uint 3
  %mat4v4half = OpTypeMatrix %v4half 4
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %15 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %20 = OpLoad %v4half %15 None
-         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %23 = OpLoad %v4half %21 None
-         %24 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %26 = OpLoad %v4half %24 None
-         %27 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_4
-         %28 = OpLoad %v4half %27 None
-         %30 = OpCompositeConstruct %mat4v4half %20 %23 %26 %28
-          %t = OpTranspose %mat4v4half %30
-         %32 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %34 = OpLoad %v4half %32 None
-         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
-          %l = OpExtInst %half %37 Length %35
-         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %39 = OpLoad %v4half %38 None
-         %40 = OpVectorShuffle %v4half %39 %39 1 3 0 2
-         %41 = OpCompositeExtract %half %40 0
-          %a = OpExtInst %half %37 FAbs %41
+         %21 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %22 = OpLoad %v4half %21 None
+         %23 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %25 = OpLoad %v4half %23 None
+         %26 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_4
+         %27 = OpLoad %v4half %26 None
+         %29 = OpCompositeConstruct %mat4v4half %20 %22 %25 %27
+          %t = OpTranspose %mat4v4half %29
+         %31 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %32 = OpLoad %v4half %31 None
+         %33 = OpVectorShuffle %v4half %32 %32 1 3 0 2
+          %l = OpExtInst %half %35 Length %33
+         %36 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %37 = OpLoad %v4half %36 None
+         %38 = OpVectorShuffle %v4half %37 %37 1 3 0 2
+         %39 = OpCompositeExtract %half %38 0
+          %a = OpExtInst %half %35 FAbs %39
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.glsl
index 02df3aa..7c74910 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.glsl
@@ -76,8 +76,8 @@
     }
   }
   a(v_3);
-  b(tint_convert_S(v_1.inner[2]));
-  c(f16mat4(v_1.inner[2].m_col0, v_1.inner[2].m_col1, v_1.inner[2].m_col2, v_1.inner[2].m_col3));
-  d(v_1.inner[0].m_col1.ywxz);
-  e(v_1.inner[0].m_col1.ywxz[0u]);
+  b(tint_convert_S(v_1.inner[2u]));
+  c(f16mat4(v_1.inner[2u].m_col0, v_1.inner[2u].m_col1, v_1.inner[2u].m_col2, v_1.inner[2u].m_col3));
+  d(v_1.inner[0u].m_col1.ywxz);
+  e(v_1.inner[0u].m_col1.ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.ir.msl
index 15d1ca4..211a7cb 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.spvasm
index 787b9e7..ba0d549 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 108
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -84,12 +84,10 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_3 = OpConstant %uint 3
-      %int_0 = OpConstant %int 0
-         %98 = OpTypeFunction %S %S_std140
+         %96 = OpTypeFunction %S %S_std140
           %a = OpFunction %void None %17
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %18 = OpLabel
@@ -148,41 +146,41 @@
          %51 = OpLabel
          %66 = OpLoad %_arr_S_uint_4 %44 None
          %67 = OpFunctionCall %void %a %66
-         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %68 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %71 = OpLoad %S_std140 %68 None
          %72 = OpFunctionCall %S %tint_convert_S %71
          %73 = OpFunctionCall %void %b %72
-         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
+         %74 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
          %76 = OpLoad %v4half %74 None
-         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %79 = OpLoad %v4half %77 None
-         %80 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %82 = OpLoad %v4half %80 None
-         %83 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_4
-         %84 = OpLoad %v4half %83 None
-         %85 = OpCompositeConstruct %mat4v4half %76 %79 %82 %84
-         %86 = OpFunctionCall %void %c %85
-         %87 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %89 = OpLoad %v4half %87 None
-         %90 = OpVectorShuffle %v4half %89 %89 1 3 0 2
-         %91 = OpFunctionCall %void %d %90
-         %92 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v4half %92 None
-         %94 = OpVectorShuffle %v4half %93 %93 1 3 0 2
-         %95 = OpCompositeExtract %half %94 0
-         %96 = OpFunctionCall %void %e %95
+         %77 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %78 = OpLoad %v4half %77 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %81 = OpLoad %v4half %79 None
+         %82 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_4
+         %83 = OpLoad %v4half %82 None
+         %84 = OpCompositeConstruct %mat4v4half %76 %78 %81 %83
+         %85 = OpFunctionCall %void %c %84
+         %86 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %87 = OpLoad %v4half %86 None
+         %88 = OpVectorShuffle %v4half %87 %87 1 3 0 2
+         %89 = OpFunctionCall %void %d %88
+         %90 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %91 = OpLoad %v4half %90 None
+         %92 = OpVectorShuffle %v4half %91 %91 1 3 0 2
+         %93 = OpCompositeExtract %half %92 0
+         %94 = OpFunctionCall %void %e %93
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %98
+%tint_convert_S = OpFunction %S None %96
  %tint_input = OpFunctionParameter %S_std140
-         %99 = OpLabel
-        %100 = OpCompositeExtract %int %tint_input 0
-        %101 = OpCompositeExtract %v4half %tint_input 1
-        %102 = OpCompositeExtract %v4half %tint_input 2
-        %103 = OpCompositeExtract %v4half %tint_input 3
-        %104 = OpCompositeExtract %v4half %tint_input 4
-        %105 = OpCompositeConstruct %mat4v4half %101 %102 %103 %104
-        %106 = OpCompositeExtract %int %tint_input 5
-        %107 = OpCompositeConstruct %S %100 %105 %106
-               OpReturnValue %107
+         %97 = OpLabel
+         %98 = OpCompositeExtract %int %tint_input 0
+         %99 = OpCompositeExtract %v4half %tint_input 1
+        %100 = OpCompositeExtract %v4half %tint_input 2
+        %101 = OpCompositeExtract %v4half %tint_input 3
+        %102 = OpCompositeExtract %v4half %tint_input 4
+        %103 = OpCompositeConstruct %mat4v4half %99 %100 %101 %102
+        %104 = OpCompositeExtract %int %tint_input 5
+        %105 = OpCompositeConstruct %S %98 %103 %104
+               OpReturnValue %105
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.glsl
index c8a3e6c..f23770c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.glsl
@@ -67,7 +67,7 @@
     }
   }
   p = v_2;
-  p[1] = tint_convert_S(v.inner[2]);
-  p[3].m = f16mat4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  p[1].m[0] = v.inner[0].m_col1.ywxz;
+  p[1u] = tint_convert_S(v.inner[2u]);
+  p[3u].m = f16mat4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  p[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 40b6938..f896909 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -67,8 +67,8 @@
   S v_21[4] = v_16(0u);
   p = v_21;
   S v_22 = v_12(256u);
-  p[int(1)] = v_22;
-  p[int(3)].m = v_4(264u);
-  p[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  p[1u] = v_22;
+  p[3u].m = v_4(264u);
+  p[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.msl
index 2610d2b..95e12d3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.spvasm
index 88aeb84..674af17 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 89
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -72,17 +72,13 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v4half = OpTypePointer Private %mat4v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v4half = OpTypePointer Private %mat4v4half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-      %int_0 = OpConstant %int 0
-         %79 = OpTypeFunction %S %S_std140
+         %75 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -116,39 +112,39 @@
          %33 = OpLabel
          %48 = OpLoad %_arr_S_uint_4 %27 None
                OpStore %p %48 None
-         %49 = OpAccessChain %_ptr_Private_S %p %int_1
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %55 = OpLoad %S_std140 %52 None
-         %56 = OpFunctionCall %S %tint_convert_S %55
-               OpStore %49 %56 None
-         %57 = OpAccessChain %_ptr_Private_mat4v4half %p %int_3 %uint_1
-         %60 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %62 = OpLoad %v4half %60 None
-         %63 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %65 = OpLoad %v4half %63 None
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %68 = OpLoad %v4half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_4
-         %70 = OpLoad %v4half %69 None
-         %71 = OpCompositeConstruct %mat4v4half %62 %65 %68 %70
-               OpStore %57 %71 None
-         %72 = OpAccessChain %_ptr_Private_v4half %p %int_1 %uint_1 %int_0
-         %75 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %76 = OpLoad %v4half %75 None
-         %77 = OpVectorShuffle %v4half %76 %76 1 3 0 2
-               OpStore %72 %77 None
+         %49 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %51 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %54 = OpLoad %S_std140 %51 None
+         %55 = OpFunctionCall %S %tint_convert_S %54
+               OpStore %49 %55 None
+         %56 = OpAccessChain %_ptr_Private_mat4v4half %p %uint_3 %uint_1
+         %59 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %61 = OpLoad %v4half %59 None
+         %62 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %63 = OpLoad %v4half %62 None
+         %64 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %65 = OpLoad %v4half %64 None
+         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_4
+         %67 = OpLoad %v4half %66 None
+         %68 = OpCompositeConstruct %mat4v4half %61 %63 %65 %67
+               OpStore %56 %68 None
+         %69 = OpAccessChain %_ptr_Private_v4half %p %uint_1 %uint_1 %uint_0
+         %71 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %72 = OpLoad %v4half %71 None
+         %73 = OpVectorShuffle %v4half %72 %72 1 3 0 2
+               OpStore %69 %73 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %79
+%tint_convert_S = OpFunction %S None %75
  %tint_input = OpFunctionParameter %S_std140
-         %80 = OpLabel
-         %81 = OpCompositeExtract %int %tint_input 0
-         %82 = OpCompositeExtract %v4half %tint_input 1
-         %83 = OpCompositeExtract %v4half %tint_input 2
-         %84 = OpCompositeExtract %v4half %tint_input 3
-         %85 = OpCompositeExtract %v4half %tint_input 4
-         %86 = OpCompositeConstruct %mat4v4half %82 %83 %84 %85
-         %87 = OpCompositeExtract %int %tint_input 5
-         %88 = OpCompositeConstruct %S %81 %86 %87
-               OpReturnValue %88
+         %76 = OpLabel
+         %77 = OpCompositeExtract %int %tint_input 0
+         %78 = OpCompositeExtract %v4half %tint_input 1
+         %79 = OpCompositeExtract %v4half %tint_input 2
+         %80 = OpCompositeExtract %v4half %tint_input 3
+         %81 = OpCompositeExtract %v4half %tint_input 4
+         %82 = OpCompositeConstruct %mat4v4half %78 %79 %80 %81
+         %83 = OpCompositeExtract %int %tint_input 5
+         %84 = OpCompositeConstruct %S %77 %82 %83
+               OpReturnValue %84
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.glsl
index bcc8f78..9ffd46f 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.glsl
@@ -114,8 +114,8 @@
     }
   }
   tint_store_and_preserve_padding(v_5);
-  S v_8 = tint_convert_S(v.inner[2]);
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_8);
-  v_1.inner[3].m = f16mat4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  v_1.inner[1].m[0] = v.inner[0].m_col1.ywxz;
+  S v_8 = tint_convert_S(v.inner[2u]);
+  tint_store_and_preserve_padding_1(uint[1](1u), v_8);
+  v_1.inner[3u].m = f16mat4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  v_1.inner[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.ir.msl
index a867e72..4126b7d 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0044 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.msl
index 4d16bf6..7e69e2b 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.spvasm
index 4e47fc6..29ac4e0 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 125
+; Bound: 120
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -85,20 +85,16 @@
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
-     %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-      %int_0 = OpConstant %int 0
-         %85 = OpTypeFunction %void %_arr_S_uint_4
-        %104 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %80 = OpTypeFunction %void %_arr_S_uint_4
+         %99 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-        %115 = OpTypeFunction %S %S_std140
+        %110 = OpTypeFunction %S %S_std140
           %f = OpFunction %void None %19
          %20 = OpLabel
          %25 = OpVariable %_ptr_Function__arr_S_std140_uint_4 Function
@@ -132,86 +128,85 @@
          %34 = OpLabel
          %49 = OpLoad %_arr_S_uint_4 %27 None
          %50 = OpFunctionCall %void %tint_store_and_preserve_padding %49
-         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
+         %52 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
          %55 = OpLoad %S_std140 %52 None
          %56 = OpFunctionCall %S %tint_convert_S %55
-         %57 = OpBitcast %uint %int_1
-         %60 = OpCompositeConstruct %_arr_uint_uint_1 %57
-         %61 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %60 %56
-         %63 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %11 %uint_0 %int_3 %uint_1
-         %66 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %68 = OpLoad %v4half %66 None
-         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
-         %71 = OpLoad %v4half %69 None
-         %72 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %74 = OpLoad %v4half %72 None
-         %75 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_4
-         %76 = OpLoad %v4half %75 None
-         %77 = OpCompositeConstruct %mat4v4half %68 %71 %74 %76
-               OpStore %63 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %int_1 %uint_1 %int_0
-         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %82 = OpLoad %v4half %81 None
-         %83 = OpVectorShuffle %v4half %82 %82 1 3 0 2
-               OpStore %78 %83 None
+         %58 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %59 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %58 %56
+         %61 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %11 %uint_0 %uint_3 %uint_1
+         %64 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %66 = OpLoad %v4half %64 None
+         %67 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %68 = OpLoad %v4half %67 None
+         %69 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
+         %70 = OpLoad %v4half %69 None
+         %71 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_4
+         %72 = OpLoad %v4half %71 None
+         %73 = OpCompositeConstruct %mat4v4half %66 %68 %70 %72
+               OpStore %61 %73 None
+         %74 = OpAccessChain %_ptr_StorageBuffer_v4half %11 %uint_0 %uint_1 %uint_1 %uint_0
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %77 = OpLoad %v4half %76 None
+         %78 = OpVectorShuffle %v4half %77 %77 1 3 0 2
+               OpStore %74 %78 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %85
+%tint_store_and_preserve_padding = OpFunction %void None %80
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %81 = OpLabel
+         %82 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %82 %value_param
+               OpBranch %83
+         %83 = OpLabel
+               OpBranch %86
          %86 = OpLabel
-         %87 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %87 %value_param
-               OpBranch %88
-         %88 = OpLabel
-               OpBranch %91
-         %91 = OpLabel
-         %93 = OpPhi %uint %uint_0 %88 %94 %90
-               OpLoopMerge %92 %90 None
-               OpBranch %89
-         %89 = OpLabel
-         %95 = OpUGreaterThanEqual %bool %93 %uint_4
-               OpSelectionMerge %96 None
-               OpBranchConditional %95 %97 %96
-         %97 = OpLabel
-               OpBranch %92
-         %96 = OpLabel
-         %98 = OpAccessChain %_ptr_Function_S %87 %93
-         %99 = OpLoad %S %98 None
-        %100 = OpCompositeConstruct %_arr_uint_uint_1 %93
-        %101 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %100 %99
-               OpBranch %90
-         %90 = OpLabel
-         %94 = OpIAdd %uint %93 %uint_1
-               OpBranch %91
+         %88 = OpPhi %uint %uint_0 %83 %89 %85
+               OpLoopMerge %87 %85 None
+               OpBranch %84
+         %84 = OpLabel
+         %90 = OpUGreaterThanEqual %bool %88 %uint_4
+               OpSelectionMerge %91 None
+               OpBranchConditional %90 %92 %91
          %92 = OpLabel
+               OpBranch %87
+         %91 = OpLabel
+         %93 = OpAccessChain %_ptr_Function_S %82 %88
+         %94 = OpLoad %S %93 None
+         %95 = OpCompositeConstruct %_arr_uint_uint_1 %88
+         %96 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %95 %94
+               OpBranch %85
+         %85 = OpLabel
+         %89 = OpIAdd %uint %88 %uint_1
+               OpBranch %86
+         %87 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %104
+%tint_store_and_preserve_padding_0 = OpFunction %void None %99
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-        %105 = OpLabel
-        %106 = OpCompositeExtract %uint %target_indices 0
-        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_0
-        %109 = OpCompositeExtract %int %value_param_0 0
-               OpStore %107 %109 None
-        %110 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %11 %uint_0 %106 %uint_1
-        %111 = OpCompositeExtract %mat4v4half %value_param_0 1
-               OpStore %110 %111 None
-        %112 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %106 %uint_2
-        %113 = OpCompositeExtract %int %value_param_0 2
-               OpStore %112 %113 None
+        %100 = OpLabel
+        %101 = OpCompositeExtract %uint %target_indices 0
+        %102 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_0
+        %104 = OpCompositeExtract %int %value_param_0 0
+               OpStore %102 %104 None
+        %105 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %11 %uint_0 %101 %uint_1
+        %106 = OpCompositeExtract %mat4v4half %value_param_0 1
+               OpStore %105 %106 None
+        %107 = OpAccessChain %_ptr_StorageBuffer_int %11 %uint_0 %101 %uint_2
+        %108 = OpCompositeExtract %int %value_param_0 2
+               OpStore %107 %108 None
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %115
+%tint_convert_S = OpFunction %S None %110
  %tint_input = OpFunctionParameter %S_std140
-        %116 = OpLabel
-        %117 = OpCompositeExtract %int %tint_input 0
-        %118 = OpCompositeExtract %v4half %tint_input 1
-        %119 = OpCompositeExtract %v4half %tint_input 2
-        %120 = OpCompositeExtract %v4half %tint_input 3
-        %121 = OpCompositeExtract %v4half %tint_input 4
-        %122 = OpCompositeConstruct %mat4v4half %118 %119 %120 %121
-        %123 = OpCompositeExtract %int %tint_input 5
-        %124 = OpCompositeConstruct %S %117 %122 %123
-               OpReturnValue %124
+        %111 = OpLabel
+        %112 = OpCompositeExtract %int %tint_input 0
+        %113 = OpCompositeExtract %v4half %tint_input 1
+        %114 = OpCompositeExtract %v4half %tint_input 2
+        %115 = OpCompositeExtract %v4half %tint_input 3
+        %116 = OpCompositeExtract %v4half %tint_input 4
+        %117 = OpCompositeConstruct %mat4v4half %113 %114 %115 %116
+        %118 = OpCompositeExtract %int %tint_input 5
+        %119 = OpCompositeConstruct %S %112 %117 %118
+               OpReturnValue %119
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.glsl
index 0e535af..89f0ca2 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.glsl
@@ -82,9 +82,9 @@
     }
   }
   w = v_4;
-  w[1] = tint_convert_S(v.inner[2]);
-  w[3].m = f16mat4(v.inner[2].m_col0, v.inner[2].m_col1, v.inner[2].m_col2, v.inner[2].m_col3);
-  w[1].m[0] = v.inner[0].m_col1.ywxz;
+  w[1u] = tint_convert_S(v.inner[2u]);
+  w[3u].m = f16mat4(v.inner[2u].m_col0, v.inner[2u].m_col1, v.inner[2u].m_col2, v.inner[2u].m_col3);
+  w[1u].m[0u] = v.inner[0u].m_col1.ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 43b7684..56a6263 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -87,9 +87,9 @@
   S v_24[4] = v_16(0u);
   w = v_24;
   S v_25 = v_12(256u);
-  w[int(1)] = v_25;
-  w[int(3)].m = v_4(264u);
-  w[int(1)].m[int(0)] = tint_bitcast_to_f16(u[1u].xy).ywxz;
+  w[1u] = v_25;
+  w[3u].m = v_4(264u);
+  w[1u].m[0u] = tint_bitcast_to_f16(u[1u].xy).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
index 47f3faf..d52d4f1 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.msl
index 53cbdd9..21fda59 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 4> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
index 82b5d41..ba82c93 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 111
+; Bound: 107
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -81,17 +81,13 @@
          %49 = OpConstantNull %_arr_S_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
 %_ptr_Function_S_std140 = OpTypePointer Function %S_std140
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S_std140 = OpTypePointer Uniform %S_std140
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v4half = OpTypePointer Workgroup %mat4v4half
-      %int_3 = OpConstant %int 3
-%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-      %int_0 = OpConstant %int 0
-         %96 = OpTypeFunction %void
-        %101 = OpTypeFunction %S %S_std140
+         %92 = OpTypeFunction %void
+         %97 = OpTypeFunction %S %S_std140
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -148,45 +144,45 @@
          %54 = OpLabel
          %67 = OpLoad %_arr_S_uint_4 %47 None
                OpStore %w %67 None
-         %68 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %70 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %int_2
-         %73 = OpLoad %S_std140 %70 None
-         %74 = OpFunctionCall %S %tint_convert_S %73
-               OpStore %68 %74 None
-         %75 = OpAccessChain %_ptr_Workgroup_mat4v4half %w %int_3 %uint_1
-         %78 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_1
-         %80 = OpLoad %v4half %78 None
-         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_2
+         %68 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %69 = OpAccessChain %_ptr_Uniform_S_std140 %1 %uint_0 %uint_2
+         %71 = OpLoad %S_std140 %69 None
+         %72 = OpFunctionCall %S %tint_convert_S %71
+               OpStore %68 %72 None
+         %73 = OpAccessChain %_ptr_Workgroup_mat4v4half %w %uint_3 %uint_1
+         %76 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_1
+         %78 = OpLoad %v4half %76 None
+         %79 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_2
+         %80 = OpLoad %v4half %79 None
+         %81 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_3
          %82 = OpLoad %v4half %81 None
-         %83 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_3
-         %85 = OpLoad %v4half %83 None
-         %86 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_2 %uint_4
-         %87 = OpLoad %v4half %86 None
-         %88 = OpCompositeConstruct %mat4v4half %80 %82 %85 %87
-               OpStore %75 %88 None
-         %89 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1 %uint_1 %int_0
-         %92 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %int_0 %uint_2
-         %93 = OpLoad %v4half %92 None
-         %94 = OpVectorShuffle %v4half %93 %93 1 3 0 2
-               OpStore %89 %94 None
+         %83 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_2 %uint_4
+         %84 = OpLoad %v4half %83 None
+         %85 = OpCompositeConstruct %mat4v4half %78 %80 %82 %84
+               OpStore %73 %85 None
+         %86 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1 %uint_1 %uint_0
+         %88 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0 %uint_0 %uint_2
+         %89 = OpLoad %v4half %88 None
+         %90 = OpVectorShuffle %v4half %89 %89 1 3 0 2
+               OpStore %86 %90 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %96
-         %97 = OpLabel
-         %98 = OpLoad %uint %f_local_invocation_index_Input None
-         %99 = OpFunctionCall %void %f_inner %98
+          %f = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %uint %f_local_invocation_index_Input None
+         %95 = OpFunctionCall %void %f_inner %94
                OpReturn
                OpFunctionEnd
-%tint_convert_S = OpFunction %S None %101
+%tint_convert_S = OpFunction %S None %97
  %tint_input = OpFunctionParameter %S_std140
-        %102 = OpLabel
-        %103 = OpCompositeExtract %int %tint_input 0
-        %104 = OpCompositeExtract %v4half %tint_input 1
-        %105 = OpCompositeExtract %v4half %tint_input 2
-        %106 = OpCompositeExtract %v4half %tint_input 3
-        %107 = OpCompositeExtract %v4half %tint_input 4
-        %108 = OpCompositeConstruct %mat4v4half %104 %105 %106 %107
-        %109 = OpCompositeExtract %int %tint_input 5
-        %110 = OpCompositeConstruct %S %103 %108 %109
-               OpReturnValue %110
+         %98 = OpLabel
+         %99 = OpCompositeExtract %int %tint_input 0
+        %100 = OpCompositeExtract %v4half %tint_input 1
+        %101 = OpCompositeExtract %v4half %tint_input 2
+        %102 = OpCompositeExtract %v4half %tint_input 3
+        %103 = OpCompositeExtract %v4half %tint_input 4
+        %104 = OpCompositeConstruct %mat4v4half %100 %101 %102 %103
+        %105 = OpCompositeExtract %int %tint_input 5
+        %106 = OpCompositeConstruct %S %99 %104 %105
+               OpReturnValue %106
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 262dcc2..457baaa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -61,17 +61,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_4 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 262dcc2..457baaa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -61,17 +61,17 @@
   int p_a_i_a_i_save = i();
   int p_a_i_a_i_m_i_save = i();
   Outer l_a[4] = a_load(0u);
-  Outer l_a_i = a_load_1((256u * uint(p_a_i_save)));
-  Inner l_a_i_a[4] = a_load_2((256u * uint(p_a_i_save)));
-  Inner l_a_i_a_i = a_load_3(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  float4x4 l_a_i_a_i_m = a_load_4(((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))));
-  const uint scalar_offset_4 = ((((256u * uint(p_a_i_save)) + (64u * uint(p_a_i_a_i_save))) + (16u * uint(p_a_i_a_i_m_i_save)))) / 4;
+  Outer l_a_i = a_load_1((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a[4] = a_load_2((256u * min(uint(p_a_i_save), 3u)));
+  Inner l_a_i_a_i = a_load_3(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  float4x4 l_a_i_a_i_m = a_load_4(((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))));
+  const uint scalar_offset_4 = ((((256u * min(uint(p_a_i_save), 3u)) + (64u * min(uint(p_a_i_a_i_save), 3u))) + (16u * min(uint(p_a_i_a_i_m_i_save), 3u)))) / 4;
   float4 l_a_i_a_i_m_i = asfloat(a[scalar_offset_4 / 4]);
   int tint_symbol = p_a_i_save;
   int tint_symbol_1 = p_a_i_a_i_save;
   int tint_symbol_2 = p_a_i_a_i_m_i_save;
   int tint_symbol_3 = i();
-  const uint scalar_offset_5 = (((((256u * uint(tint_symbol)) + (64u * uint(tint_symbol_1))) + (16u * uint(tint_symbol_2))) + (4u * uint(tint_symbol_3)))) / 4;
+  const uint scalar_offset_5 = (((((256u * min(uint(tint_symbol), 3u)) + (64u * min(uint(tint_symbol_1), 3u))) + (16u * min(uint(tint_symbol_2), 3u))) + (4u * min(uint(tint_symbol_3), 3u)))) / 4;
   float l_a_i_a_i_m_i_i = asfloat(a[scalar_offset_5 / 4][scalar_offset_5 % 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 9daa46d..56303fa 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -20,14 +20,14 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
-  int v_2 = i();
-  int v_3 = i();
+  uint v_1 = min(uint(i()), 3u);
+  uint v_2 = min(uint(i()), 3u);
+  uint v_3 = min(uint(i()), 3u);
   Outer l_a[4] = v.inner;
   Outer l_a_i = v.inner[v_1];
   Inner l_a_i_a[4] = v.inner[v_1].a;
   Inner l_a_i_a_i = v.inner[v_1].a[v_2];
   mat4 l_a_i_a_i_m = v.inner[v_1].a[v_2].m;
   vec4 l_a_i_a_i_m_i = v.inner[v_1].a[v_2].m[v_3];
-  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][i()];
+  float l_a_i_a_i_m_i_i = v.inner[v_1].a[v_2].m[v_3][min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 97e2183..b8553f4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float4x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 97e2183..b8553f4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -79,16 +79,16 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_16 = (256u * uint(i()));
-  uint v_17 = (64u * uint(i()));
-  uint v_18 = (16u * uint(i()));
+  uint v_16 = (256u * uint(min(uint(i()), 3u)));
+  uint v_17 = (64u * uint(min(uint(i()), 3u)));
+  uint v_18 = (16u * uint(min(uint(i()), 3u)));
   Outer l_a[4] = v_11(0u);
   Outer l_a_i = v_8(v_16);
   Inner l_a_i_a[4] = v_3(v_16);
   Inner l_a_i_a_i = v_1((v_16 + v_17));
   float4x4 l_a_i_a_i_m = v((v_16 + v_17));
   float4 l_a_i_a_i_m_i = asfloat(a[(((v_16 + v_17) + v_18) / 16u)]);
-  uint v_19 = (((v_16 + v_17) + v_18) + (uint(i()) * 4u));
+  uint v_19 = (((v_16 + v_17) + v_18) + (uint(min(uint(i()), 3u)) * 4u));
   float l_a_i_a_i_m_i_i = asfloat(a[(v_19 / 16u)][((v_19 % 16u) / 4u)]);
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 5ac5fca..aab1d45 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -35,16 +35,16 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a, .counter=(&counter)};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_i = (&(*p_a)[i(tint_module_vars)]);
+  const constant Outer* const p_a_i = (&(*p_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant tint_array<Inner, 4>* const p_a_i_a = (&(*p_a_i).a);
-  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[i(tint_module_vars)]);
+  const constant Inner* const p_a_i_a_i = (&(*p_a_i_a)[min(uint(i(tint_module_vars)), 3u)]);
   const constant float4x4* const p_a_i_a_i_m = (&(*p_a_i_a_i).m);
-  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[i(tint_module_vars)]);
+  const constant float4* const p_a_i_a_i_m_i = (&(*p_a_i_a_i_m)[min(uint(i(tint_module_vars)), 3u)]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_i = (*p_a_i);
   tint_array<Inner, 4> const l_a_i_a = (*p_a_i_a);
   Inner const l_a_i_a_i = (*p_a_i_a_i);
   float4x4 const l_a_i_a_i_m = (*p_a_i_a_i_m);
   float4 const l_a_i_a_i_m_i = (*p_a_i_a_i_m_i);
-  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[i(tint_module_vars)];
+  float const l_a_i_a_i_m_i_i = (*p_a_i_a_i_m_i)[min(uint(i(tint_module_vars)), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index c191459..826270c 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -35,11 +35,11 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_a_i_save = tint_symbol;
+  uint const p_a_i_save = min(uint(tint_symbol), 3u);
   int const tint_symbol_1 = i(&(tint_private_vars));
-  int const p_a_i_a_i_save = tint_symbol_1;
+  uint const p_a_i_a_i_save = min(uint(tint_symbol_1), 3u);
   int const tint_symbol_2 = i(&(tint_private_vars));
-  int const p_a_i_a_i_m_i_save = tint_symbol_2;
+  uint const p_a_i_a_i_m_i_save = min(uint(tint_symbol_2), 3u);
   tint_array<Outer, 4> const l_a = *(tint_symbol_4);
   Outer const l_a_i = (*(tint_symbol_4))[p_a_i_save];
   tint_array<Inner, 4> const l_a_i_a = (*(tint_symbol_4))[p_a_i_save].a;
@@ -47,7 +47,7 @@
   float4x4 const l_a_i_a_i_m = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m;
   float4 const l_a_i_a_i_m_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save];
   int const tint_symbol_3 = i(&(tint_private_vars));
-  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][tint_symbol_3];
+  float const l_a_i_a_i_m_i_i = (*(tint_symbol_4))[p_a_i_save].a[p_a_i_a_i_save].m[p_a_i_a_i_m_i_save][min(uint(tint_symbol_3), 3u)];
   return;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 9abc237..90a5cff 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,6 +63,7 @@
          %26 = OpTypeFunction %void
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
@@ -80,21 +82,29 @@
          %27 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
          %31 = OpFunctionCall %int %i
-      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %31
+         %32 = OpBitcast %uint %31
+         %33 = OpExtInst %uint %34 UMin %32 %uint_3
+      %p_a_i = OpAccessChain %_ptr_Uniform_Outer %p_a %33
     %p_a_i_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_i %uint_0
-         %36 = OpFunctionCall %int %i
-  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %36
+         %40 = OpFunctionCall %int %i
+         %41 = OpBitcast %uint %40
+         %42 = OpExtInst %uint %34 UMin %41 %uint_3
+  %p_a_i_a_i = OpAccessChain %_ptr_Uniform_Inner %p_a_i_a %42
 %p_a_i_a_i_m = OpAccessChain %_ptr_Uniform_mat4v4float %p_a_i_a_i %uint_0
-         %41 = OpFunctionCall %int %i
-%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %41
+         %47 = OpFunctionCall %int %i
+         %48 = OpBitcast %uint %47
+         %49 = OpExtInst %uint %34 UMin %48 %uint_3
+%p_a_i_a_i_m_i = OpAccessChain %_ptr_Uniform_v4float %p_a_i_a_i_m %49
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_i = OpLoad %Outer %p_a_i None
     %l_a_i_a = OpLoad %_arr_Inner_uint_4 %p_a_i_a None
   %l_a_i_a_i = OpLoad %Inner %p_a_i_a_i None
 %l_a_i_a_i_m = OpLoad %mat4v4float %p_a_i_a_i_m None
 %l_a_i_a_i_m_i = OpLoad %v4float %p_a_i_a_i_m_i None
-         %50 = OpFunctionCall %int %i
-         %51 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %50
-%l_a_i_a_i_m_i_i = OpLoad %float %51 None
+         %58 = OpFunctionCall %int %i
+         %59 = OpBitcast %uint %58
+         %60 = OpExtInst %uint %34 UMin %59 %uint_3
+         %61 = OpAccessChain %_ptr_Uniform_float %p_a_i_a_i_m_i %60
+%l_a_i_a_i_m_i_i = OpLoad %float %61 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
index ea6b52b..919ed41 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -16,10 +16,10 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   Outer l_a[4] = v.inner;
-  Outer l_a_3 = v.inner[3];
-  Inner l_a_3_a[4] = v.inner[3].a;
-  Inner l_a_3_a_2 = v.inner[3].a[2];
-  mat4 l_a_3_a_2_m = v.inner[3].a[2].m;
-  vec4 l_a_3_a_2_m_1 = v.inner[3].a[2].m[1];
-  float l_a_3_a_2_m_1_0 = v.inner[3].a[2].m[1].x;
+  Outer l_a_3 = v.inner[3u];
+  Inner l_a_3_a[4] = v.inner[3u].a;
+  Inner l_a_3_a_2 = v.inner[3u].a[2u];
+  mat4 l_a_3_a_2_m = v.inner[3u].a[2u].m;
+  vec4 l_a_3_a_2_m_1 = v.inner[3u].a[2u].m[1u];
+  float l_a_3_a_2_m_1_0 = v.inner[3u].a[2u].m[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 14605b6..3919448 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -28,16 +28,16 @@
 kernel void f(const constant tint_array<Outer, 4>* a [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.a=a};
   const constant tint_array<Outer, 4>* const p_a = tint_module_vars.a;
-  const constant Outer* const p_a_3 = (&(*p_a)[3]);
+  const constant Outer* const p_a_3 = (&(*p_a)[3u]);
   const constant tint_array<Inner, 4>* const p_a_3_a = (&(*p_a_3).a);
-  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2]);
+  const constant Inner* const p_a_3_a_2 = (&(*p_a_3_a)[2u]);
   const constant float4x4* const p_a_3_a_2_m = (&(*p_a_3_a_2).m);
-  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1]);
+  const constant float4* const p_a_3_a_2_m_1 = (&(*p_a_3_a_2_m)[1u]);
   tint_array<Outer, 4> const l_a = (*p_a);
   Outer const l_a_3 = (*p_a_3);
   tint_array<Inner, 4> const l_a_3_a = (*p_a_3_a);
   Inner const l_a_3_a_2 = (*p_a_3_a_2);
   float4x4 const l_a_3_a_2_m = (*p_a_3_a_2_m);
   float4 const l_a_3_a_2_m_1 = (*p_a_3_a_2_m_1);
-  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0];
+  float const l_a_3_a_2_m_1_0 = (*p_a_3_a_2_m_1)[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index ed14183..f4a5c86 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,31 +55,29 @@
 %_ptr_Uniform__arr_Outer_uint_4 = OpTypePointer Uniform %_arr_Outer_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_Outer = OpTypePointer Uniform %Outer
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform__arr_Inner_uint_4 = OpTypePointer Uniform %_arr_Inner_uint_4
 %_ptr_Uniform_Inner = OpTypePointer Uniform %Inner
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-      %int_0 = OpConstant %int 0
           %f = OpFunction %void None %15
          %16 = OpLabel
         %p_a = OpAccessChain %_ptr_Uniform__arr_Outer_uint_4 %1 %uint_0
-      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %int_3
+      %p_a_3 = OpAccessChain %_ptr_Uniform_Outer %p_a %uint_3
     %p_a_3_a = OpAccessChain %_ptr_Uniform__arr_Inner_uint_4 %p_a_3 %uint_0
-  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %int_2
+  %p_a_3_a_2 = OpAccessChain %_ptr_Uniform_Inner %p_a_3_a %uint_2
 %p_a_3_a_2_m = OpAccessChain %_ptr_Uniform_mat4v4float %p_a_3_a_2 %uint_0
-%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %int_1
+%p_a_3_a_2_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_a_3_a_2_m %uint_1
         %l_a = OpLoad %_arr_Outer_uint_4 %p_a None
       %l_a_3 = OpLoad %Outer %p_a_3 None
     %l_a_3_a = OpLoad %_arr_Inner_uint_4 %p_a_3_a None
   %l_a_3_a_2 = OpLoad %Inner %p_a_3_a_2 None
 %l_a_3_a_2_m = OpLoad %mat4v4float %p_a_3_a_2_m None
 %l_a_3_a_2_m_1 = OpLoad %v4float %p_a_3_a_2_m_1 None
-         %40 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %int_0
-%l_a_3_a_2_m_1_0 = OpLoad %float %40 None
+         %39 = OpAccessChain %_ptr_Uniform_float %p_a_3_a_2_m_1 %uint_0
+%l_a_3_a_2_m_1_0 = OpLoad %float %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.glsl
index 3369166..9584788 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.glsl
@@ -43,7 +43,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  mat4 t = transpose(v.inner[2].m);
-  float l = length(v.inner[0].m[1].ywxz);
-  float a = abs(v.inner[0].m[1].ywxz[0u]);
+  mat4 t = transpose(v.inner[2u].m);
+  float l = length(v.inner[0u].m[1u].ywxz);
+  float a = abs(v.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
index fb7b896..a638f96 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
-  float4x4 const t = transpose((*tint_module_vars.u)[2].m);
-  float const l = length((*tint_module_vars.u)[0].m[1].ywxz);
-  float const a = abs((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  float4x4 const t = transpose((*tint_module_vars.u)[2u].m);
+  float const l = length((*tint_module_vars.u)[0u].m[1u].ywxz);
+  float const a = abs((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.spvasm
index 97c6e49..5c72074 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
-         %30 = OpExtInstImport "GLSL.std.450"
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -44,24 +44,22 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
      %uint_0 = OpConstant %uint 0
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %f = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2 %uint_1
+         %16 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2 %uint_1
          %21 = OpLoad %mat4v4float %16 None
           %t = OpTranspose %mat4v4float %21
-         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %27 = OpLoad %v4float %23 None
-         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
-          %l = OpExtInst %float %30 Length %28
-         %31 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %32 = OpLoad %v4float %31 None
-         %33 = OpVectorShuffle %v4float %32 %32 1 3 0 2
-         %34 = OpCompositeExtract %float %33 0
-          %a = OpExtInst %float %30 FAbs %34
+         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %25 = OpLoad %v4float %23 None
+         %26 = OpVectorShuffle %v4float %25 %25 1 3 0 2
+          %l = OpExtInst %float %28 Length %26
+         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %30 = OpLoad %v4float %29 None
+         %31 = OpVectorShuffle %v4float %30 %30 1 3 0 2
+         %32 = OpCompositeExtract %float %31 0
+          %a = OpExtInst %float %28 FAbs %32
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.glsl
index 986abc4..03d1763 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.glsl
@@ -54,8 +54,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[2]);
-  c(v_1.inner[2].m);
-  d(v_1.inner[0].m[1].ywxz);
-  e(v_1.inner[0].m[1].ywxz[0u]);
+  b(v_1.inner[2u]);
+  c(v_1.inner[2u].m);
+  d(v_1.inner[0u].m[1u].ywxz);
+  e(v_1.inner[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.ir.msl
index 6fbff88..e236ba4 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.ir.msl
@@ -44,8 +44,8 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[2]);
-  c((*tint_module_vars.u)[2].m);
-  d((*tint_module_vars.u)[0].m[1].ywxz);
-  e((*tint_module_vars.u)[0].m[1].ywxz[0u]);
+  b((*tint_module_vars.u)[2u]);
+  c((*tint_module_vars.u)[2u].m);
+  d((*tint_module_vars.u)[0u].m[1u].ywxz);
+  e((*tint_module_vars.u)[0u].m[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.spvasm
index 209a411..ba99705 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -56,12 +56,10 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
      %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
           %a = OpFunction %void None %15
         %a_0 = OpFunctionParameter %_arr_S_uint_4
          %16 = OpLabel
@@ -92,20 +90,20 @@
          %36 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %39 = OpLoad %_arr_S_uint_4 %36 None
          %40 = OpFunctionCall %void %a %39
-         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %41 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %44 = OpLoad %S %41 None
          %45 = OpFunctionCall %void %b %44
-         %46 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2 %uint_1
+         %46 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2 %uint_1
          %49 = OpLoad %mat4v4float %46 None
          %50 = OpFunctionCall %void %c %49
-         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %55 = OpLoad %v4float %51 None
-         %56 = OpVectorShuffle %v4float %55 %55 1 3 0 2
-         %57 = OpFunctionCall %void %d %56
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %59 = OpLoad %v4float %58 None
-         %60 = OpVectorShuffle %v4float %59 %59 1 3 0 2
-         %61 = OpCompositeExtract %float %60 0
-         %62 = OpFunctionCall %void %e %61
+         %51 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %53 = OpLoad %v4float %51 None
+         %54 = OpVectorShuffle %v4float %53 %53 1 3 0 2
+         %55 = OpFunctionCall %void %d %54
+         %56 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %56 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+         %59 = OpCompositeExtract %float %58 0
+         %60 = OpFunctionCall %void %e %59
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.glsl
index ec25492..6bc199e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.glsl
@@ -45,7 +45,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[2];
-  p[3].m = v.inner[2].m;
-  p[1].m[0] = v.inner[0].m[1].ywxz;
+  p[1u] = v.inner[2u];
+  p[3u].m = v.inner[2u].m;
+  p[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 9f77f6f..55fd615 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(384u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(400u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(400u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 9f77f6f..55fd615 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -48,8 +48,8 @@
   S v_10[4] = v_5(0u);
   p = v_10;
   S v_11 = v_1(384u);
-  p[int(1)] = v_11;
-  p[int(3)].m = v(400u);
-  p[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  p[1u] = v_11;
+  p[3u].m = v(400u);
+  p[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.msl
index c712668..4ca6694 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   thread tint_array<S, 4> p = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.p)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.p)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.p)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.p)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.spvasm
index a1d8bfc..bc6a1a3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,33 +45,31 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_1 = OpConstant %int 1
-%_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-%_ptr_Private_mat4v4float = OpTypePointer Private %mat4v4float
-      %int_3 = OpConstant %int 3
      %uint_1 = OpConstant %uint 1
+%_ptr_Uniform_S = OpTypePointer Uniform %S
+     %uint_2 = OpConstant %uint 2
+%_ptr_Private_mat4v4float = OpTypePointer Private %mat4v4float
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_S %p %int_1
-         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %23 = OpAccessChain %_ptr_Private_S %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %29 = OpLoad %S %26 None
                OpStore %23 %29 None
-         %30 = OpAccessChain %_ptr_Private_mat4v4float %p %int_3 %uint_1
-         %34 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2 %uint_1
-         %36 = OpLoad %mat4v4float %34 None
-               OpStore %30 %36 None
-         %37 = OpAccessChain %_ptr_Private_v4float %p %int_1 %uint_1 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %42 = OpLoad %v4float %40 None
-         %43 = OpVectorShuffle %v4float %42 %42 1 3 0 2
-               OpStore %37 %43 None
+         %30 = OpAccessChain %_ptr_Private_mat4v4float %p %uint_3 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2 %uint_1
+         %35 = OpLoad %mat4v4float %33 None
+               OpStore %30 %35 None
+         %36 = OpAccessChain %_ptr_Private_v4float %p %uint_1 %uint_1 %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %40 = OpLoad %v4float %38 None
+         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
+               OpStore %36 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.glsl
index 7fff012..eefc02a 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.glsl
@@ -70,8 +70,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(v.inner);
-  S v_4 = v.inner[2];
-  tint_store_and_preserve_padding_1(uint[1](uint(1)), v_4);
-  v_1.inner[3].m = v.inner[2].m;
-  v_1.inner[1].m[0] = v.inner[0].m[1].ywxz;
+  S v_4 = v.inner[2u];
+  tint_store_and_preserve_padding_1(uint[1](1u), v_4);
+  v_1.inner[3u].m = v.inner[2u].m;
+  v_1.inner[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.ir.msl
index 10fb498..ae9d7f6 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   /* 0x0084 */ tint_array<int8_t, 60> tint_pad_2;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant tint_array<S, 4>* u;
   device tint_array<S, 4>* s;
@@ -38,6 +41,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -54,7 +58,7 @@
 kernel void f(const constant tint_array<S, 4>* u [[buffer(0)]], device tint_array<S, 4>* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   tint_store_and_preserve_padding(tint_module_vars.s, (*tint_module_vars.u));
-  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1]), (*tint_module_vars.u)[2]);
-  (*tint_module_vars.s)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.s)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  tint_store_and_preserve_padding_1((&(*tint_module_vars.s)[1u]), (*tint_module_vars.u)[2u]);
+  (*tint_module_vars.s)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.s)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.msl
index bc5986c..c25d5a8 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -31,7 +34,8 @@
 
 void assign_and_preserve_padding(device tint_array<S, 4>* const dest, tint_array<S, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 3u)]), value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.spvasm
index a2ca286..6632c05 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 83
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -57,87 +57,83 @@
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
+     %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %50 = OpTypeFunction %void %_arr_S_uint_4
+         %47 = OpTypeFunction %void %_arr_S_uint_4
 %_ptr_Function__arr_S_uint_4 = OpTypePointer Function %_arr_S_uint_4
        %bool = OpTypeBool
 %_ptr_Function_S = OpTypePointer Function %S
-         %72 = OpTypeFunction %void %_arr_uint_uint_1 %S
+         %69 = OpTypeFunction %void %_arr_uint_uint_1 %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-     %uint_2 = OpConstant %uint 2
           %f = OpFunction %void None %17
          %18 = OpLabel
          %19 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %22 = OpLoad %_arr_S_uint_4 %19 None
          %23 = OpFunctionCall %void %tint_store_and_preserve_padding %22
-         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
+         %25 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
          %28 = OpLoad %S %25 None
-         %29 = OpBitcast %uint %int_1
-         %33 = OpCompositeConstruct %_arr_uint_uint_1 %29
-         %34 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %33 %28
-         %36 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %12 %uint_0 %int_3 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2 %uint_1
-         %41 = OpLoad %mat4v4float %39 None
-               OpStore %36 %41 None
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %int_1 %uint_1 %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %47 = OpLoad %v4float %45 None
-         %48 = OpVectorShuffle %v4float %47 %47 1 3 0 2
-               OpStore %42 %48 None
+         %31 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %32 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %31 %28
+         %34 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %12 %uint_0 %uint_3 %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2 %uint_1
+         %39 = OpLoad %mat4v4float %37 None
+               OpStore %34 %39 None
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %12 %uint_0 %uint_1 %uint_1 %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %44 = OpLoad %v4float %42 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+               OpStore %40 %45 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %50
+%tint_store_and_preserve_padding = OpFunction %void None %47
 %value_param = OpFunctionParameter %_arr_S_uint_4
+         %48 = OpLabel
+         %49 = OpVariable %_ptr_Function__arr_S_uint_4 Function
+               OpStore %49 %value_param
+               OpBranch %51
          %51 = OpLabel
-         %52 = OpVariable %_ptr_Function__arr_S_uint_4 Function
-               OpStore %52 %value_param
                OpBranch %54
          %54 = OpLabel
-               OpBranch %57
-         %57 = OpLabel
-         %59 = OpPhi %uint %uint_0 %54 %60 %56
-               OpLoopMerge %58 %56 None
+         %56 = OpPhi %uint %uint_0 %51 %57 %53
+               OpLoopMerge %55 %53 None
+               OpBranch %52
+         %52 = OpLabel
+         %58 = OpUGreaterThanEqual %bool %56 %uint_4
+               OpSelectionMerge %60 None
+               OpBranchConditional %58 %61 %60
+         %61 = OpLabel
                OpBranch %55
+         %60 = OpLabel
+         %62 = OpAccessChain %_ptr_Function_S %49 %56
+         %64 = OpLoad %S %62 None
+         %65 = OpCompositeConstruct %_arr_uint_uint_1 %56
+         %66 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %65 %64
+               OpBranch %53
+         %53 = OpLabel
+         %57 = OpIAdd %uint %56 %uint_1
+               OpBranch %54
          %55 = OpLabel
-         %61 = OpUGreaterThanEqual %bool %59 %uint_4
-               OpSelectionMerge %63 None
-               OpBranchConditional %61 %64 %63
-         %64 = OpLabel
-               OpBranch %58
-         %63 = OpLabel
-         %65 = OpAccessChain %_ptr_Function_S %52 %59
-         %67 = OpLoad %S %65 None
-         %68 = OpCompositeConstruct %_arr_uint_uint_1 %59
-         %69 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %68 %67
-               OpBranch %56
-         %56 = OpLabel
-         %60 = OpIAdd %uint %59 %uint_1
-               OpBranch %57
-         %58 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %72
+%tint_store_and_preserve_padding_0 = OpFunction %void None %69
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param_0 = OpFunctionParameter %S
-         %73 = OpLabel
-         %74 = OpCompositeExtract %uint %target_indices 0
-         %75 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_0
-         %77 = OpCompositeExtract %int %value_param_0 0
-               OpStore %75 %77 None
-         %78 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %12 %uint_0 %74 %uint_1
-         %79 = OpCompositeExtract %mat4v4float %value_param_0 1
-               OpStore %78 %79 None
-         %80 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %74 %uint_2
-         %82 = OpCompositeExtract %int %value_param_0 2
-               OpStore %80 %82 None
+         %70 = OpLabel
+         %71 = OpCompositeExtract %uint %target_indices 0
+         %72 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_0
+         %74 = OpCompositeExtract %int %value_param_0 0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %12 %uint_0 %71 %uint_1
+         %76 = OpCompositeExtract %mat4v4float %value_param_0 1
+               OpStore %75 %76 None
+         %77 = OpAccessChain %_ptr_StorageBuffer_int %12 %uint_0 %71 %uint_2
+         %78 = OpCompositeExtract %int %value_param_0 2
+               OpStore %77 %78 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.glsl
index bdfc7e9..9bfcf18 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.glsl
@@ -60,9 +60,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[2];
-  w[3].m = v.inner[2].m;
-  w[1].m[0] = v.inner[0].m[1].ywxz;
+  w[1u] = v.inner[2u];
+  w[3u].m = v.inner[2u].m;
+  w[1u].m[0u] = v.inner[0u].m[1u].ywxz;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 4a68386..20152e5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(384u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(400u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(400u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 4a68386..20152e5 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -68,9 +68,9 @@
   S v_13[4] = v_5(0u);
   w = v_13;
   S v_14 = v_1(384u);
-  w[int(1)] = v_14;
-  w[int(3)].m = v(400u);
-  w[int(1)].m[int(0)] = asfloat(u[2u]).ywxz;
+  w[1u] = v_14;
+  w[3u].m = v(400u);
+  w[1u].m[0u] = asfloat(u[2u]).ywxz;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
index 714b11d..32d3e05 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -27,6 +27,9 @@
   threadgroup tint_array<S, 4>* w;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 4> tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -49,9 +53,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[2];
-  (*tint_module_vars.w)[3].m = (*tint_module_vars.u)[2].m;
-  (*tint_module_vars.w)[1].m[0] = (*tint_module_vars.u)[0].m[1].ywxz;
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[2u];
+  (*tint_module_vars.w)[3u].m = (*tint_module_vars.u)[2u].m;
+  (*tint_module_vars.w)[1u].m[0u] = (*tint_module_vars.u)[0u].m[1u].ywxz;
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<S, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.msl b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.msl
index 837ec67..8e1b9e3 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   /* 0x0000 */ int before;
   /* 0x0004 */ tint_array<int8_t, 12> tint_pad;
@@ -29,6 +32,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol = S{};
     (*(tint_symbol_1))[i] = tint_symbol;
diff --git a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
index a65465c..91d504e 100644
--- a/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/struct/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -55,16 +55,13 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform__arr_S_uint_4 = OpTypePointer Uniform %_arr_S_uint_4
      %uint_0 = OpConstant %uint 0
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_S = OpTypePointer Uniform %S
-      %int_2 = OpConstant %int 2
 %_ptr_Workgroup_mat4v4float = OpTypePointer Workgroup %mat4v4float
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-         %63 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
     %f_inner = OpFunction %void None %19
 %tint_local_index = OpFunctionParameter %uint
          %20 = OpLabel
@@ -93,24 +90,24 @@
          %39 = OpAccessChain %_ptr_Uniform__arr_S_uint_4 %1 %uint_0
          %42 = OpLoad %_arr_S_uint_4 %39 None
                OpStore %w %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_S %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %int_2
-         %48 = OpLoad %S %45 None
-               OpStore %43 %48 None
-         %49 = OpAccessChain %_ptr_Workgroup_mat4v4float %w %int_3 %uint_1
-         %52 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %int_2 %uint_1
-         %54 = OpLoad %mat4v4float %52 None
-               OpStore %49 %54 None
-         %55 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1 %uint_1 %int_0
-         %58 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0 %uint_1 %int_1
-         %60 = OpLoad %v4float %58 None
-         %61 = OpVectorShuffle %v4float %60 %60 1 3 0 2
-               OpStore %55 %61 None
+         %43 = OpAccessChain %_ptr_Workgroup_S %w %uint_1
+         %44 = OpAccessChain %_ptr_Uniform_S %1 %uint_0 %uint_2
+         %46 = OpLoad %S %44 None
+               OpStore %43 %46 None
+         %47 = OpAccessChain %_ptr_Workgroup_mat4v4float %w %uint_3 %uint_1
+         %50 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0 %uint_2 %uint_1
+         %52 = OpLoad %mat4v4float %50 None
+               OpStore %47 %52 None
+         %53 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1 %uint_1 %uint_0
+         %55 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_1 %uint_1
+         %57 = OpLoad %v4float %55 None
+         %58 = OpVectorShuffle %v4float %57 %57 1 3 0 2
+               OpStore %53 %58 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %63
-         %64 = OpLabel
-         %65 = OpLoad %uint %f_local_invocation_index_Input None
-         %66 = OpFunctionCall %void %f_inner %65
+          %f = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpLoad %uint %f_local_invocation_index_Input None
+         %63 = OpFunctionCall %void %f_inner %62
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4a1860d..c8ce3e9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 2, 2> l_m = m_load(0u);
-  const uint scalar_offset_2 = ((4u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((4u * min(uint(p_m_i_save), 1u))) / 4;
   uint ubo_load_2 = m[scalar_offset_2 / 4][scalar_offset_2 % 4];
   vector<float16_t, 2> l_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_2 & 0xFFFF)), float16_t(f16tof32(ubo_load_2 >> 16)));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 828f25a..c3370d2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,5 +15,5 @@
 void main() {
   f16mat2 v_1 = f16mat2(v.inner_col0, v.inner_col1);
   f16mat2 l_m = v_1;
-  f16vec2 l_m_i = v_1[i()];
+  f16vec2 l_m_i = v_1[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 68d778f..a70ee8b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_4 = (4u * uint(i()));
+  uint v_4 = (4u * uint(min(uint(i()), 1u)));
   matrix<float16_t, 2, 2> l_m = v_2(0u);
   vector<float16_t, 2> l_m_i = tint_bitcast_to_f16(m[(v_4 / 16u)][((v_4 % 16u) / 4u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index ceffef1..0aa6eaf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half2x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)]);
   half2x2 const l_m = (*p_m);
   half2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 5739bd5..fc87bf6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   half2x2 const l_m = *(tint_symbol_1);
   half2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index ed28032..d709a24 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,7 +63,9 @@
         %l_m = OpCompositeConstruct %mat2v2half %25 %28
                OpStore %31 %l_m
          %33 = OpFunctionCall %int %i
-         %34 = OpAccessChain %_ptr_Function_v2half %31 %33
-      %l_m_i = OpLoad %v2half %34 None
+         %34 = OpBitcast %uint %33
+         %35 = OpExtInst %uint %36 UMin %34 %uint_1
+         %37 = OpAccessChain %_ptr_Function_v2half %31 %35
+      %l_m_i = OpLoad %v2half %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 3dc5e8c..658dcdf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 void main() {
   f16mat2 v_1 = f16mat2(v.inner_col0, v.inner_col1);
   f16mat2 l_m = v_1;
-  f16vec2 l_m_1 = v_1[1];
+  f16vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index d112f60..1e225f0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half2x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half2x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_1 = (&(*p_m)[1]);
+  const constant half2* const p_m_1 = (&(*p_m)[1u]);
   half2x2 const l_m = (*p_m);
   half2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.glsl
index ba3c550..9cecaeb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.glsl
@@ -9,6 +9,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat2 t = transpose(f16mat2(v.inner_col0, v.inner_col1));
-  float16_t l = length(f16mat2(v.inner_col0, v.inner_col1)[1]);
-  float16_t a = abs(f16mat2(v.inner_col0, v.inner_col1)[0].yx[0u]);
+  float16_t l = length(f16mat2(v.inner_col0, v.inner_col1)[1u]);
+  float16_t a = abs(f16mat2(v.inner_col0, v.inner_col1)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
index e408da4..4a5fb93 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half2x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half2x2 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.glsl
index 3b76cfa..ebec7f8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.glsl
@@ -15,8 +15,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat2(v_1.inner_col0, v_1.inner_col1));
-  b(f16mat2(v_1.inner_col0, v_1.inner_col1)[1]);
-  b(f16mat2(v_1.inner_col0, v_1.inner_col1)[1].yx);
-  c(f16mat2(v_1.inner_col0, v_1.inner_col1)[1][0u]);
-  c(f16mat2(v_1.inner_col0, v_1.inner_col1)[1].yx[0u]);
+  b(f16mat2(v_1.inner_col0, v_1.inner_col1)[1u]);
+  b(f16mat2(v_1.inner_col0, v_1.inner_col1)[1u].yx);
+  c(f16mat2(v_1.inner_col0, v_1.inner_col1)[1u][0u]);
+  c(f16mat2(v_1.inner_col0, v_1.inner_col1)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.ir.msl
index 480c176..8f7457c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half2x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.glsl
index 7de14f4..f6437f4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat2(v.inner_col0, v.inner_col1);
-  p[1] = f16mat2(v.inner_col0, v.inner_col1)[0];
-  p[1] = f16mat2(v.inner_col0, v.inner_col1)[0].yx;
-  p[0][1] = f16mat2(v.inner_col0, v.inner_col1)[1][0];
+  p[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u];
+  p[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  p[0u][1u] = f16mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index fb051f7..8a462c7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -19,8 +19,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_2(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  p[int(0)].y = float16_t(f16tof32(u[0u].y));
+  p[1u] = tint_bitcast_to_f16(u[0u].x);
+  p[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  p[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.msl
index 0aa67e2..d6f077e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half2x2 p = half2x2(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.spvasm
index 6bada9a..621db62 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -37,9 +37,6 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -50,20 +47,20 @@
          %21 = OpLoad %v2half %19 None
          %22 = OpCompositeConstruct %mat2v2half %18 %21
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %27 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %28 = OpLoad %v2half %27 None
-               OpStore %23 %28 None
-         %29 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %31 = OpLoad %v2half %30 None
-         %32 = OpVectorShuffle %v2half %31 %31 1 0
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_Private_v2half %p %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %36 = OpAccessChain %_ptr_Uniform_half %35 %int_0
-         %38 = OpLoad %half %36 None
-         %39 = OpAccessChain %_ptr_Private_half %33 %int_1
-               OpStore %39 %38 None
+         %23 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %25 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %26 = OpLoad %v2half %25 None
+               OpStore %23 %26 None
+         %27 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %29 = OpLoad %v2half %28 None
+         %30 = OpVectorShuffle %v2half %29 %29 1 0
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_Private_v2half %p %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_half %32 %uint_0
+         %35 = OpLoad %half %33 None
+         %36 = OpAccessChain %_ptr_Private_half %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.glsl
index 8f1b155..ca05372 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.glsl
@@ -13,7 +13,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat2(v.inner_col0, v.inner_col1);
-  v_1.inner[1] = f16mat2(v.inner_col0, v.inner_col1)[0];
-  v_1.inner[1] = f16mat2(v.inner_col0, v.inner_col1)[0].yx;
-  v_1.inner[0][1] = f16mat2(v.inner_col0, v.inner_col1)[1][0];
+  v_1.inner[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u];
+  v_1.inner[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  v_1.inner[0u][1u] = f16mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.ir.msl
index 13cb5b4..3a732d3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half2x2* u [[buffer(0)]], device half2x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.spvasm
index c525bf8..324cbdf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -46,9 +46,6 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_mat2v2half = OpTypePointer StorageBuffer %mat2v2half
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -60,20 +57,20 @@
          %22 = OpCompositeConstruct %mat2v2half %18 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_mat2v2half %6 %uint_0
                OpStore %23 %22 None
-         %25 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %30 = OpLoad %v2half %29 None
-               OpStore %25 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %33 = OpLoad %v2half %32 None
-         %34 = OpVectorShuffle %v2half %33 %33 1 0
-               OpStore %31 %34 None
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %38 = OpAccessChain %_ptr_Uniform_half %37 %int_0
-         %40 = OpLoad %half %38 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_half %35 %int_1
-               OpStore %41 %40 None
+         %25 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %28 = OpLoad %v2half %27 None
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %31 = OpLoad %v2half %30 None
+         %32 = OpVectorShuffle %v2half %31 %31 1 0
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_half %34 %uint_0
+         %37 = OpLoad %half %35 None
+         %38 = OpAccessChain %_ptr_StorageBuffer_half %33 %uint_1
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.glsl
index a9ee295..959dcae 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.glsl
@@ -13,9 +13,9 @@
   }
   barrier();
   w = f16mat2(v.inner_col0, v.inner_col1);
-  w[1] = f16mat2(v.inner_col0, v.inner_col1)[0];
-  w[1] = f16mat2(v.inner_col0, v.inner_col1)[0].yx;
-  w[0][1] = f16mat2(v.inner_col0, v.inner_col1)[1][0];
+  w[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u];
+  w[1u] = f16mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  w[0u][1u] = f16mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 8f5344a..619d2ba 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -26,9 +26,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_2(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  w[int(0)].y = float16_t(f16tof32(u[0u].y));
+  w[1u] = tint_bitcast_to_f16(u[0u].x);
+  w[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  w[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
index 0df3685..81b0699 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half2x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
index b5e9ba5..ccd227c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -46,12 +46,9 @@
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %52 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -69,26 +66,26 @@
          %31 = OpLoad %v2half %30 None
          %32 = OpCompositeConstruct %mat2v2half %29 %31
                OpStore %w %32 None
-         %33 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %37 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %38 = OpLoad %v2half %37 None
-               OpStore %33 %38 None
-         %39 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %41 = OpLoad %v2half %40 None
-         %42 = OpVectorShuffle %v2half %41 %41 1 0
-               OpStore %39 %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_v2half %w %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %46 = OpAccessChain %_ptr_Uniform_half %45 %int_0
-         %48 = OpLoad %half %46 None
-         %49 = OpAccessChain %_ptr_Workgroup_half %43 %int_1
-               OpStore %49 %48 None
+         %33 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %36 = OpLoad %v2half %35 None
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %39 = OpLoad %v2half %38 None
+         %40 = OpVectorShuffle %v2half %39 %39 1 0
+               OpStore %37 %40 None
+         %41 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_half %42 %uint_0
+         %45 = OpLoad %half %43 None
+         %46 = OpAccessChain %_ptr_Workgroup_half %41 %uint_1
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %52
-         %53 = OpLabel
-         %54 = OpLoad %uint %f_local_invocation_index_Input None
-         %55 = OpFunctionCall %void %f_inner %54
+          %f = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpLoad %uint %f_local_invocation_index_Input None
+         %52 = OpFunctionCall %void %f_inner %51
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index f93fe64..3fb9180 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float2x2 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((8u * min(uint(p_m_i_save), 1u))) / 4;
   uint4 ubo_load_2 = m[scalar_offset_2 / 4];
   float2 l_m_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index f93fe64..3fb9180 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float2x2 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((8u * min(uint(p_m_i_save), 1u))) / 4;
   uint4 ubo_load_2 = m[scalar_offset_2 / 4];
   float2 l_m_i = asfloat(((scalar_offset_2 & 2) ? ubo_load_2.zw : ubo_load_2.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 8e07eb0..4978a8e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -14,5 +14,5 @@
 void main() {
   mat2 v_1 = mat2(v.inner_col0, v.inner_col1);
   mat2 l_m = v_1;
-  vec2 l_m_i = v_1[i()];
+  vec2 l_m_i = v_1[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 4a16b1f..38da796 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -17,7 +17,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_4 = (8u * uint(i()));
+  uint v_4 = (8u * uint(min(uint(i()), 1u)));
   float2x2 l_m = v(0u);
   uint4 v_5 = m[(v_4 / 16u)];
   float2 l_m_i = asfloat((((((v_4 % 16u) / 4u) == 2u)) ? (v_5.zw) : (v_5.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 4a16b1f..38da796 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -17,7 +17,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_4 = (8u * uint(i()));
+  uint v_4 = (8u * uint(min(uint(i()), 1u)));
   float2x2 l_m = v(0u);
   uint4 v_5 = m[(v_4 / 16u)];
   float2 l_m_i = asfloat((((((v_4 % 16u) / 4u) == 2u)) ? (v_5.zw) : (v_5.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 742667b..60a1500 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float2x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)]);
   float2x2 const l_m = (*p_m);
   float2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 1a7a358..4b83a55 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   float2x2 const l_m = *(tint_symbol_1);
   float2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index e755076..15c091c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -59,7 +60,9 @@
         %l_m = OpCompositeConstruct %mat2v2float %25 %28
                OpStore %31 %l_m
          %33 = OpFunctionCall %int %i
-         %34 = OpAccessChain %_ptr_Function_v2float %31 %33
-      %l_m_i = OpLoad %v2float %34 None
+         %34 = OpBitcast %uint %33
+         %35 = OpExtInst %uint %36 UMin %34 %uint_1
+         %37 = OpAccessChain %_ptr_Function_v2float %31 %35
+      %l_m_i = OpLoad %v2float %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
index 3576819..278094d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 void main() {
   mat2 v_1 = mat2(v.inner_col0, v.inner_col1);
   mat2 l_m = v_1;
-  vec2 l_m_1 = v_1[1];
+  vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 8330d3d..f3506d5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float2x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float2x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_1 = (&(*p_m)[1]);
+  const constant float2* const p_m_1 = (&(*p_m)[1u]);
   float2x2 const l_m = (*p_m);
   float2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.glsl
index 4c89489..2ae6ade 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.glsl
@@ -8,6 +8,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2 t = transpose(mat2(v.inner_col0, v.inner_col1));
-  float l = length(mat2(v.inner_col0, v.inner_col1)[1]);
-  float a = abs(mat2(v.inner_col0, v.inner_col1)[0].yx[0u]);
+  float l = length(mat2(v.inner_col0, v.inner_col1)[1u]);
+  float a = abs(mat2(v.inner_col0, v.inner_col1)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
index e104dd1..7aa6c90 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float2x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float2x2 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.glsl
index 510149a..2053ab1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.glsl
@@ -14,8 +14,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat2(v_1.inner_col0, v_1.inner_col1));
-  b(mat2(v_1.inner_col0, v_1.inner_col1)[1]);
-  b(mat2(v_1.inner_col0, v_1.inner_col1)[1].yx);
-  c(mat2(v_1.inner_col0, v_1.inner_col1)[1][0u]);
-  c(mat2(v_1.inner_col0, v_1.inner_col1)[1].yx[0u]);
+  b(mat2(v_1.inner_col0, v_1.inner_col1)[1u]);
+  b(mat2(v_1.inner_col0, v_1.inner_col1)[1u].yx);
+  c(mat2(v_1.inner_col0, v_1.inner_col1)[1u][0u]);
+  c(mat2(v_1.inner_col0, v_1.inner_col1)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.ir.msl
index 3e1c91f..c4a8e59 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float2x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.glsl
index a9ae726..b1519fd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat2(v.inner_col0, v.inner_col1);
-  p[1] = mat2(v.inner_col0, v.inner_col1)[0];
-  p[1] = mat2(v.inner_col0, v.inner_col1)[0].yx;
-  p[0][1] = mat2(v.inner_col0, v.inner_col1)[1][0];
+  p[1u] = mat2(v.inner_col0, v.inner_col1)[0u];
+  p[1u] = mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  p[0u][1u] = mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index eddce4f..c2ac758 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index eddce4f..c2ac758 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.msl
index 5d9debc..ffe8d2c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float2x2 p = float2x2(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.spvasm
index 4e9aaf6..1e48d30 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -34,9 +34,6 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -47,20 +44,20 @@
          %21 = OpLoad %v2float %19 None
          %22 = OpCompositeConstruct %mat2v2float %18 %21
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %27 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %28 = OpLoad %v2float %27 None
-               OpStore %23 %28 None
-         %29 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %31 = OpLoad %v2float %30 None
-         %32 = OpVectorShuffle %v2float %31 %31 1 0
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_Private_v2float %p %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %36 = OpAccessChain %_ptr_Uniform_float %35 %int_0
-         %38 = OpLoad %float %36 None
-         %39 = OpAccessChain %_ptr_Private_float %33 %int_1
-               OpStore %39 %38 None
+         %23 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %25 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %26 = OpLoad %v2float %25 None
+               OpStore %23 %26 None
+         %27 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %29 = OpLoad %v2float %28 None
+         %30 = OpVectorShuffle %v2float %29 %29 1 0
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_Private_v2float %p %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_float %32 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpAccessChain %_ptr_Private_float %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.glsl
index ead3551..c851fd0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = mat2(v.inner_col0, v.inner_col1);
-  v_1.inner[1] = mat2(v.inner_col0, v.inner_col1)[0];
-  v_1.inner[1] = mat2(v.inner_col0, v.inner_col1)[0].yx;
-  v_1.inner[0][1] = mat2(v.inner_col0, v.inner_col1)[1][0];
+  v_1.inner[1u] = mat2(v.inner_col0, v.inner_col1)[0u];
+  v_1.inner[1u] = mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  v_1.inner[0u][1u] = mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.ir.msl
index 8c9384e..4e83b6d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float2x2* u [[buffer(0)]], device float2x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.spvasm
index 34a40c5..209f4d8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,9 +43,6 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_mat2v2float = OpTypePointer StorageBuffer %mat2v2float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -57,20 +54,20 @@
          %22 = OpCompositeConstruct %mat2v2float %18 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_mat2v2float %6 %uint_0
                OpStore %23 %22 None
-         %25 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %30 = OpLoad %v2float %29 None
-               OpStore %25 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %33 = OpLoad %v2float %32 None
-         %34 = OpVectorShuffle %v2float %33 %33 1 0
-               OpStore %31 %34 None
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %38 = OpAccessChain %_ptr_Uniform_float %37 %int_0
-         %40 = OpLoad %float %38 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_float %35 %int_1
-               OpStore %41 %40 None
+         %25 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %28 = OpLoad %v2float %27 None
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %31 = OpLoad %v2float %30 None
+         %32 = OpVectorShuffle %v2float %31 %31 1 0
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_float %34 %uint_0
+         %37 = OpLoad %float %35 None
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %33 %uint_1
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.glsl
index 52bedbc..e489cb7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.glsl
@@ -12,9 +12,9 @@
   }
   barrier();
   w = mat2(v.inner_col0, v.inner_col1);
-  w[1] = mat2(v.inner_col0, v.inner_col1)[0];
-  w[1] = mat2(v.inner_col0, v.inner_col1)[0].yx;
-  w[0][1] = mat2(v.inner_col0, v.inner_col1)[1][0];
+  w[1u] = mat2(v.inner_col0, v.inner_col1)[0u];
+  w[1u] = mat2(v.inner_col0, v.inner_col1)[0u].yx;
+  w[0u][1u] = mat2(v.inner_col0, v.inner_col1)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 412c226..941d5a1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -20,9 +20,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 412c226..941d5a1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -20,9 +20,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
index df40be3..3a7263b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float2x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
index 2a7d2dd..b9e8dee 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,12 +43,9 @@
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %52 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -66,26 +63,26 @@
          %31 = OpLoad %v2float %30 None
          %32 = OpCompositeConstruct %mat2v2float %29 %31
                OpStore %w %32 None
-         %33 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %37 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %38 = OpLoad %v2float %37 None
-               OpStore %33 %38 None
-         %39 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %41 = OpLoad %v2float %40 None
-         %42 = OpVectorShuffle %v2float %41 %41 1 0
-               OpStore %39 %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_v2float %w %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %46 = OpAccessChain %_ptr_Uniform_float %45 %int_0
-         %48 = OpLoad %float %46 None
-         %49 = OpAccessChain %_ptr_Workgroup_float %43 %int_1
-               OpStore %49 %48 None
+         %33 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %36 = OpLoad %v2float %35 None
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %39 = OpLoad %v2float %38 None
+         %40 = OpVectorShuffle %v2float %39 %39 1 0
+               OpStore %37 %40 None
+         %41 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_float %42 %uint_0
+         %45 = OpLoad %float %43 None
+         %46 = OpAccessChain %_ptr_Workgroup_float %41 %uint_1
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %52
-         %53 = OpLabel
-         %54 = OpLoad %uint %f_local_invocation_index_Input None
-         %55 = OpFunctionCall %void %f_inner %54
+          %f = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpLoad %uint %f_local_invocation_index_Input None
+         %52 = OpFunctionCall %void %f_inner %51
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index c1921ca..a0d31c1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -26,7 +26,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 2, 3> l_m = m_load(0u);
-  const uint scalar_offset_2 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((8u * min(uint(p_m_i_save), 1u))) / 4;
   uint4 ubo_load_5 = m[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index fdeb923..006d78e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,5 +15,5 @@
 void main() {
   f16mat2x3 v_1 = f16mat2x3(v.inner_col0, v.inner_col1);
   f16mat2x3 l_m = v_1;
-  f16vec3 l_m_i = v_1[i()];
+  f16vec3 l_m_i = v_1[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index b018752..91071ca 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -29,7 +29,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (8u * uint(i()));
+  uint v_8 = (8u * uint(min(uint(i()), 1u)));
   matrix<float16_t, 2, 3> l_m = v_4(0u);
   uint4 v_9 = m[(v_8 / 16u)];
   vector<float16_t, 3> l_m_i = tint_bitcast_to_f16((((((v_8 % 16u) / 4u) == 2u)) ? (v_9.zw) : (v_9.xy))).xyz;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 0389270..d1cb2ea 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half2x3 const l_m = half2x3(v_1, half3(v[1u].packed));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 614fb69..705f880 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   half2x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   half3 const l_m_i = half3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 052272e..539e853 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,7 +63,9 @@
         %l_m = OpCompositeConstruct %mat2v3half %25 %28
                OpStore %31 %l_m
          %33 = OpFunctionCall %int %i
-         %34 = OpAccessChain %_ptr_Function_v3half %31 %33
-      %l_m_i = OpLoad %v3half %34 None
+         %34 = OpBitcast %uint %33
+         %35 = OpExtInst %uint %36 UMin %34 %uint_1
+         %37 = OpAccessChain %_ptr_Function_v3half %31 %35
+      %l_m_i = OpLoad %v3half %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
index b1a4de3..84bd5df 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 void main() {
   f16mat2x3 v_1 = f16mat2x3(v.inner_col0, v.inner_col1);
   f16mat2x3 l_m = v_1;
-  f16vec3 l_m_1 = v_1[1];
+  f16vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 8bfaf43..112bbf6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f16_array_element, 2>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f16_array_element, 2>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_half3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half2x3 const l_m = half2x3(v_1, half3(v[1u].packed));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.glsl
index 58a3513..b1a15aa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.glsl
@@ -9,6 +9,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat3x2 t = transpose(f16mat2x3(v.inner_col0, v.inner_col1));
-  float16_t l = length(f16mat2x3(v.inner_col0, v.inner_col1)[1]);
-  float16_t a = abs(f16mat2x3(v.inner_col0, v.inner_col1)[0].zxy[0u]);
+  float16_t l = length(f16mat2x3(v.inner_col0, v.inner_col1)[1u]);
+  float16_t a = abs(f16mat2x3(v.inner_col0, v.inner_col1)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
index cfc4f01..9bac4a6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -27,6 +27,6 @@
   tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u);
   half3 const v_1 = half3(v[0u].packed);
   half3x2 const t = transpose(half2x3(v_1, half3(v[1u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[1].packed));
-  half const a = abs(half3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[1u].packed));
+  half const a = abs(half3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.glsl
index 4f35ef8..0a51a40 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.glsl
@@ -15,8 +15,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat2x3(v_1.inner_col0, v_1.inner_col1));
-  b(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1]);
-  b(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1].zxy);
-  c(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1][0u]);
-  c(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1].zxy[0u]);
+  b(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1u]);
+  b(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1u].zxy);
+  c(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1u][0u]);
+  c(f16mat2x3(v_1.inner_col0, v_1.inner_col1)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.ir.msl
index af477f9..cb71b95 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_fn.wgsl.expected.ir.msl
@@ -36,8 +36,8 @@
   tint_array<tint_packed_vec3_f16_array_element, 2> const v_1 = (*tint_module_vars.u);
   half3 const v_2 = half3(v_1[0u].packed);
   a(half2x3(v_2, half3(v_1[1u].packed)));
-  b(half3((*tint_module_vars.u)[1].packed));
-  b(half3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(half3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(half3((*tint_module_vars.u)[1u].packed));
+  b(half3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(half3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.glsl
index 24f1a99..a28c451 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat2x3(v.inner_col0, v.inner_col1);
-  p[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0];
-  p[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  p[0][1] = f16mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  p[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u];
+  p[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  p[0u][1u] = f16mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 559c0c1..873176d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -25,8 +25,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.msl
index 3a1b508..292beb0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.ir.msl
@@ -29,7 +29,7 @@
   tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u);
   half3 const v_1 = half3(v[0u].packed);
   (*tint_module_vars.p) = half2x3(v_1, half3(v[1u].packed));
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.spvasm
index 2229b10..dfc4807 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -37,9 +37,6 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -50,20 +47,20 @@
          %21 = OpLoad %v3half %19 None
          %22 = OpCompositeConstruct %mat2v3half %18 %21
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %27 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %28 = OpLoad %v3half %27 None
-               OpStore %23 %28 None
-         %29 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %31 = OpLoad %v3half %30 None
-         %32 = OpVectorShuffle %v3half %31 %31 2 0 1
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_Private_v3half %p %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %36 = OpAccessChain %_ptr_Uniform_half %35 %int_0
-         %38 = OpLoad %half %36 None
-         %39 = OpAccessChain %_ptr_Private_half %33 %int_1
-               OpStore %39 %38 None
+         %23 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %25 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %26 = OpLoad %v3half %25 None
+               OpStore %23 %26 None
+         %27 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %29 = OpLoad %v3half %28 None
+         %30 = OpVectorShuffle %v3half %29 %29 2 0 1
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_Private_v3half %p %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_half %32 %uint_0
+         %35 = OpLoad %half %33 None
+         %36 = OpAccessChain %_ptr_Private_half %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
index 0d9577c..f2e1611 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.glsl
@@ -17,7 +17,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(f16mat2x3(v.inner_col0, v.inner_col1));
-  v_1.inner[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0];
-  v_1.inner[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  v_1.inner[0][1] = f16mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  v_1.inner[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u];
+  v_1.inner[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  v_1.inner[0u][1u] = f16mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.ir.msl
index 0fa0f93..db7e05d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.ir.msl
@@ -33,7 +33,7 @@
   tint_array<tint_packed_vec3_f16_array_element, 2> const v = (*tint_module_vars.u);
   half3 const v_1 = half3(v[0u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, half2x3(v_1, half3(v[1u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
index be18c9f..ced90d1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 50
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -47,12 +47,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %44 = OpTypeFunction %void %mat2v3half
+         %41 = OpTypeFunction %void %mat2v3half
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
@@ -61,31 +58,31 @@
          %21 = OpLoad %v3half %19 None
          %22 = OpCompositeConstruct %mat2v3half %18 %21
          %23 = OpFunctionCall %void %tint_store_and_preserve_padding %22
-         %25 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %30 = OpLoad %v3half %29 None
-               OpStore %25 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %33 = OpLoad %v3half %32 None
-         %34 = OpVectorShuffle %v3half %33 %33 2 0 1
-               OpStore %31 %34 None
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %38 = OpAccessChain %_ptr_Uniform_half %37 %int_0
-         %40 = OpLoad %half %38 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_half %35 %int_1
-               OpStore %41 %40 None
+         %25 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %28 = OpLoad %v3half %27 None
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %31 = OpLoad %v3half %30 None
+         %32 = OpVectorShuffle %v3half %31 %31 2 0 1
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_half %34 %uint_0
+         %37 = OpLoad %half %35 None
+         %38 = OpAccessChain %_ptr_StorageBuffer_half %33 %uint_1
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %44
+%tint_store_and_preserve_padding = OpFunction %void None %41
 %value_param = OpFunctionParameter %mat2v3half
-         %45 = OpLabel
-         %46 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
-         %47 = OpCompositeExtract %v3half %value_param 0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
-         %49 = OpCompositeExtract %v3half %value_param 1
-               OpStore %48 %49 None
+         %42 = OpLabel
+         %43 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %44 = OpCompositeExtract %v3half %value_param 0
+               OpStore %43 %44 None
+         %45 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %46 = OpCompositeExtract %v3half %value_param 1
+               OpStore %45 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.glsl
index 148abc0..0feb032 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.glsl
@@ -13,9 +13,9 @@
   }
   barrier();
   w = f16mat2x3(v.inner_col0, v.inner_col1);
-  w[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0];
-  w[1] = f16mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  w[0][1] = f16mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  w[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u];
+  w[1u] = f16mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  w[0u][1u] = f16mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index cfef2c4..b9c6f79 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -32,9 +32,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
index 42c1dd1..21dbb89 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -38,9 +38,9 @@
   half2x3 const v_2 = half2x3(v_1, half3(v[1u].packed));
   (*tint_module_vars.w)[0u].packed = packed_half3(v_2[0u]);
   (*tint_module_vars.w)[1u].packed = packed_half3(v_2[1u]);
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f16_array_element, 2>* u [[buffer(0)]], threadgroup tint_symbol_1* v_3 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
index 87ca4b1..b10f166 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -46,12 +46,9 @@
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %52 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -69,26 +66,26 @@
          %31 = OpLoad %v3half %30 None
          %32 = OpCompositeConstruct %mat2v3half %29 %31
                OpStore %w %32 None
-         %33 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %38 = OpLoad %v3half %37 None
-               OpStore %33 %38 None
-         %39 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %41 = OpLoad %v3half %40 None
-         %42 = OpVectorShuffle %v3half %41 %41 2 0 1
-               OpStore %39 %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_v3half %w %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %46 = OpAccessChain %_ptr_Uniform_half %45 %int_0
-         %48 = OpLoad %half %46 None
-         %49 = OpAccessChain %_ptr_Workgroup_half %43 %int_1
-               OpStore %49 %48 None
+         %33 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %36 = OpLoad %v3half %35 None
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %39 = OpLoad %v3half %38 None
+         %40 = OpVectorShuffle %v3half %39 %39 2 0 1
+               OpStore %37 %40 None
+         %41 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_half %42 %uint_0
+         %45 = OpLoad %half %43 None
+         %46 = OpAccessChain %_ptr_Workgroup_half %41 %uint_1
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %52
-         %53 = OpLabel
-         %54 = OpLoad %uint %f_local_invocation_index_Input None
-         %55 = OpFunctionCall %void %f_inner %54
+          %f = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpLoad %uint %f_local_invocation_index_Input None
+         %52 = OpFunctionCall %void %f_inner %51
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 5ca1922..12e1426 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -18,7 +18,7 @@
 void f() {
   int p_m_i_save = i();
   float2x3 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((16u * min(uint(p_m_i_save), 1u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_2 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 5ca1922..12e1426 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -18,7 +18,7 @@
 void f() {
   int p_m_i_save = i();
   float2x3 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((16u * min(uint(p_m_i_save), 1u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_2 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index ce71ccc..bc80aa9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,5 +15,5 @@
 void main() {
   mat2x3 v_1 = mat2x3(v.inner_col0, v.inner_col1);
   mat2x3 l_m = v_1;
-  vec3 l_m_i = v_1[i()];
+  vec3 l_m_i = v_1[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 0d7ddb4..ed824a2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 1u)));
   float2x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 0d7ddb4..ed824a2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 1u)));
   float2x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 59519ad..bc34a40 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)].packed);
   tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float2x3 const l_m = float2x3(v_1, float3(v[1u].packed));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index c8fc6a9..2cc3aa2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   float2x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   float3 const l_m_i = float3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 2c18275..a050239 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -59,7 +60,9 @@
         %l_m = OpCompositeConstruct %mat2v3float %25 %28
                OpStore %31 %l_m
          %33 = OpFunctionCall %int %i
-         %34 = OpAccessChain %_ptr_Function_v3float %31 %33
-      %l_m_i = OpLoad %v3float %34 None
+         %34 = OpBitcast %uint %33
+         %35 = OpExtInst %uint %36 UMin %34 %uint_1
+         %37 = OpAccessChain %_ptr_Function_v3float %31 %35
+      %l_m_i = OpLoad %v3float %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
index 0e01181..29e5002 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 void main() {
   mat2x3 v_1 = mat2x3(v.inner_col0, v.inner_col1);
   mat2x3 l_m = v_1;
-  vec3 l_m_1 = v_1[1];
+  vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 61305e2..d159500 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f32_array_element, 2>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f32_array_element, 2>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_float3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float2x3 const l_m = float2x3(v_1, float3(v[1u].packed));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.glsl
index 91d8e2b..394869e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.glsl
@@ -9,6 +9,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3x2 t = transpose(mat2x3(v.inner_col0, v.inner_col1));
-  float l = length(mat2x3(v.inner_col0, v.inner_col1)[1]);
-  float a = abs(mat2x3(v.inner_col0, v.inner_col1)[0].zxy[0u]);
+  float l = length(mat2x3(v.inner_col0, v.inner_col1)[1u]);
+  float a = abs(mat2x3(v.inner_col0, v.inner_col1)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
index 03ad861..1d0a67f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -27,6 +27,6 @@
   tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u);
   float3 const v_1 = float3(v[0u].packed);
   float3x2 const t = transpose(float2x3(v_1, float3(v[1u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[1].packed));
-  float const a = abs(float3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[1u].packed));
+  float const a = abs(float3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.glsl
index 7dcc239..5974d15 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.glsl
@@ -15,8 +15,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat2x3(v_1.inner_col0, v_1.inner_col1));
-  b(mat2x3(v_1.inner_col0, v_1.inner_col1)[1]);
-  b(mat2x3(v_1.inner_col0, v_1.inner_col1)[1].zxy);
-  c(mat2x3(v_1.inner_col0, v_1.inner_col1)[1][0u]);
-  c(mat2x3(v_1.inner_col0, v_1.inner_col1)[1].zxy[0u]);
+  b(mat2x3(v_1.inner_col0, v_1.inner_col1)[1u]);
+  b(mat2x3(v_1.inner_col0, v_1.inner_col1)[1u].zxy);
+  c(mat2x3(v_1.inner_col0, v_1.inner_col1)[1u][0u]);
+  c(mat2x3(v_1.inner_col0, v_1.inner_col1)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.ir.msl
index 40a3ac81..5fb2d76 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_fn.wgsl.expected.ir.msl
@@ -36,8 +36,8 @@
   tint_array<tint_packed_vec3_f32_array_element, 2> const v_1 = (*tint_module_vars.u);
   float3 const v_2 = float3(v_1[0u].packed);
   a(float2x3(v_2, float3(v_1[1u].packed)));
-  b(float3((*tint_module_vars.u)[1].packed));
-  b(float3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(float3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(float3((*tint_module_vars.u)[1u].packed));
+  b(float3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(float3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.glsl
index fe107f8..2145a08 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat2x3(v.inner_col0, v.inner_col1);
-  p[1] = mat2x3(v.inner_col0, v.inner_col1)[0];
-  p[1] = mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  p[0][1] = mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  p[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u];
+  p[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  p[0u][1u] = mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 0ad7b3d..a4ba52f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 0ad7b3d..a4ba52f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.msl
index 23bf2ac..74d09fa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.ir.msl
@@ -29,7 +29,7 @@
   tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u);
   float3 const v_1 = float3(v[0u].packed);
   (*tint_module_vars.p) = float2x3(v_1, float3(v[1u].packed));
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.spvasm
index ca94634..6b4b6fd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -34,9 +34,6 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -47,20 +44,20 @@
          %21 = OpLoad %v3float %19 None
          %22 = OpCompositeConstruct %mat2v3float %18 %21
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %27 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %28 = OpLoad %v3float %27 None
-               OpStore %23 %28 None
-         %29 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %31 = OpLoad %v3float %30 None
-         %32 = OpVectorShuffle %v3float %31 %31 2 0 1
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_Private_v3float %p %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %36 = OpAccessChain %_ptr_Uniform_float %35 %int_0
-         %38 = OpLoad %float %36 None
-         %39 = OpAccessChain %_ptr_Private_float %33 %int_1
-               OpStore %39 %38 None
+         %23 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %25 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %26 = OpLoad %v3float %25 None
+               OpStore %23 %26 None
+         %27 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %29 = OpLoad %v3float %28 None
+         %30 = OpVectorShuffle %v3float %29 %29 2 0 1
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_Private_v3float %p %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_float %32 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpAccessChain %_ptr_Private_float %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
index 9ea8a1a..6d99e56 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.glsl
@@ -17,7 +17,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(mat2x3(v.inner_col0, v.inner_col1));
-  v_1.inner[1] = mat2x3(v.inner_col0, v.inner_col1)[0];
-  v_1.inner[1] = mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  v_1.inner[0][1] = mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  v_1.inner[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u];
+  v_1.inner[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  v_1.inner[0u][1u] = mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.ir.msl
index ca90073..5212aec 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.ir.msl
@@ -33,7 +33,7 @@
   tint_array<tint_packed_vec3_f32_array_element, 2> const v = (*tint_module_vars.u);
   float3 const v_1 = float3(v[0u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, float2x3(v_1, float3(v[1u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
index 3b85886..c3c7e03 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 50
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -44,12 +44,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %44 = OpTypeFunction %void %mat2v3float
+         %41 = OpTypeFunction %void %mat2v3float
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
@@ -58,31 +55,31 @@
          %21 = OpLoad %v3float %19 None
          %22 = OpCompositeConstruct %mat2v3float %18 %21
          %23 = OpFunctionCall %void %tint_store_and_preserve_padding %22
-         %25 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %30 = OpLoad %v3float %29 None
-               OpStore %25 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %33 = OpLoad %v3float %32 None
-         %34 = OpVectorShuffle %v3float %33 %33 2 0 1
-               OpStore %31 %34 None
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %38 = OpAccessChain %_ptr_Uniform_float %37 %int_0
-         %40 = OpLoad %float %38 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_float %35 %int_1
-               OpStore %41 %40 None
+         %25 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %28 = OpLoad %v3float %27 None
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %31 = OpLoad %v3float %30 None
+         %32 = OpVectorShuffle %v3float %31 %31 2 0 1
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_float %34 %uint_0
+         %37 = OpLoad %float %35 None
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %33 %uint_1
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %44
+%tint_store_and_preserve_padding = OpFunction %void None %41
 %value_param = OpFunctionParameter %mat2v3float
-         %45 = OpLabel
-         %46 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
-         %47 = OpCompositeExtract %v3float %value_param 0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
-         %49 = OpCompositeExtract %v3float %value_param 1
-               OpStore %48 %49 None
+         %42 = OpLabel
+         %43 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %44 = OpCompositeExtract %v3float %value_param 0
+               OpStore %43 %44 None
+         %45 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %46 = OpCompositeExtract %v3float %value_param 1
+               OpStore %45 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.glsl
index c4c8bec..acd7305 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.glsl
@@ -13,9 +13,9 @@
   }
   barrier();
   w = mat2x3(v.inner_col0, v.inner_col1);
-  w[1] = mat2x3(v.inner_col0, v.inner_col1)[0];
-  w[1] = mat2x3(v.inner_col0, v.inner_col1)[0].zxy;
-  w[0][1] = mat2x3(v.inner_col0, v.inner_col1)[1][0];
+  w[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u];
+  w[1u] = mat2x3(v.inner_col0, v.inner_col1)[0u].zxy;
+  w[0u][1u] = mat2x3(v.inner_col0, v.inner_col1)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 5f3b3d2..68a3e24 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 5f3b3d2..68a3e24 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
index 64dbf80..52a1b4c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -38,9 +38,9 @@
   float2x3 const v_2 = float2x3(v_1, float3(v[1u].packed));
   (*tint_module_vars.w)[0u].packed = packed_float3(v_2[0u]);
   (*tint_module_vars.w)[1u].packed = packed_float3(v_2[1u]);
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f32_array_element, 2>* u [[buffer(0)]], threadgroup tint_symbol_1* v_3 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
index 61dd745..8231ff3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,12 +43,9 @@
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %52 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -66,26 +63,26 @@
          %31 = OpLoad %v3float %30 None
          %32 = OpCompositeConstruct %mat2v3float %29 %31
                OpStore %w %32 None
-         %33 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %38 = OpLoad %v3float %37 None
-               OpStore %33 %38 None
-         %39 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %41 = OpLoad %v3float %40 None
-         %42 = OpVectorShuffle %v3float %41 %41 2 0 1
-               OpStore %39 %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_v3float %w %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %46 = OpAccessChain %_ptr_Uniform_float %45 %int_0
-         %48 = OpLoad %float %46 None
-         %49 = OpAccessChain %_ptr_Workgroup_float %43 %int_1
-               OpStore %49 %48 None
+         %33 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %36 = OpLoad %v3float %35 None
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %39 = OpLoad %v3float %38 None
+         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
+               OpStore %37 %40 None
+         %41 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_float %42 %uint_0
+         %45 = OpLoad %float %43 None
+         %46 = OpAccessChain %_ptr_Workgroup_float %41 %uint_1
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %52
-         %53 = OpLabel
-         %54 = OpLoad %uint %f_local_invocation_index_Input None
-         %55 = OpFunctionCall %void %f_inner %54
+          %f = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpLoad %uint %f_local_invocation_index_Input None
+         %52 = OpFunctionCall %void %f_inner %51
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 83da068..bb2456e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -26,7 +26,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 2, 4> l_m = m_load(0u);
-  const uint scalar_offset_2 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((8u * min(uint(p_m_i_save), 1u))) / 4;
   uint4 ubo_load_5 = m[scalar_offset_2 / 4];
   uint2 ubo_load_4 = ((scalar_offset_2 & 2) ? ubo_load_5.zw : ubo_load_5.xy);
   vector<float16_t, 2> ubo_load_4_xz = vector<float16_t, 2>(f16tof32(ubo_load_4 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 8b6eaca..74224e3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,5 +15,5 @@
 void main() {
   f16mat2x4 v_1 = f16mat2x4(v.inner_col0, v.inner_col1);
   f16mat2x4 l_m = v_1;
-  f16vec4 l_m_i = v_1[i()];
+  f16vec4 l_m_i = v_1[min(uint(i()), 1u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 88cc783..802c73b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -29,7 +29,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (8u * uint(i()));
+  uint v_8 = (8u * uint(min(uint(i()), 1u)));
   matrix<float16_t, 2, 4> l_m = v_4(0u);
   uint4 v_9 = m[(v_8 / 16u)];
   vector<float16_t, 4> l_m_i = tint_bitcast_to_f16((((((v_8 % 16u) / 4u) == 2u)) ? (v_9.zw) : (v_9.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 2afc726..b5ea618 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half2x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)]);
   half2x4 const l_m = (*p_m);
   half4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index b0c5224..0800172 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   half2x4 const l_m = *(tint_symbol_1);
   half4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 9476b57..6899370 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -62,7 +63,9 @@
         %l_m = OpCompositeConstruct %mat2v4half %25 %28
                OpStore %31 %l_m
          %33 = OpFunctionCall %int %i
-         %34 = OpAccessChain %_ptr_Function_v4half %31 %33
-      %l_m_i = OpLoad %v4half %34 None
+         %34 = OpBitcast %uint %33
+         %35 = OpExtInst %uint %36 UMin %34 %uint_1
+         %37 = OpAccessChain %_ptr_Function_v4half %31 %35
+      %l_m_i = OpLoad %v4half %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
index c4524f2..fbeeb47 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 void main() {
   f16mat2x4 v_1 = f16mat2x4(v.inner_col0, v.inner_col1);
   f16mat2x4 l_m = v_1;
-  f16vec4 l_m_1 = v_1[1];
+  f16vec4 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 4ec5c4d..2661d33 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half2x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half2x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_1 = (&(*p_m)[1]);
+  const constant half4* const p_m_1 = (&(*p_m)[1u]);
   half2x4 const l_m = (*p_m);
   half4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.glsl
index 2592923..7256351 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.glsl
@@ -9,6 +9,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat4x2 t = transpose(f16mat2x4(v.inner_col0, v.inner_col1));
-  float16_t l = length(f16mat2x4(v.inner_col0, v.inner_col1)[1]);
-  float16_t a = abs(f16mat2x4(v.inner_col0, v.inner_col1)[0].ywxz[0u]);
+  float16_t l = length(f16mat2x4(v.inner_col0, v.inner_col1)[1u]);
+  float16_t a = abs(f16mat2x4(v.inner_col0, v.inner_col1)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
index 601c793..e2f6f1b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half2x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half4x2 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.glsl
index 06c8818..9193a6a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.glsl
@@ -15,8 +15,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat2x4(v_1.inner_col0, v_1.inner_col1));
-  b(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1]);
-  b(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1].ywxz);
-  c(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1][0u]);
-  c(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1].ywxz[0u]);
+  b(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1u]);
+  b(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1u].ywxz);
+  c(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1u][0u]);
+  c(f16mat2x4(v_1.inner_col0, v_1.inner_col1)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.ir.msl
index 3340280..58d6d2c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half2x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.glsl
index fe9c3a1..ec79174 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat2x4(v.inner_col0, v.inner_col1);
-  p[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0];
-  p[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0].ywxz;
-  p[0][1] = f16mat2x4(v.inner_col0, v.inner_col1)[1][0];
+  p[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u];
+  p[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u].ywxz;
+  p[0u][1u] = f16mat2x4(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index bc98dfa..ee2e837 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -25,8 +25,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy);
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.msl
index 46e4fb5..46cbeb5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half2x4 p = half2x4(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.spvasm
index ff227b1..be327a7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -37,9 +37,6 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -50,20 +47,20 @@
          %21 = OpLoad %v4half %19 None
          %22 = OpCompositeConstruct %mat2v4half %18 %21
                OpStore %p %22 None
-         %23 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %27 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %28 = OpLoad %v4half %27 None
-               OpStore %23 %28 None
-         %29 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %31 = OpLoad %v4half %30 None
-         %32 = OpVectorShuffle %v4half %31 %31 1 3 0 2
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_Private_v4half %p %int_0
-         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %36 = OpAccessChain %_ptr_Uniform_half %35 %int_0
-         %38 = OpLoad %half %36 None
-         %39 = OpAccessChain %_ptr_Private_half %33 %int_1
-               OpStore %39 %38 None
+         %23 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %25 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %26 = OpLoad %v4half %25 None
+               OpStore %23 %26 None
+         %27 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %29 = OpLoad %v4half %28 None
+         %30 = OpVectorShuffle %v4half %29 %29 1 3 0 2
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_Private_v4half %p %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_half %32 %uint_0
+         %35 = OpLoad %half %33 None
+         %36 = OpAccessChain %_ptr_Private_half %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.glsl
index 2fb3dc1..4fe5fe2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.glsl
@@ -13,7 +13,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat2x4(v.inner_col0, v.inner_col1);
-  v_1.inner[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0];
-  v_1.inner[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0].ywxz;
-  v_1.inner[0][1] = f16mat2x4(v.inner_col0, v.inner_col1)[1][0];
+  v_1.inner[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u];
+  v_1.inner[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u].ywxz;
+  v_1.inner[0u][1u] = f16mat2x4(v.inner_col0, v.inner_col1)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.ir.msl
index bbe994e..6848ebf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half2x4* u [[buffer(0)]], device half2x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.spvasm
index fbce5a6..c2d62b2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -46,9 +46,6 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_mat2v4half = OpTypePointer StorageBuffer %mat2v4half
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -60,20 +57,20 @@
          %22 = OpCompositeConstruct %mat2v4half %18 %21
          %23 = OpAccessChain %_ptr_StorageBuffer_mat2v4half %6 %uint_0
                OpStore %23 %22 None
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %29 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %30 = OpLoad %v4half %29 None
-               OpStore %25 %30 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %33 = OpLoad %v4half %32 None
-         %34 = OpVectorShuffle %v4half %33 %33 1 3 0 2
-               OpStore %31 %34 None
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %38 = OpAccessChain %_ptr_Uniform_half %37 %int_0
-         %40 = OpLoad %half %38 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_half %35 %int_1
-               OpStore %41 %40 None
+         %25 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %27 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %28 = OpLoad %v4half %27 None
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %31 = OpLoad %v4half %30 None
+         %32 = OpVectorShuffle %v4half %31 %31 1 3 0 2
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_half %34 %uint_0
+         %37 = OpLoad %half %35 None
+         %38 = OpAccessChain %_ptr_StorageBuffer_half %33 %uint_1
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.glsl
index f483be7..72035f9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.glsl
@@ -13,9 +13,9 @@
   }
   barrier();
   w = f16mat2x4(v.inner_col0, v.inner_col1);
-  w[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0];
-  w[1] = f16mat2x4(v.inner_col0, v.inner_col1)[0].ywxz;
-  w[0][1] = f16mat2x4(v.inner_col0, v.inner_col1)[1][0];
+  w[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u];
+  w[1u] = f16mat2x4(v.inner_col0, v.inner_col1)[0u].ywxz;
+  w[0u][1u] = f16mat2x4(v.inner_col0, v.inner_col1)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 47ef6b5..59e92eb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -32,9 +32,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy);
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
index 7b1c517..5897ca1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half2x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
index ded851d..d5f0731 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -46,12 +46,9 @@
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %52 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -69,26 +66,26 @@
          %31 = OpLoad %v4half %30 None
          %32 = OpCompositeConstruct %mat2v4half %29 %31
                OpStore %w %32 None
-         %33 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %37 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %38 = OpLoad %v4half %37 None
-               OpStore %33 %38 None
-         %39 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %40 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %41 = OpLoad %v4half %40 None
-         %42 = OpVectorShuffle %v4half %41 %41 1 3 0 2
-               OpStore %39 %42 None
-         %43 = OpAccessChain %_ptr_Workgroup_v4half %w %int_0
-         %45 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %46 = OpAccessChain %_ptr_Uniform_half %45 %int_0
-         %48 = OpLoad %half %46 None
-         %49 = OpAccessChain %_ptr_Workgroup_half %43 %int_1
-               OpStore %49 %48 None
+         %33 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %36 = OpLoad %v4half %35 None
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %39 = OpLoad %v4half %38 None
+         %40 = OpVectorShuffle %v4half %39 %39 1 3 0 2
+               OpStore %37 %40 None
+         %41 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_0
+         %42 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_half %42 %uint_0
+         %45 = OpLoad %half %43 None
+         %46 = OpAccessChain %_ptr_Workgroup_half %41 %uint_1
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %52
-         %53 = OpLabel
-         %54 = OpLoad %uint %f_local_invocation_index_Input None
-         %55 = OpFunctionCall %void %f_inner %54
+          %f = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpLoad %uint %f_local_invocation_index_Input None
+         %52 = OpFunctionCall %void %f_inner %51
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 4b88dc7..5e0e783 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -18,7 +18,7 @@
 void f() {
   int p_m_i_save = i();
   float2x4 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((16u * min(uint(p_m_i_save), 1u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_2 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 4b88dc7..5e0e783 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -18,7 +18,7 @@
 void f() {
   int p_m_i_save = i();
   float2x4 l_m = m_load(0u);
-  const uint scalar_offset_2 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_2 = ((16u * min(uint(p_m_i_save), 1u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_2 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 2e737cb..566f493 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
+  uint v_1 = min(uint(i()), 1u);
   mat2x4 l_m = v.inner;
   vec4 l_m_i = v.inner[v_1];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 8033aed..f41ff5b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 1u)));
   float2x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 8033aed..f41ff5b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 1u)));
   float2x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 0d7e19b..5336fb2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float2x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 1u)]);
   float2x4 const l_m = (*p_m);
   float4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index a7299df..c836482 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 1u);
   float2x4 const l_m = *(tint_symbol_1);
   float4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 22b66c2..885aeb1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -40,6 +41,7 @@
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %i = OpFunction %int None %12
          %13 = OpLabel
@@ -53,7 +55,9 @@
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
          %26 = OpFunctionCall %int %i
-      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %26
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_1
+      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %28
         %l_m = OpLoad %mat2v4float %p_m None
       %l_m_i = OpLoad %v4float %p_m_i None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
index d6cd2af..cf4d81a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -7,5 +7,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 l_m = v.inner;
-  vec4 l_m_1 = v.inner[1];
+  vec4 l_m_1 = v.inner[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 101fdb7..a7221c6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float2x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float2x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_1 = (&(*p_m)[1]);
+  const constant float4* const p_m_1 = (&(*p_m)[1u]);
   float2x4 const l_m = (*p_m);
   float4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index 4dd30f2..dcacbee 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -41,6 +41,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+     %uint_1 = OpConstant %uint 1
           %i = OpFunction %int None %12
          %13 = OpLabel
          %14 = OpLoad %int %counter None
@@ -52,7 +53,7 @@
           %f = OpFunction %void None %20
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
-      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %int_1
+      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %uint_1
         %l_m = OpLoad %mat2v4float %p_m None
       %l_m_1 = OpLoad %v4float %p_m_1 None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.glsl
index b81580d..00779be 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat4x2 t = transpose(v.inner);
-  float l = length(v.inner[1]);
-  float a = abs(v.inner[0].ywxz[0u]);
+  float l = length(v.inner[1u]);
+  float a = abs(v.inner[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
index 96089cb..f391341 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float2x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float4x2 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.spvasm
index 578df41..55d562c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
-         %25 = OpExtInstImport "GLSL.std.450"
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -35,21 +35,19 @@
     %v2float = OpTypeVector %float 2
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
           %f = OpFunction %void None %9
          %10 = OpLabel
          %11 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
          %15 = OpLoad %mat2v4float %11 None
           %t = OpTranspose %mat4v2float %15
-         %19 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %23 = OpLoad %v4float %19 None
-          %l = OpExtInst %float %25 Length %23
-         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %28 = OpLoad %v4float %26 None
-         %29 = OpVectorShuffle %v4float %28 %28 1 3 0 2
-         %30 = OpCompositeExtract %float %29 0
-          %a = OpExtInst %float %25 FAbs %30
+         %19 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %22 = OpLoad %v4float %19 None
+          %l = OpExtInst %float %24 Length %22
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %26 = OpLoad %v4float %25 None
+         %27 = OpVectorShuffle %v4float %26 %26 1 3 0 2
+         %28 = OpCompositeExtract %float %27 0
+          %a = OpExtInst %float %24 FAbs %28
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.glsl
index 297dfdc..b443532 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.glsl
@@ -13,8 +13,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[1]);
-  b(v_1.inner[1].ywxz);
-  c(v_1.inner[1].x);
-  c(v_1.inner[1].ywxz[0u]);
+  b(v_1.inner[1u]);
+  b(v_1.inner[1u].ywxz);
+  c(v_1.inner[1u].x);
+  c(v_1.inner[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.ir.msl
index 01ad64c..a47b0b8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float2x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.spvasm
index b1989b7..a569957 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,8 +38,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
           %a = OpFunction %void None %10
           %m = OpFunctionParameter %mat2v4float
@@ -61,21 +60,21 @@
          %23 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
          %27 = OpLoad %mat2v4float %23 None
          %28 = OpFunctionCall %void %a %27
-         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpLoad %v4float %29 None
-         %34 = OpFunctionCall %void %b %33
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %36 = OpLoad %v4float %35 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-         %38 = OpFunctionCall %void %b %37
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpFunctionCall %void %c %42
-         %44 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %45 = OpLoad %v4float %44 None
-         %46 = OpVectorShuffle %v4float %45 %45 1 3 0 2
-         %47 = OpCompositeExtract %float %46 0
-         %48 = OpFunctionCall %void %c %47
+         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %32 = OpLoad %v4float %29 None
+         %33 = OpFunctionCall %void %b %32
+         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %35 = OpLoad %v4float %34 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+         %37 = OpFunctionCall %void %b %36
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpFunctionCall %void %c %41
+         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %v4float %43 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+         %46 = OpCompositeExtract %float %45 0
+         %47 = OpFunctionCall %void %c %46
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.glsl
index 0c26ef3..853d9c2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[0];
-  p[1] = v.inner[0].ywxz;
-  p[0][1] = v.inner[1].x;
+  p[1u] = v.inner[0u];
+  p[1u] = v.inner[0u].ywxz;
+  p[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 59bdb22..7babfd6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 59bdb22..7babfd6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.msl
index f551854..46e3a14 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float2x4 p = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.spvasm
index a296f3f..7b3037a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -33,10 +33,8 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -44,20 +42,20 @@
          %14 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
          %18 = OpLoad %mat2v4float %14 None
                OpStore %p %18 None
-         %19 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %26 = OpLoad %v4float %23 None
-               OpStore %19 %26 None
-         %27 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %29 = OpLoad %v4float %28 None
-         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
-               OpStore %27 %30 None
-         %31 = OpAccessChain %_ptr_Private_v4float %p %int_0
-         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpAccessChain %_ptr_Uniform_float %32 %int_0
-         %35 = OpLoad %float %33 None
-         %36 = OpAccessChain %_ptr_Private_float %31 %int_1
-               OpStore %36 %35 None
+         %19 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %22 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %24 = OpLoad %v4float %22 None
+               OpStore %19 %24 None
+         %25 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %27 = OpLoad %v4float %26 None
+         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_Private_v4float %p %uint_0
+         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_float %30 %uint_0
+         %33 = OpLoad %float %31 None
+         %34 = OpAccessChain %_ptr_Private_float %29 %uint_1
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.glsl
index 8247ee2..f427a1f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[0];
-  v_1.inner[1] = v.inner[0].ywxz;
-  v_1.inner[0][1] = v.inner[1].x;
+  v_1.inner[1u] = v.inner[0u];
+  v_1.inner[1u] = v.inner[0u].ywxz;
+  v_1.inner[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.ir.msl
index 6fcf8c6..8a2ce76 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float2x4* u [[buffer(0)]], device float2x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.spvasm
index 0f0e5c3..bb43197 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -42,10 +42,8 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_mat2v4float = OpTypePointer StorageBuffer %mat2v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -54,20 +52,20 @@
          %18 = OpLoad %mat2v4float %14 None
          %19 = OpAccessChain %_ptr_StorageBuffer_mat2v4float %7 %uint_0
                OpStore %19 %18 None
-         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %28 = OpLoad %v4float %25 None
-               OpStore %21 %28 None
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %31 = OpLoad %v4float %30 None
-         %32 = OpVectorShuffle %v4float %31 %31 1 3 0 2
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %34 %int_0
-         %37 = OpLoad %float %35 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %33 %int_1
-               OpStore %38 %37 None
+         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %24 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %26 = OpLoad %v4float %24 None
+               OpStore %21 %26 None
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %29 = OpLoad %v4float %28 None
+         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_float %32 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_float %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.glsl
index a1220c7..5019fc3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.glsl
@@ -11,9 +11,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[0];
-  w[1] = v.inner[0].ywxz;
-  w[0][1] = v.inner[1].x;
+  w[1u] = v.inner[0u];
+  w[1u] = v.inner[0u].ywxz;
+  w[0u][1u] = v.inner[1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 2d38c45..c1a7b4f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 2d38c45..c1a7b4f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
index 98586d3..3c70c39 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float2x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
index a41475b..4bca0db 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat2x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,13 +43,10 @@
 %_ptr_Uniform_mat2v4float = OpTypePointer Uniform %mat2v4float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %50 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -64,26 +61,26 @@
          %26 = OpAccessChain %_ptr_Uniform_mat2v4float %1 %uint_0
          %29 = OpLoad %mat2v4float %26 None
                OpStore %w %29 None
-         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %37 = OpLoad %v4float %34 None
-               OpStore %30 %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %40 = OpLoad %v4float %39 None
-         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
-               OpStore %38 %41 None
-         %42 = OpAccessChain %_ptr_Workgroup_v4float %w %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %44 = OpAccessChain %_ptr_Uniform_float %43 %int_0
-         %46 = OpLoad %float %44 None
-         %47 = OpAccessChain %_ptr_Workgroup_float %42 %int_1
-               OpStore %47 %46 None
+         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %34 = OpLoad %v4float %32 None
+               OpStore %30 %34 None
+         %35 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %37 = OpLoad %v4float %36 None
+         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
+         %43 = OpLoad %float %41 None
+         %44 = OpAccessChain %_ptr_Workgroup_float %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %50
-         %51 = OpLabel
-         %52 = OpLoad %uint %f_local_invocation_index_Input None
-         %53 = OpFunctionCall %void %f_inner %52
+          %f = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpLoad %uint %f_local_invocation_index_Input None
+         %50 = OpFunctionCall %void %f_inner %49
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 9032476..123d2f5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -22,7 +22,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 3, 2> l_m = m_load(0u);
-  const uint scalar_offset_3 = ((4u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((4u * min(uint(p_m_i_save), 2u))) / 4;
   uint ubo_load_3 = m[scalar_offset_3 / 4][scalar_offset_3 % 4];
   vector<float16_t, 2> l_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_3 & 0xFFFF)), float16_t(f16tof32(ubo_load_3 >> 16)));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 15b20e4..b11ca7d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -16,5 +16,5 @@
 void main() {
   f16mat3x2 v_1 = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3x2 l_m = v_1;
-  f16vec2 l_m_i = v_1[i()];
+  f16vec2 l_m_i = v_1[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 9213578..ac9e26f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -24,7 +24,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_5 = (4u * uint(i()));
+  uint v_5 = (4u * uint(min(uint(i()), 2u)));
   matrix<float16_t, 3, 2> l_m = v_2(0u);
   vector<float16_t, 2> l_m_i = tint_bitcast_to_f16(m[(v_5 / 16u)][((v_5 % 16u) / 4u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index ddb7409..e345d18 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half3x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)]);
   half3x2 const l_m = (*p_m);
   half2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 864db13..d775249 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   half3x2 const l_m = *(tint_symbol_1);
   half2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index dbccb4d..53588e8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -67,7 +68,9 @@
         %l_m = OpCompositeConstruct %mat3v2half %25 %28 %31
                OpStore %34 %l_m
          %36 = OpFunctionCall %int %i
-         %37 = OpAccessChain %_ptr_Function_v2half %34 %36
-      %l_m_i = OpLoad %v2half %37 None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %39 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Function_v2half %34 %38
+      %l_m_i = OpLoad %v2half %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 2f79647..53cce2a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 void main() {
   f16mat3x2 v_1 = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3x2 l_m = v_1;
-  f16vec2 l_m_1 = v_1[1];
+  f16vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index de3c21c..c52d279 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half3x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half3x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_1 = (&(*p_m)[1]);
+  const constant half2* const p_m_1 = (&(*p_m)[1u]);
   half3x2 const l_m = (*p_m);
   half2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.glsl
index 63bca65..ab21ce2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.glsl
@@ -10,6 +10,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat2x3 t = transpose(f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2));
-  float16_t l = length(f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1]);
-  float16_t a = abs(f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx[0u]);
+  float16_t l = length(f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u]);
+  float16_t a = abs(f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
index 28d2e92..b51b8ed 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half3x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half2x3 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.glsl
index 9128fa4..fd49ec8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.glsl
@@ -16,8 +16,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2));
-  b(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1]);
-  b(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].yx);
-  c(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1][0u]);
-  c(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].yx[0u]);
+  b(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u]);
+  b(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].yx);
+  c(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u][0u]);
+  c(f16mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.ir.msl
index d00561a..f1ef025 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half3x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.glsl
index 38a7580..ce767d8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  p[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  p[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  p[0][1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  p[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  p[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  p[0u][1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 95c273a..a4046a0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -20,8 +20,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_2(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  p[int(0)].y = float16_t(f16tof32(u[0u].y));
+  p[1u] = tint_bitcast_to_f16(u[0u].x);
+  p[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  p[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.msl
index 3412301..697110a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half3x2 p = half3x2(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.spvasm
index a5e2eef..c5c296b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -40,9 +40,6 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -55,20 +52,20 @@
          %24 = OpLoad %v2half %22 None
          %25 = OpCompositeConstruct %mat3v2half %18 %21 %24
                OpStore %p %25 None
-         %26 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %31 = OpLoad %v2half %30 None
-               OpStore %26 %31 None
-         %32 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %34 = OpLoad %v2half %33 None
-         %35 = OpVectorShuffle %v2half %34 %34 1 0
-               OpStore %32 %35 None
-         %36 = OpAccessChain %_ptr_Private_v2half %p %int_0
-         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_half %38 %int_0
-         %41 = OpLoad %half %39 None
-         %42 = OpAccessChain %_ptr_Private_half %36 %int_1
-               OpStore %42 %41 None
+         %26 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %29 = OpLoad %v2half %28 None
+               OpStore %26 %29 None
+         %30 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %32 = OpLoad %v2half %31 None
+         %33 = OpVectorShuffle %v2half %32 %32 1 0
+               OpStore %30 %33 None
+         %34 = OpAccessChain %_ptr_Private_v2half %p %uint_0
+         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_half %35 %uint_0
+         %38 = OpLoad %half %36 None
+         %39 = OpAccessChain %_ptr_Private_half %34 %uint_1
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.glsl
index c03ea444..97fe656 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.glsl
@@ -14,7 +14,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  v_1.inner[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  v_1.inner[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  v_1.inner[0][1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  v_1.inner[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  v_1.inner[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  v_1.inner[0u][1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.ir.msl
index e5a9482..c6d275f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half3x2* u [[buffer(0)]], device half3x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.spvasm
index 07c5086..4beac01 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -49,9 +49,6 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_mat3v2half = OpTypePointer StorageBuffer %mat3v2half
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -65,20 +62,20 @@
          %25 = OpCompositeConstruct %mat3v2half %18 %21 %24
          %26 = OpAccessChain %_ptr_StorageBuffer_mat3v2half %6 %uint_0
                OpStore %26 %25 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %33 = OpLoad %v2half %32 None
-               OpStore %28 %33 None
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %36 = OpLoad %v2half %35 None
-         %37 = OpVectorShuffle %v2half %36 %36 1 0
-               OpStore %34 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %41 = OpAccessChain %_ptr_Uniform_half %40 %int_0
-         %43 = OpLoad %half %41 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_half %38 %int_1
-               OpStore %44 %43 None
+         %28 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %31 = OpLoad %v2half %30 None
+               OpStore %28 %31 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %34 = OpLoad %v2half %33 None
+         %35 = OpVectorShuffle %v2half %34 %34 1 0
+               OpStore %32 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_half %37 %uint_0
+         %40 = OpLoad %half %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_half %36 %uint_1
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.glsl
index d28a5a2..d061887 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.glsl
@@ -14,9 +14,9 @@
   }
   barrier();
   w = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  w[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  w[1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  w[0][1] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  w[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  w[1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  w[0u][1u] = f16mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 548882d..98fd053 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -27,9 +27,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_2(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  w[int(0)].y = float16_t(f16tof32(u[0u].y));
+  w[1u] = tint_bitcast_to_f16(u[0u].x);
+  w[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  w[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
index b1f0e22..3775f3e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half3x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
index fd0e8bb..2fe8f7c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -48,12 +48,9 @@
 %_ptr_Uniform_v2half = OpTypePointer Uniform %v2half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %54 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -73,26 +70,26 @@
          %33 = OpLoad %v2half %32 None
          %34 = OpCompositeConstruct %mat3v2half %29 %31 %33
                OpStore %w %34 None
-         %35 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %40 = OpLoad %v2half %39 None
-               OpStore %35 %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %43 = OpLoad %v2half %42 None
-         %44 = OpVectorShuffle %v2half %43 %43 1 0
-               OpStore %41 %44 None
-         %45 = OpAccessChain %_ptr_Workgroup_v2half %w %int_0
-         %47 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %48 = OpAccessChain %_ptr_Uniform_half %47 %int_0
-         %50 = OpLoad %half %48 None
-         %51 = OpAccessChain %_ptr_Workgroup_half %45 %int_1
-               OpStore %51 %50 None
+         %35 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %38 = OpLoad %v2half %37 None
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %41 = OpLoad %v2half %40 None
+         %42 = OpVectorShuffle %v2half %41 %41 1 0
+               OpStore %39 %42 None
+         %43 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_0
+         %44 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %45 = OpAccessChain %_ptr_Uniform_half %44 %uint_0
+         %47 = OpLoad %half %45 None
+         %48 = OpAccessChain %_ptr_Workgroup_half %43 %uint_1
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpLoad %uint %f_local_invocation_index_Input None
-         %57 = OpFunctionCall %void %f_inner %56
+          %f = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpLoad %uint %f_local_invocation_index_Input None
+         %54 = OpFunctionCall %void %f_inner %53
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 7b39d8a..ca3679f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -22,7 +22,7 @@
 void f() {
   int p_m_i_save = i();
   float3x2 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((8u * min(uint(p_m_i_save), 2u))) / 4;
   uint4 ubo_load_3 = m[scalar_offset_3 / 4];
   float2 l_m_i = asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 7b39d8a..ca3679f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -22,7 +22,7 @@
 void f() {
   int p_m_i_save = i();
   float3x2 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((8u * min(uint(p_m_i_save), 2u))) / 4;
   uint4 ubo_load_3 = m[scalar_offset_3 / 4];
   float2 l_m_i = asfloat(((scalar_offset_3 & 2) ? ubo_load_3.zw : ubo_load_3.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index a3b7204..3a5136e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -15,5 +15,5 @@
 void main() {
   mat3x2 v_1 = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
   mat3x2 l_m = v_1;
-  vec2 l_m_i = v_1[i()];
+  vec2 l_m_i = v_1[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index f27e9ee..2fc0a22 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -19,7 +19,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_6 = (8u * uint(i()));
+  uint v_6 = (8u * uint(min(uint(i()), 2u)));
   float3x2 l_m = v(0u);
   uint4 v_7 = m[(v_6 / 16u)];
   float2 l_m_i = asfloat((((((v_6 % 16u) / 4u) == 2u)) ? (v_7.zw) : (v_7.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index f27e9ee..2fc0a22 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -19,7 +19,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_6 = (8u * uint(i()));
+  uint v_6 = (8u * uint(min(uint(i()), 2u)));
   float3x2 l_m = v(0u);
   uint4 v_7 = m[(v_6 / 16u)];
   float2 l_m_i = asfloat((((((v_6 % 16u) / 4u) == 2u)) ? (v_7.zw) : (v_7.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index d464543..df0f633 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float3x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)]);
   float3x2 const l_m = (*p_m);
   float2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index ed823d3..d0d00c5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   float3x2 const l_m = *(tint_symbol_1);
   float2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index e0da1162..fa1ce06 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -64,7 +65,9 @@
         %l_m = OpCompositeConstruct %mat3v2float %25 %28 %31
                OpStore %34 %l_m
          %36 = OpFunctionCall %int %i
-         %37 = OpAccessChain %_ptr_Function_v2float %34 %36
-      %l_m_i = OpLoad %v2float %37 None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %39 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Function_v2float %34 %38
+      %l_m_i = OpLoad %v2float %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
index bb25e71..c71fab7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 void main() {
   mat3x2 v_1 = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
   mat3x2 l_m = v_1;
-  vec2 l_m_1 = v_1[1];
+  vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 9188e96..c1aa531 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float3x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float3x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_1 = (&(*p_m)[1]);
+  const constant float2* const p_m_1 = (&(*p_m)[1u]);
   float3x2 const l_m = (*p_m);
   float2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.glsl
index a0ed4bd..13cabd6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.glsl
@@ -9,6 +9,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x3 t = transpose(mat3x2(v.inner_col0, v.inner_col1, v.inner_col2));
-  float l = length(mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1]);
-  float a = abs(mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx[0u]);
+  float l = length(mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u]);
+  float a = abs(mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
index ae1517b..c30b794 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float3x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float2x3 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.glsl
index d58458c..d39a0d8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.glsl
@@ -15,8 +15,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2));
-  b(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1]);
-  b(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].yx);
-  c(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1][0u]);
-  c(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].yx[0u]);
+  b(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u]);
+  b(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].yx);
+  c(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u][0u]);
+  c(mat3x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.ir.msl
index 4fd3154..98b3e5a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float3x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.glsl
index a1d2b51..ae34c7e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  p[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  p[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  p[0][1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  p[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  p[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  p[0u][1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 100e3ee..c6bbb59 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 100e3ee..c6bbb59 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.msl
index b749424..2ab9f76 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float3x2 p = float3x2(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.spvasm
index 85b4180..040b5bd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -37,9 +37,6 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -52,20 +49,20 @@
          %24 = OpLoad %v2float %22 None
          %25 = OpCompositeConstruct %mat3v2float %18 %21 %24
                OpStore %p %25 None
-         %26 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %31 = OpLoad %v2float %30 None
-               OpStore %26 %31 None
-         %32 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %34 = OpLoad %v2float %33 None
-         %35 = OpVectorShuffle %v2float %34 %34 1 0
-               OpStore %32 %35 None
-         %36 = OpAccessChain %_ptr_Private_v2float %p %int_0
-         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_float %38 %int_0
-         %41 = OpLoad %float %39 None
-         %42 = OpAccessChain %_ptr_Private_float %36 %int_1
-               OpStore %42 %41 None
+         %26 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %29 = OpLoad %v2float %28 None
+               OpStore %26 %29 None
+         %30 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %32 = OpLoad %v2float %31 None
+         %33 = OpVectorShuffle %v2float %32 %32 1 0
+               OpStore %30 %33 None
+         %34 = OpAccessChain %_ptr_Private_v2float %p %uint_0
+         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_float %35 %uint_0
+         %38 = OpLoad %float %36 None
+         %39 = OpAccessChain %_ptr_Private_float %34 %uint_1
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.glsl
index bfd8977..c6f74d9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.glsl
@@ -13,7 +13,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  v_1.inner[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  v_1.inner[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  v_1.inner[0][1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  v_1.inner[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  v_1.inner[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  v_1.inner[0u][1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.ir.msl
index e157c42..ca4205b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float3x2* u [[buffer(0)]], device float3x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.spvasm
index 962f517..320d7c5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -46,9 +46,6 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_mat3v2float = OpTypePointer StorageBuffer %mat3v2float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -62,20 +59,20 @@
          %25 = OpCompositeConstruct %mat3v2float %18 %21 %24
          %26 = OpAccessChain %_ptr_StorageBuffer_mat3v2float %6 %uint_0
                OpStore %26 %25 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %33 = OpLoad %v2float %32 None
-               OpStore %28 %33 None
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %36 = OpLoad %v2float %35 None
-         %37 = OpVectorShuffle %v2float %36 %36 1 0
-               OpStore %34 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %41 = OpAccessChain %_ptr_Uniform_float %40 %int_0
-         %43 = OpLoad %float %41 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_float %38 %int_1
-               OpStore %44 %43 None
+         %28 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %31 = OpLoad %v2float %30 None
+               OpStore %28 %31 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %34 = OpLoad %v2float %33 None
+         %35 = OpVectorShuffle %v2float %34 %34 1 0
+               OpStore %32 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_float %37 %uint_0
+         %40 = OpLoad %float %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %36 %uint_1
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.glsl
index d6c5391..b3dcda8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.glsl
@@ -13,9 +13,9 @@
   }
   barrier();
   w = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2);
-  w[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  w[1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0].yx;
-  w[0][1] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  w[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  w[1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[0u].yx;
+  w[0u][1u] = mat3x2(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 027cf5d..58d1577 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -22,9 +22,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 027cf5d..58d1577 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -22,9 +22,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
index 064aee3..76d4637 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float3x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
index 174b69d..e76d7a9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,12 +45,9 @@
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %54 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -70,26 +67,26 @@
          %33 = OpLoad %v2float %32 None
          %34 = OpCompositeConstruct %mat3v2float %29 %31 %33
                OpStore %w %34 None
-         %35 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %40 = OpLoad %v2float %39 None
-               OpStore %35 %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %43 = OpLoad %v2float %42 None
-         %44 = OpVectorShuffle %v2float %43 %43 1 0
-               OpStore %41 %44 None
-         %45 = OpAccessChain %_ptr_Workgroup_v2float %w %int_0
-         %47 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %48 = OpAccessChain %_ptr_Uniform_float %47 %int_0
-         %50 = OpLoad %float %48 None
-         %51 = OpAccessChain %_ptr_Workgroup_float %45 %int_1
-               OpStore %51 %50 None
+         %35 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %38 = OpLoad %v2float %37 None
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %41 = OpLoad %v2float %40 None
+         %42 = OpVectorShuffle %v2float %41 %41 1 0
+               OpStore %39 %42 None
+         %43 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_0
+         %44 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %45 = OpAccessChain %_ptr_Uniform_float %44 %uint_0
+         %47 = OpLoad %float %45 None
+         %48 = OpAccessChain %_ptr_Workgroup_float %43 %uint_1
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpLoad %uint %f_local_invocation_index_Input None
-         %57 = OpFunctionCall %void %f_inner %56
+          %f = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpLoad %uint %f_local_invocation_index_Input None
+         %54 = OpFunctionCall %void %f_inner %53
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 46d590d..7394edb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -31,7 +31,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 3, 3> l_m = m_load(0u);
-  const uint scalar_offset_3 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((8u * min(uint(p_m_i_save), 2u))) / 4;
   uint4 ubo_load_7 = m[scalar_offset_3 / 4];
   uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy);
   vector<float16_t, 2> ubo_load_6_xz = vector<float16_t, 2>(f16tof32(ubo_load_6 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 953aff2..164799c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -16,5 +16,5 @@
 void main() {
   f16mat3 v_1 = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3 l_m = v_1;
-  f16vec3 l_m_i = v_1[i()];
+  f16vec3 l_m_i = v_1[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index f438c1d..c930a33 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_10 = (8u * uint(i()));
+  uint v_10 = (8u * uint(min(uint(i()), 2u)));
   matrix<float16_t, 3, 3> l_m = v_4(0u);
   uint4 v_11 = m[(v_10 / 16u)];
   vector<float16_t, 3> l_m_i = tint_bitcast_to_f16((((((v_10 % 16u) / 4u) == 2u)) ? (v_11.zw) : (v_11.xy))).xyz;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index b68c821..c61be2e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f16_array_element, 3>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)].packed);
   tint_array<tint_packed_vec3_f16_array_element, 3> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index c6a61a1..57bbed5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   half3x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   half3 const l_m_i = half3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 633a9c2..e0d08b3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -67,7 +68,9 @@
         %l_m = OpCompositeConstruct %mat3v3half %25 %28 %31
                OpStore %34 %l_m
          %36 = OpFunctionCall %int %i
-         %37 = OpAccessChain %_ptr_Function_v3half %34 %36
-      %l_m_i = OpLoad %v3half %37 None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %39 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Function_v3half %34 %38
+      %l_m_i = OpLoad %v3half %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
index 549acf4..37feced 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 void main() {
   f16mat3 v_1 = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3 l_m = v_1;
-  f16vec3 l_m_1 = v_1[1];
+  f16vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 430d5f8..f61d301 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f16_array_element, 3>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f16_array_element, 3>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_half3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f16_array_element, 3> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.glsl
index d5ac65d..06bad24 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.glsl
@@ -10,6 +10,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat3 t = transpose(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2));
-  float16_t l = length(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1]);
-  float16_t a = abs(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy[0u]);
+  float16_t l = length(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u]);
+  float16_t a = abs(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
index 489aeaf..6f867ba 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -28,6 +28,6 @@
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   half3x3 const t = transpose(half3x3(v_1, v_2, half3(v[2u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[1].packed));
-  half const a = abs(half3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[1u].packed));
+  half const a = abs(half3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.glsl
index 065f0f7..f2114f6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.glsl
@@ -16,8 +16,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2));
-  b(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1]);
-  b(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].zxy);
-  c(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1][0u]);
-  c(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].zxy[0u]);
+  b(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u]);
+  b(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].zxy);
+  c(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u][0u]);
+  c(f16mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.ir.msl
index 8a6a9a2..247971e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_fn.wgsl.expected.ir.msl
@@ -37,8 +37,8 @@
   half3 const v_2 = half3(v_1[0u].packed);
   half3 const v_3 = half3(v_1[1u].packed);
   a(half3x3(v_2, v_3, half3(v_1[2u].packed)));
-  b(half3((*tint_module_vars.u)[1].packed));
-  b(half3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(half3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(half3((*tint_module_vars.u)[1u].packed));
+  b(half3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(half3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.glsl
index 7018c81..16f1e9c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2);
-  p[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  p[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  p[0][1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  p[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  p[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  p[0u][1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index ebaf8bc2..81342aa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -27,8 +27,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.msl
index d2710f2..b75e4d2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   (*tint_module_vars.p) = half3x3(v_1, v_2, half3(v[2u].packed));
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.spvasm
index 1f763c3..0f73b57 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -40,9 +40,6 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -55,20 +52,20 @@
          %24 = OpLoad %v3half %22 None
          %25 = OpCompositeConstruct %mat3v3half %18 %21 %24
                OpStore %p %25 None
-         %26 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %31 = OpLoad %v3half %30 None
-               OpStore %26 %31 None
-         %32 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %34 = OpLoad %v3half %33 None
-         %35 = OpVectorShuffle %v3half %34 %34 2 0 1
-               OpStore %32 %35 None
-         %36 = OpAccessChain %_ptr_Private_v3half %p %int_0
-         %38 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_half %38 %int_0
-         %41 = OpLoad %half %39 None
-         %42 = OpAccessChain %_ptr_Private_half %36 %int_1
-               OpStore %42 %41 None
+         %26 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %29 = OpLoad %v3half %28 None
+               OpStore %26 %29 None
+         %30 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %32 = OpLoad %v3half %31 None
+         %33 = OpVectorShuffle %v3half %32 %32 2 0 1
+               OpStore %30 %33 None
+         %34 = OpAccessChain %_ptr_Private_v3half %p %uint_0
+         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_half %35 %uint_0
+         %38 = OpLoad %half %36 None
+         %39 = OpAccessChain %_ptr_Private_half %34 %uint_1
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
index e96c14f..d76451f5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.glsl
@@ -19,7 +19,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(f16mat3(v.inner_col0, v.inner_col1, v.inner_col2));
-  v_1.inner[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  v_1.inner[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  v_1.inner[0][1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  v_1.inner[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  v_1.inner[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  v_1.inner[0u][1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.ir.msl
index d00e11b..1a12b8e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.ir.msl
@@ -35,7 +35,7 @@
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, half3x3(v_1, v_2, half3(v[2u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
index 42e7bed..ffb07c0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 55
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -50,12 +50,9 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %47 = OpTypeFunction %void %mat3v3half
+         %44 = OpTypeFunction %void %mat3v3half
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
@@ -66,34 +63,34 @@
          %24 = OpLoad %v3half %22 None
          %25 = OpCompositeConstruct %mat3v3half %18 %21 %24
          %26 = OpFunctionCall %void %tint_store_and_preserve_padding %25
-         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %33 = OpLoad %v3half %32 None
-               OpStore %28 %33 None
-         %34 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %36 = OpLoad %v3half %35 None
-         %37 = OpVectorShuffle %v3half %36 %36 2 0 1
-               OpStore %34 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %41 = OpAccessChain %_ptr_Uniform_half %40 %int_0
-         %43 = OpLoad %half %41 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_half %38 %int_1
-               OpStore %44 %43 None
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %31 = OpLoad %v3half %30 None
+               OpStore %28 %31 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %34 = OpLoad %v3half %33 None
+         %35 = OpVectorShuffle %v3half %34 %34 2 0 1
+               OpStore %32 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_half %37 %uint_0
+         %40 = OpLoad %half %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_half %36 %uint_1
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %47
+%tint_store_and_preserve_padding = OpFunction %void None %44
 %value_param = OpFunctionParameter %mat3v3half
-         %48 = OpLabel
-         %49 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
-         %50 = OpCompositeExtract %v3half %value_param 0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
-         %52 = OpCompositeExtract %v3half %value_param 1
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_2
-         %54 = OpCompositeExtract %v3half %value_param 2
-               OpStore %53 %54 None
+         %45 = OpLabel
+         %46 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %47 = OpCompositeExtract %v3half %value_param 0
+               OpStore %46 %47 None
+         %48 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %49 = OpCompositeExtract %v3half %value_param 1
+               OpStore %48 %49 None
+         %50 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_2
+         %51 = OpCompositeExtract %v3half %value_param 2
+               OpStore %50 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.glsl
index 697f7ba..1980066 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.glsl
@@ -14,9 +14,9 @@
   }
   barrier();
   w = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2);
-  w[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  w[1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  w[0][1] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  w[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  w[1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  w[0u][1u] = f16mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 0aa0257..a44f52d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
index e0eea63..2d93424 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -41,9 +41,9 @@
   (*tint_module_vars.w)[0u].packed = packed_half3(v_3[0u]);
   (*tint_module_vars.w)[1u].packed = packed_half3(v_3[1u]);
   (*tint_module_vars.w)[2u].packed = packed_half3(v_3[2u]);
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f16_array_element, 3>* u [[buffer(0)]], threadgroup tint_symbol_1* v_4 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
index 4ee3fd9..d9beea5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -48,12 +48,9 @@
 %_ptr_Uniform_v3half = OpTypePointer Uniform %v3half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %54 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -73,26 +70,26 @@
          %33 = OpLoad %v3half %32 None
          %34 = OpCompositeConstruct %mat3v3half %29 %31 %33
                OpStore %w %34 None
-         %35 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %40 = OpLoad %v3half %39 None
-               OpStore %35 %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %43 = OpLoad %v3half %42 None
-         %44 = OpVectorShuffle %v3half %43 %43 2 0 1
-               OpStore %41 %44 None
-         %45 = OpAccessChain %_ptr_Workgroup_v3half %w %int_0
-         %47 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %48 = OpAccessChain %_ptr_Uniform_half %47 %int_0
-         %50 = OpLoad %half %48 None
-         %51 = OpAccessChain %_ptr_Workgroup_half %45 %int_1
-               OpStore %51 %50 None
+         %35 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %38 = OpLoad %v3half %37 None
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %41 = OpLoad %v3half %40 None
+         %42 = OpVectorShuffle %v3half %41 %41 2 0 1
+               OpStore %39 %42 None
+         %43 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_0
+         %44 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %45 = OpAccessChain %_ptr_Uniform_half %44 %uint_0
+         %47 = OpLoad %half %45 None
+         %48 = OpAccessChain %_ptr_Workgroup_half %43 %uint_1
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpLoad %uint %f_local_invocation_index_Input None
-         %57 = OpFunctionCall %void %f_inner %56
+          %f = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpLoad %uint %f_local_invocation_index_Input None
+         %54 = OpFunctionCall %void %f_inner %53
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 49bc3d0..1226ce3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -19,7 +19,7 @@
 void f() {
   int p_m_i_save = i();
   float3x3 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((16u * min(uint(p_m_i_save), 2u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_3 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 49bc3d0..1226ce3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -19,7 +19,7 @@
 void f() {
   int p_m_i_save = i();
   float3x3 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((16u * min(uint(p_m_i_save), 2u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_3 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index eb73759..554813d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -17,5 +17,5 @@
 void main() {
   mat3 v_1 = mat3(v.inner_col0, v.inner_col1, v.inner_col2);
   mat3 l_m = v_1;
-  vec3 l_m_i = v_1[i()];
+  vec3 l_m_i = v_1[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index fad5437..b032288 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 2u)));
   float3x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index fad5437..b032288 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 2u)));
   float3x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 3ab8e87..1de71d7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)].packed);
   tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 7f0fce8..a440241 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   float3x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   float3 const l_m_i = float3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index efb8558..8656d3b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -64,7 +65,9 @@
         %l_m = OpCompositeConstruct %mat3v3float %25 %28 %31
                OpStore %34 %l_m
          %36 = OpFunctionCall %int %i
-         %37 = OpAccessChain %_ptr_Function_v3float %34 %36
-      %l_m_i = OpLoad %v3float %37 None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %39 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Function_v3float %34 %38
+      %l_m_i = OpLoad %v3float %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
index fa6d337..6a973e3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -12,5 +12,5 @@
 void main() {
   mat3 v_1 = mat3(v.inner_col0, v.inner_col1, v.inner_col2);
   mat3 l_m = v_1;
-  vec3 l_m_1 = v_1[1];
+  vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 229bff8..e7e1fe3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f32_array_element, 3>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f32_array_element, 3>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_float3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f32_array_element, 3> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.glsl
index 2161ccd..d4d673c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.glsl
@@ -11,6 +11,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3 t = transpose(mat3(v.inner_col0, v.inner_col1, v.inner_col2));
-  float l = length(mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1]);
-  float a = abs(mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy[0u]);
+  float l = length(mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u]);
+  float a = abs(mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
index 1ae7f21..a60d4e6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -28,6 +28,6 @@
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   float3x3 const t = transpose(float3x3(v_1, v_2, float3(v[2u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[1].packed));
-  float const a = abs(float3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[1u].packed));
+  float const a = abs(float3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.glsl
index 8e07636..38fd64f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.glsl
@@ -17,8 +17,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2));
-  b(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1]);
-  b(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].zxy);
-  c(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1][0u]);
-  c(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].zxy[0u]);
+  b(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u]);
+  b(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].zxy);
+  c(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u][0u]);
+  c(mat3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.ir.msl
index 435723d..ffef100 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_fn.wgsl.expected.ir.msl
@@ -37,8 +37,8 @@
   float3 const v_2 = float3(v_1[0u].packed);
   float3 const v_3 = float3(v_1[1u].packed);
   a(float3x3(v_2, v_3, float3(v_1[2u].packed)));
-  b(float3((*tint_module_vars.u)[1].packed));
-  b(float3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(float3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(float3((*tint_module_vars.u)[1u].packed));
+  b(float3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(float3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.glsl
index 06c7bee..aec39e0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat3(v.inner_col0, v.inner_col1, v.inner_col2);
-  p[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  p[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  p[0][1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  p[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  p[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  p[0u][1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 44e136b..d829f1b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 44e136b..d829f1b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.msl
index e2c680a..2d24211 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.ir.msl
@@ -30,7 +30,7 @@
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   (*tint_module_vars.p) = float3x3(v_1, v_2, float3(v[2u].packed));
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.spvasm
index 78788f9..6aa49be 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -37,9 +37,6 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -52,20 +49,20 @@
          %24 = OpLoad %v3float %22 None
          %25 = OpCompositeConstruct %mat3v3float %18 %21 %24
                OpStore %p %25 None
-         %26 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %31 = OpLoad %v3float %30 None
-               OpStore %26 %31 None
-         %32 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %34 = OpLoad %v3float %33 None
-         %35 = OpVectorShuffle %v3float %34 %34 2 0 1
-               OpStore %32 %35 None
-         %36 = OpAccessChain %_ptr_Private_v3float %p %int_0
-         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_float %38 %int_0
-         %41 = OpLoad %float %39 None
-         %42 = OpAccessChain %_ptr_Private_float %36 %int_1
-               OpStore %42 %41 None
+         %26 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %29 = OpLoad %v3float %28 None
+               OpStore %26 %29 None
+         %30 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %32 = OpLoad %v3float %31 None
+         %33 = OpVectorShuffle %v3float %32 %32 2 0 1
+               OpStore %30 %33 None
+         %34 = OpAccessChain %_ptr_Private_v3float %p %uint_0
+         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_float %35 %uint_0
+         %38 = OpLoad %float %36 None
+         %39 = OpAccessChain %_ptr_Private_float %34 %uint_1
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
index 1c008cf..15b1e8e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.glsl
@@ -20,7 +20,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(mat3(v.inner_col0, v.inner_col1, v.inner_col2));
-  v_1.inner[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  v_1.inner[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  v_1.inner[0][1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  v_1.inner[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  v_1.inner[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  v_1.inner[0u][1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.ir.msl
index dad0b4e..0254a20 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.ir.msl
@@ -35,7 +35,7 @@
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, float3x3(v_1, v_2, float3(v[2u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
index 750e835..4a1299e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 55
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -47,12 +47,9 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %47 = OpTypeFunction %void %mat3v3float
+         %44 = OpTypeFunction %void %mat3v3float
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
@@ -63,34 +60,34 @@
          %24 = OpLoad %v3float %22 None
          %25 = OpCompositeConstruct %mat3v3float %18 %21 %24
          %26 = OpFunctionCall %void %tint_store_and_preserve_padding %25
-         %28 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %33 = OpLoad %v3float %32 None
-               OpStore %28 %33 None
-         %34 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %36 = OpLoad %v3float %35 None
-         %37 = OpVectorShuffle %v3float %36 %36 2 0 1
-               OpStore %34 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %41 = OpAccessChain %_ptr_Uniform_float %40 %int_0
-         %43 = OpLoad %float %41 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_float %38 %int_1
-               OpStore %44 %43 None
+         %28 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %31 = OpLoad %v3float %30 None
+               OpStore %28 %31 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %34 = OpLoad %v3float %33 None
+         %35 = OpVectorShuffle %v3float %34 %34 2 0 1
+               OpStore %32 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_float %37 %uint_0
+         %40 = OpLoad %float %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %36 %uint_1
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %47
+%tint_store_and_preserve_padding = OpFunction %void None %44
 %value_param = OpFunctionParameter %mat3v3float
-         %48 = OpLabel
-         %49 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
-         %50 = OpCompositeExtract %v3float %value_param 0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
-         %52 = OpCompositeExtract %v3float %value_param 1
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_2
-         %54 = OpCompositeExtract %v3float %value_param 2
-               OpStore %53 %54 None
+         %45 = OpLabel
+         %46 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %47 = OpCompositeExtract %v3float %value_param 0
+               OpStore %46 %47 None
+         %48 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %49 = OpCompositeExtract %v3float %value_param 1
+               OpStore %48 %49 None
+         %50 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_2
+         %51 = OpCompositeExtract %v3float %value_param 2
+               OpStore %50 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.glsl
index 4dff45b..a106b20 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.glsl
@@ -15,9 +15,9 @@
   }
   barrier();
   w = mat3(v.inner_col0, v.inner_col1, v.inner_col2);
-  w[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  w[1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0].zxy;
-  w[0][1] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  w[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  w[1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[0u].zxy;
+  w[0u][1u] = mat3(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 388b62e..6678a9a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 388b62e..6678a9a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
index 7b90d40..42add18 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -41,9 +41,9 @@
   (*tint_module_vars.w)[0u].packed = packed_float3(v_3[0u]);
   (*tint_module_vars.w)[1u].packed = packed_float3(v_3[1u]);
   (*tint_module_vars.w)[2u].packed = packed_float3(v_3[2u]);
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f32_array_element, 3>* u [[buffer(0)]], threadgroup tint_symbol_1* v_4 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
index a19f5d8..280f9a2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -45,12 +45,9 @@
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %54 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -70,26 +67,26 @@
          %33 = OpLoad %v3float %32 None
          %34 = OpCompositeConstruct %mat3v3float %29 %31 %33
                OpStore %w %34 None
-         %35 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %40 = OpLoad %v3float %39 None
-               OpStore %35 %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %43 = OpLoad %v3float %42 None
-         %44 = OpVectorShuffle %v3float %43 %43 2 0 1
-               OpStore %41 %44 None
-         %45 = OpAccessChain %_ptr_Workgroup_v3float %w %int_0
-         %47 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %48 = OpAccessChain %_ptr_Uniform_float %47 %int_0
-         %50 = OpLoad %float %48 None
-         %51 = OpAccessChain %_ptr_Workgroup_float %45 %int_1
-               OpStore %51 %50 None
+         %35 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %38 = OpLoad %v3float %37 None
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %41 = OpLoad %v3float %40 None
+         %42 = OpVectorShuffle %v3float %41 %41 2 0 1
+               OpStore %39 %42 None
+         %43 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_0
+         %44 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %45 = OpAccessChain %_ptr_Uniform_float %44 %uint_0
+         %47 = OpLoad %float %45 None
+         %48 = OpAccessChain %_ptr_Workgroup_float %43 %uint_1
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpLoad %uint %f_local_invocation_index_Input None
-         %57 = OpFunctionCall %void %f_inner %56
+          %f = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpLoad %uint %f_local_invocation_index_Input None
+         %54 = OpFunctionCall %void %f_inner %53
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 8a1141c..1ae5046 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -31,7 +31,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 3, 4> l_m = m_load(0u);
-  const uint scalar_offset_3 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((8u * min(uint(p_m_i_save), 2u))) / 4;
   uint4 ubo_load_7 = m[scalar_offset_3 / 4];
   uint2 ubo_load_6 = ((scalar_offset_3 & 2) ? ubo_load_7.zw : ubo_load_7.xy);
   vector<float16_t, 2> ubo_load_6_xz = vector<float16_t, 2>(f16tof32(ubo_load_6 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index c7d9346..985459a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -16,5 +16,5 @@
 void main() {
   f16mat3x4 v_1 = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3x4 l_m = v_1;
-  f16vec4 l_m_i = v_1[i()];
+  f16vec4 l_m_i = v_1[min(uint(i()), 2u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 6a7d93d..ce303f4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_10 = (8u * uint(i()));
+  uint v_10 = (8u * uint(min(uint(i()), 2u)));
   matrix<float16_t, 3, 4> l_m = v_4(0u);
   uint4 v_11 = m[(v_10 / 16u)];
   vector<float16_t, 4> l_m_i = tint_bitcast_to_f16((((((v_10 % 16u) / 4u) == 2u)) ? (v_11.zw) : (v_11.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index af67891..3517d0f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half3x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)]);
   half3x4 const l_m = (*p_m);
   half4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index b858eb1..2c7f5dd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   half3x4 const l_m = *(tint_symbol_1);
   half4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 342cad0..b746ddc 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -67,7 +68,9 @@
         %l_m = OpCompositeConstruct %mat3v4half %25 %28 %31
                OpStore %34 %l_m
          %36 = OpFunctionCall %int %i
-         %37 = OpAccessChain %_ptr_Function_v4half %34 %36
-      %l_m_i = OpLoad %v4half %37 None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %39 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Function_v4half %34 %38
+      %l_m_i = OpLoad %v4half %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
index e092ecd..78605ff 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 void main() {
   f16mat3x4 v_1 = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2);
   f16mat3x4 l_m = v_1;
-  f16vec4 l_m_1 = v_1[1];
+  f16vec4 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 35d4780..931b81e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half3x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half3x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_1 = (&(*p_m)[1]);
+  const constant half4* const p_m_1 = (&(*p_m)[1u]);
   half3x4 const l_m = (*p_m);
   half4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.glsl
index 9a7457e0..bafbb24 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.glsl
@@ -10,6 +10,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat4x3 t = transpose(f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2));
-  float16_t l = length(f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1]);
-  float16_t a = abs(f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0].ywxz[0u]);
+  float16_t l = length(f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1u]);
+  float16_t a = abs(f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
index cf8b374..1e04e4c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half3x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half4x3 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.glsl
index d97799a..0385796 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.glsl
@@ -16,8 +16,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2));
-  b(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1]);
-  b(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].ywxz);
-  c(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1][0u]);
-  c(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1].ywxz[0u]);
+  b(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u]);
+  b(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].ywxz);
+  c(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u][0u]);
+  c(f16mat3x4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.ir.msl
index 6e9fa5d..0f88245 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half3x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.glsl
index daab961..814c6d2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2);
-  p[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  p[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0].ywxz;
-  p[0][1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  p[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  p[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u].ywxz;
+  p[0u][1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index a2d2a14..5e95de4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -27,8 +27,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy);
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.msl
index 91a6149..bcdb306 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half3x4 p = half3x4(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.spvasm
index 82b0456..4e75a2c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -40,9 +40,6 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -55,20 +52,20 @@
          %24 = OpLoad %v4half %22 None
          %25 = OpCompositeConstruct %mat3v4half %18 %21 %24
                OpStore %p %25 None
-         %26 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %31 = OpLoad %v4half %30 None
-               OpStore %26 %31 None
-         %32 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %34 = OpLoad %v4half %33 None
-         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
-               OpStore %32 %35 None
-         %36 = OpAccessChain %_ptr_Private_v4half %p %int_0
-         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %39 = OpAccessChain %_ptr_Uniform_half %38 %int_0
-         %41 = OpLoad %half %39 None
-         %42 = OpAccessChain %_ptr_Private_half %36 %int_1
-               OpStore %42 %41 None
+         %26 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %29 = OpLoad %v4half %28 None
+               OpStore %26 %29 None
+         %30 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %32 = OpLoad %v4half %31 None
+         %33 = OpVectorShuffle %v4half %32 %32 1 3 0 2
+               OpStore %30 %33 None
+         %34 = OpAccessChain %_ptr_Private_v4half %p %uint_0
+         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_half %35 %uint_0
+         %38 = OpLoad %half %36 None
+         %39 = OpAccessChain %_ptr_Private_half %34 %uint_1
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.glsl
index db0df73..e11f999 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.glsl
@@ -14,7 +14,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2);
-  v_1.inner[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  v_1.inner[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0].ywxz;
-  v_1.inner[0][1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  v_1.inner[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  v_1.inner[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u].ywxz;
+  v_1.inner[0u][1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.ir.msl
index 78b416f..b7e9471 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half3x4* u [[buffer(0)]], device half3x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.spvasm
index 9dabe28..57efa61 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -49,9 +49,6 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_mat3v4half = OpTypePointer StorageBuffer %mat3v4half
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -65,20 +62,20 @@
          %25 = OpCompositeConstruct %mat3v4half %18 %21 %24
          %26 = OpAccessChain %_ptr_StorageBuffer_mat3v4half %6 %uint_0
                OpStore %26 %25 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %32 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %33 = OpLoad %v4half %32 None
-               OpStore %28 %33 None
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %36 = OpLoad %v4half %35 None
-         %37 = OpVectorShuffle %v4half %36 %36 1 3 0 2
-               OpStore %34 %37 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_0
-         %40 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %41 = OpAccessChain %_ptr_Uniform_half %40 %int_0
-         %43 = OpLoad %half %41 None
-         %44 = OpAccessChain %_ptr_StorageBuffer_half %38 %int_1
-               OpStore %44 %43 None
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %30 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %31 = OpLoad %v4half %30 None
+               OpStore %28 %31 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %34 = OpLoad %v4half %33 None
+         %35 = OpVectorShuffle %v4half %34 %34 1 3 0 2
+               OpStore %32 %35 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %38 = OpAccessChain %_ptr_Uniform_half %37 %uint_0
+         %40 = OpLoad %half %38 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_half %36 %uint_1
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.glsl
index 4bd0b67..4f00f2b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.glsl
@@ -14,9 +14,9 @@
   }
   barrier();
   w = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2);
-  w[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0];
-  w[1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0].ywxz;
-  w[0][1] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1][0];
+  w[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u];
+  w[1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[0u].ywxz;
+  w[0u][1u] = f16mat3x4(v.inner_col0, v.inner_col1, v.inner_col2)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 87a62f8..a8329f1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -34,9 +34,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy);
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
index 0f6403f..f120731 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half3x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
index 47906ca..7d509aa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -48,12 +48,9 @@
 %_ptr_Uniform_v4half = OpTypePointer Uniform %v4half
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %54 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -73,26 +70,26 @@
          %33 = OpLoad %v4half %32 None
          %34 = OpCompositeConstruct %mat3v4half %29 %31 %33
                OpStore %w %34 None
-         %35 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %40 = OpLoad %v4half %39 None
-               OpStore %35 %40 None
-         %41 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %43 = OpLoad %v4half %42 None
-         %44 = OpVectorShuffle %v4half %43 %43 1 3 0 2
-               OpStore %41 %44 None
-         %45 = OpAccessChain %_ptr_Workgroup_v4half %w %int_0
-         %47 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %48 = OpAccessChain %_ptr_Uniform_half %47 %int_0
-         %50 = OpLoad %half %48 None
-         %51 = OpAccessChain %_ptr_Workgroup_half %45 %int_1
-               OpStore %51 %50 None
+         %35 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %37 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %38 = OpLoad %v4half %37 None
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %41 = OpLoad %v4half %40 None
+         %42 = OpVectorShuffle %v4half %41 %41 1 3 0 2
+               OpStore %39 %42 None
+         %43 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_0
+         %44 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %45 = OpAccessChain %_ptr_Uniform_half %44 %uint_0
+         %47 = OpLoad %half %45 None
+         %48 = OpAccessChain %_ptr_Workgroup_half %43 %uint_1
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpLoad %uint %f_local_invocation_index_Input None
-         %57 = OpFunctionCall %void %f_inner %56
+          %f = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpLoad %uint %f_local_invocation_index_Input None
+         %54 = OpFunctionCall %void %f_inner %53
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index f86af8f..d290e31 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -19,7 +19,7 @@
 void f() {
   int p_m_i_save = i();
   float3x4 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((16u * min(uint(p_m_i_save), 2u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_3 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index f86af8f..d290e31 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -19,7 +19,7 @@
 void f() {
   int p_m_i_save = i();
   float3x4 l_m = m_load(0u);
-  const uint scalar_offset_3 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_3 = ((16u * min(uint(p_m_i_save), 2u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_3 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 75509fa..127e6c6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
+  uint v_1 = min(uint(i()), 2u);
   mat3x4 l_m = v.inner;
   vec4 l_m_i = v.inner[v_1];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 37ecdb1..abca4e5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 2u)));
   float3x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 37ecdb1..abca4e5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 2u)));
   float3x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 55daaa0..b900ac7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float3x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 2u)]);
   float3x4 const l_m = (*p_m);
   float4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 0cc2a65..492e0d9 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 2u);
   float3x4 const l_m = *(tint_symbol_1);
   float4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 60d642c..6129daf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -40,6 +41,7 @@
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %i = OpFunction %int None %12
          %13 = OpLabel
@@ -53,7 +55,9 @@
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
          %26 = OpFunctionCall %int %i
-      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %26
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_2
+      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %28
         %l_m = OpLoad %mat3v4float %p_m None
       %l_m_i = OpLoad %v4float %p_m_i None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
index 0df7cb7..08eb79d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -7,5 +7,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3x4 l_m = v.inner;
-  vec4 l_m_1 = v.inner[1];
+  vec4 l_m_1 = v.inner[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 59010b3..fe9f7af 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float3x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float3x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_1 = (&(*p_m)[1]);
+  const constant float4* const p_m_1 = (&(*p_m)[1u]);
   float3x4 const l_m = (*p_m);
   float4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index e4dd970..03ca678 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -41,6 +41,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+     %uint_1 = OpConstant %uint 1
           %i = OpFunction %int None %12
          %13 = OpLabel
          %14 = OpLoad %int %counter None
@@ -52,7 +53,7 @@
           %f = OpFunction %void None %20
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
-      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %int_1
+      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %uint_1
         %l_m = OpLoad %mat3v4float %p_m None
       %l_m_1 = OpLoad %v4float %p_m_1 None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.glsl
index b56cc6c..76a8a9b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat4x3 t = transpose(v.inner);
-  float l = length(v.inner[1]);
-  float a = abs(v.inner[0].ywxz[0u]);
+  float l = length(v.inner[1u]);
+  float a = abs(v.inner[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
index d8aba95..b8bac12 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float3x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float4x3 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.spvasm
index f70c717..4853453 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
-         %25 = OpExtInstImport "GLSL.std.450"
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -35,21 +35,19 @@
     %v3float = OpTypeVector %float 3
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
           %f = OpFunction %void None %9
          %10 = OpLabel
          %11 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
          %15 = OpLoad %mat3v4float %11 None
           %t = OpTranspose %mat4v3float %15
-         %19 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %23 = OpLoad %v4float %19 None
-          %l = OpExtInst %float %25 Length %23
-         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %28 = OpLoad %v4float %26 None
-         %29 = OpVectorShuffle %v4float %28 %28 1 3 0 2
-         %30 = OpCompositeExtract %float %29 0
-          %a = OpExtInst %float %25 FAbs %30
+         %19 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %22 = OpLoad %v4float %19 None
+          %l = OpExtInst %float %24 Length %22
+         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %26 = OpLoad %v4float %25 None
+         %27 = OpVectorShuffle %v4float %26 %26 1 3 0 2
+         %28 = OpCompositeExtract %float %27 0
+          %a = OpExtInst %float %24 FAbs %28
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.glsl
index 3f77754..1581aa2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.glsl
@@ -13,8 +13,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[1]);
-  b(v_1.inner[1].ywxz);
-  c(v_1.inner[1].x);
-  c(v_1.inner[1].ywxz[0u]);
+  b(v_1.inner[1u]);
+  b(v_1.inner[1u].ywxz);
+  c(v_1.inner[1u].x);
+  c(v_1.inner[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.ir.msl
index 0b41b66..e9d7ec2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float3x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.spvasm
index c11b8b6..4dd572d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,8 +38,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
           %a = OpFunction %void None %10
           %m = OpFunctionParameter %mat3v4float
@@ -61,21 +60,21 @@
          %23 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
          %27 = OpLoad %mat3v4float %23 None
          %28 = OpFunctionCall %void %a %27
-         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpLoad %v4float %29 None
-         %34 = OpFunctionCall %void %b %33
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %36 = OpLoad %v4float %35 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-         %38 = OpFunctionCall %void %b %37
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpFunctionCall %void %c %42
-         %44 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %45 = OpLoad %v4float %44 None
-         %46 = OpVectorShuffle %v4float %45 %45 1 3 0 2
-         %47 = OpCompositeExtract %float %46 0
-         %48 = OpFunctionCall %void %c %47
+         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %32 = OpLoad %v4float %29 None
+         %33 = OpFunctionCall %void %b %32
+         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %35 = OpLoad %v4float %34 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+         %37 = OpFunctionCall %void %b %36
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpFunctionCall %void %c %41
+         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %v4float %43 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+         %46 = OpCompositeExtract %float %45 0
+         %47 = OpFunctionCall %void %c %46
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.glsl
index c2d51df..ad1bbb4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[0];
-  p[1] = v.inner[0].ywxz;
-  p[0][1] = v.inner[1].x;
+  p[1u] = v.inner[0u];
+  p[1u] = v.inner[0u].ywxz;
+  p[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index e1b225e..00a8aec 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index e1b225e..00a8aec 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.msl
index 6c42f57..770e922 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float3x4 p = float3x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.spvasm
index 84bc97e..70dceb8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -33,10 +33,8 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -44,20 +42,20 @@
          %14 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
          %18 = OpLoad %mat3v4float %14 None
                OpStore %p %18 None
-         %19 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %26 = OpLoad %v4float %23 None
-               OpStore %19 %26 None
-         %27 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %29 = OpLoad %v4float %28 None
-         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
-               OpStore %27 %30 None
-         %31 = OpAccessChain %_ptr_Private_v4float %p %int_0
-         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpAccessChain %_ptr_Uniform_float %32 %int_0
-         %35 = OpLoad %float %33 None
-         %36 = OpAccessChain %_ptr_Private_float %31 %int_1
-               OpStore %36 %35 None
+         %19 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %22 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %24 = OpLoad %v4float %22 None
+               OpStore %19 %24 None
+         %25 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %27 = OpLoad %v4float %26 None
+         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_Private_v4float %p %uint_0
+         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_float %30 %uint_0
+         %33 = OpLoad %float %31 None
+         %34 = OpAccessChain %_ptr_Private_float %29 %uint_1
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.glsl
index 436de28..701ba91 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[0];
-  v_1.inner[1] = v.inner[0].ywxz;
-  v_1.inner[0][1] = v.inner[1].x;
+  v_1.inner[1u] = v.inner[0u];
+  v_1.inner[1u] = v.inner[0u].ywxz;
+  v_1.inner[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.ir.msl
index d0941e3..a780ae2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float3x4* u [[buffer(0)]], device float3x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.spvasm
index 7eb9224..7ac248e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -42,10 +42,8 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_mat3v4float = OpTypePointer StorageBuffer %mat3v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -54,20 +52,20 @@
          %18 = OpLoad %mat3v4float %14 None
          %19 = OpAccessChain %_ptr_StorageBuffer_mat3v4float %7 %uint_0
                OpStore %19 %18 None
-         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %28 = OpLoad %v4float %25 None
-               OpStore %21 %28 None
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %31 = OpLoad %v4float %30 None
-         %32 = OpVectorShuffle %v4float %31 %31 1 3 0 2
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %34 %int_0
-         %37 = OpLoad %float %35 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %33 %int_1
-               OpStore %38 %37 None
+         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %24 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %26 = OpLoad %v4float %24 None
+               OpStore %21 %26 None
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %29 = OpLoad %v4float %28 None
+         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_float %32 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_float %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.glsl
index b73e948..5a79c26 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.glsl
@@ -11,9 +11,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[0];
-  w[1] = v.inner[0].ywxz;
-  w[0][1] = v.inner[1].x;
+  w[1u] = v.inner[0u];
+  w[1u] = v.inner[0u].ywxz;
+  w[0u][1u] = v.inner[1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 931c72e..c0a1c67 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 931c72e..c0a1c67 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
index 66a35fb..790d4fd4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float3x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
index 0effa98..7e425e1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat3x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,13 +43,10 @@
 %_ptr_Uniform_mat3v4float = OpTypePointer Uniform %mat3v4float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %50 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -64,26 +61,26 @@
          %26 = OpAccessChain %_ptr_Uniform_mat3v4float %1 %uint_0
          %29 = OpLoad %mat3v4float %26 None
                OpStore %w %29 None
-         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %37 = OpLoad %v4float %34 None
-               OpStore %30 %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %40 = OpLoad %v4float %39 None
-         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
-               OpStore %38 %41 None
-         %42 = OpAccessChain %_ptr_Workgroup_v4float %w %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %44 = OpAccessChain %_ptr_Uniform_float %43 %int_0
-         %46 = OpLoad %float %44 None
-         %47 = OpAccessChain %_ptr_Workgroup_float %42 %int_1
-               OpStore %47 %46 None
+         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %34 = OpLoad %v4float %32 None
+               OpStore %30 %34 None
+         %35 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %37 = OpLoad %v4float %36 None
+         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
+         %43 = OpLoad %float %41 None
+         %44 = OpAccessChain %_ptr_Workgroup_float %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %50
-         %51 = OpLabel
-         %52 = OpLoad %uint %f_local_invocation_index_Input None
-         %53 = OpFunctionCall %void %f_inner %52
+          %f = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpLoad %uint %f_local_invocation_index_Input None
+         %50 = OpFunctionCall %void %f_inner %49
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 334e721..705f8bd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -24,7 +24,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 4, 2> l_m = m_load(0u);
-  const uint scalar_offset_4 = ((4u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((4u * min(uint(p_m_i_save), 3u))) / 4;
   uint ubo_load_4 = m[scalar_offset_4 / 4][scalar_offset_4 % 4];
   vector<float16_t, 2> l_m_i = vector<float16_t, 2>(float16_t(f16tof32(ubo_load_4 & 0xFFFF)), float16_t(f16tof32(ubo_load_4 >> 16)));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 20bec84..2a94775 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -17,5 +17,5 @@
 void main() {
   f16mat4x2 v_1 = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4x2 l_m = v_1;
-  f16vec2 l_m_i = v_1[i()];
+  f16vec2 l_m_i = v_1[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index c388ebf..0bfc900 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -25,7 +25,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_6 = (4u * uint(i()));
+  uint v_6 = (4u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 2> l_m = v_2(0u);
   vector<float16_t, 2> l_m_i = tint_bitcast_to_f16(m[(v_6 / 16u)][((v_6 % 16u) / 4u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index c0c721a..3d68a87 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half4x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)]);
   half4x2 const l_m = (*p_m);
   half2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
index 11618f7..3aa5f3a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   half4x2 const l_m = *(tint_symbol_1);
   half2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index a489a94..b692f31 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,7 +73,9 @@
         %l_m = OpCompositeConstruct %mat4v2half %25 %28 %31 %34
                OpStore %37 %l_m
          %39 = OpFunctionCall %int %i
-         %40 = OpAccessChain %_ptr_Function_v2half %37 %39
-      %l_m_i = OpLoad %v2half %40 None
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %42 UMin %40 %uint_3
+         %43 = OpAccessChain %_ptr_Function_v2half %37 %41
+      %l_m_i = OpLoad %v2half %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
index 00601dc..1e5b7c2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -12,5 +12,5 @@
 void main() {
   f16mat4x2 v_1 = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4x2 l_m = v_1;
-  f16vec2 l_m_1 = v_1[1];
+  f16vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
index ad5a6cf..b020346 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half4x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half4x2* const p_m = tint_module_vars.m;
-  const constant half2* const p_m_1 = (&(*p_m)[1]);
+  const constant half2* const p_m_1 = (&(*p_m)[1u]);
   half4x2 const l_m = (*p_m);
   half2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.glsl
index 7cac479..09848fa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.glsl
@@ -11,6 +11,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat2x4 t = transpose(f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  float16_t l = length(f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1]);
-  float16_t a = abs(f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx[0u]);
+  float16_t l = length(f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u]);
+  float16_t a = abs(f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
index 4f6812b..3977fa1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half4x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half2x4 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.glsl
index e7da139..ab043cd 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.glsl
@@ -17,8 +17,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3));
-  b(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1]);
-  b(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].yx);
-  c(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1][0u]);
-  c(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].yx[0u]);
+  b(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u]);
+  b(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].yx);
+  c(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u][0u]);
+  c(f16mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.ir.msl
index 3677b13..0c4f866 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half4x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.glsl
index 3c176eb..c607e4e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  p[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  p[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  p[0][1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  p[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  p[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  p[0u][1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 5a108b9..898fe06 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -21,8 +21,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_2(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  p[int(0)].y = float16_t(f16tof32(u[0u].y));
+  p[1u] = tint_bitcast_to_f16(u[0u].x);
+  p[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  p[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.msl
index d08bea8..bfa7f2d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half4x2 p = half4x2(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.spvasm
index ca9adb8..708143a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -43,9 +43,6 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v2half = OpTypePointer Private %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -60,20 +57,20 @@
          %27 = OpLoad %v2half %25 None
          %28 = OpCompositeConstruct %mat4v2half %18 %21 %24 %27
                OpStore %p %28 None
-         %29 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %34 = OpLoad %v2half %33 None
-               OpStore %29 %34 None
-         %35 = OpAccessChain %_ptr_Private_v2half %p %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %37 = OpLoad %v2half %36 None
-         %38 = OpVectorShuffle %v2half %37 %37 1 0
-               OpStore %35 %38 None
-         %39 = OpAccessChain %_ptr_Private_v2half %p %int_0
-         %41 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %42 = OpAccessChain %_ptr_Uniform_half %41 %int_0
-         %44 = OpLoad %half %42 None
-         %45 = OpAccessChain %_ptr_Private_half %39 %int_1
-               OpStore %45 %44 None
+         %29 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %32 = OpLoad %v2half %31 None
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_Private_v2half %p %uint_1
+         %34 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %35 = OpLoad %v2half %34 None
+         %36 = OpVectorShuffle %v2half %35 %35 1 0
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Private_v2half %p %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_half %38 %uint_0
+         %41 = OpLoad %half %39 None
+         %42 = OpAccessChain %_ptr_Private_half %37 %uint_1
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.glsl
index f490576..2c58114 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.glsl
@@ -15,7 +15,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  v_1.inner[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  v_1.inner[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  v_1.inner[0][1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  v_1.inner[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  v_1.inner[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  v_1.inner[0u][1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.ir.msl
index f671069..33f0774 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half4x2* u [[buffer(0)]], device half4x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.spvasm
index 8f6e035..63d5684 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -52,9 +52,6 @@
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_mat4v2half = OpTypePointer StorageBuffer %mat4v2half
 %_ptr_StorageBuffer_v2half = OpTypePointer StorageBuffer %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -70,20 +67,20 @@
          %28 = OpCompositeConstruct %mat4v2half %18 %21 %24 %27
          %29 = OpAccessChain %_ptr_StorageBuffer_mat4v2half %6 %uint_0
                OpStore %29 %28 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %36 = OpLoad %v2half %35 None
-               OpStore %31 %36 None
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_1
-         %38 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %39 = OpLoad %v2half %38 None
-         %40 = OpVectorShuffle %v2half %39 %39 1 0
-               OpStore %37 %40 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %44 = OpAccessChain %_ptr_Uniform_half %43 %int_0
-         %46 = OpLoad %half %44 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_half %41 %int_1
-               OpStore %47 %46 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %34 = OpLoad %v2half %33 None
+               OpStore %31 %34 None
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %37 = OpLoad %v2half %36 None
+         %38 = OpVectorShuffle %v2half %37 %37 1 0
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_StorageBuffer_v2half %6 %uint_0 %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_half %40 %uint_0
+         %43 = OpLoad %half %41 None
+         %44 = OpAccessChain %_ptr_StorageBuffer_half %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.glsl
index 482b288..095b21a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.glsl
@@ -15,9 +15,9 @@
   }
   barrier();
   w = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  w[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  w[1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  w[0][1] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  w[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  w[1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  w[0u][1u] = f16mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 792e5a6..0548c7e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -28,9 +28,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_2(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].x).yx;
-  w[int(0)].y = float16_t(f16tof32(u[0u].y));
+  w[1u] = tint_bitcast_to_f16(u[0u].x);
+  w[1u] = tint_bitcast_to_f16(u[0u].x).yx;
+  w[0u].y = float16_t(f16tof32(u[0u].y));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
index 11fcbda..607249a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half4x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
index 2fce08c..ab6ac78 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -51,12 +51,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v2half = OpTypePointer Workgroup %v2half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %57 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -78,26 +75,26 @@
          %36 = OpLoad %v2half %34 None
          %37 = OpCompositeConstruct %mat4v2half %29 %31 %33 %36
                OpStore %w %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %43 = OpLoad %v2half %42 None
-               OpStore %38 %43 None
-         %44 = OpAccessChain %_ptr_Workgroup_v2half %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
-         %46 = OpLoad %v2half %45 None
-         %47 = OpVectorShuffle %v2half %46 %46 1 0
-               OpStore %44 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v2half %w %int_0
-         %50 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
-         %51 = OpAccessChain %_ptr_Uniform_half %50 %int_0
-         %53 = OpLoad %half %51 None
-         %54 = OpAccessChain %_ptr_Workgroup_half %48 %int_1
-               OpStore %54 %53 None
+         %38 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %41 = OpLoad %v2half %40 None
+               OpStore %38 %41 None
+         %42 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_0
+         %44 = OpLoad %v2half %43 None
+         %45 = OpVectorShuffle %v2half %44 %44 1 0
+               OpStore %42 %45 None
+         %46 = OpAccessChain %_ptr_Workgroup_v2half %w %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v2half %1 %uint_1
+         %48 = OpAccessChain %_ptr_Uniform_half %47 %uint_0
+         %50 = OpLoad %half %48 None
+         %51 = OpAccessChain %_ptr_Workgroup_half %46 %uint_1
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %58 = OpLabel
-         %59 = OpLoad %uint %f_local_invocation_index_Input None
-         %60 = OpFunctionCall %void %f_inner %59
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 8b39d78..41ce012 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -24,7 +24,7 @@
 void f() {
   int p_m_i_save = i();
   float4x2 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((8u * min(uint(p_m_i_save), 3u))) / 4;
   uint4 ubo_load_4 = m[scalar_offset_4 / 4];
   float2 l_m_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 8b39d78..41ce012 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -24,7 +24,7 @@
 void f() {
   int p_m_i_save = i();
   float4x2 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((8u * min(uint(p_m_i_save), 3u))) / 4;
   uint4 ubo_load_4 = m[scalar_offset_4 / 4];
   float2 l_m_i = asfloat(((scalar_offset_4 & 2) ? ubo_load_4.zw : ubo_load_4.xy));
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 329a764..1fea73b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -16,5 +16,5 @@
 void main() {
   mat4x2 v_1 = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   mat4x2 l_m = v_1;
-  vec2 l_m_i = v_1[i()];
+  vec2 l_m_i = v_1[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 4f071e1..4669399 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -21,7 +21,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (8u * uint(i()));
+  uint v_8 = (8u * uint(min(uint(i()), 3u)));
   float4x2 l_m = v(0u);
   uint4 v_9 = m[(v_8 / 16u)];
   float2 l_m_i = asfloat((((((v_8 % 16u) / 4u) == 2u)) ? (v_9.zw) : (v_9.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 4f071e1..4669399 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -21,7 +21,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_8 = (8u * uint(i()));
+  uint v_8 = (8u * uint(min(uint(i()), 3u)));
   float4x2 l_m = v(0u);
   uint4 v_9 = m[(v_8 / 16u)];
   float2 l_m_i = asfloat((((((v_8 % 16u) / 4u) == 2u)) ? (v_9.zw) : (v_9.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index be9a251..55ddcba 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float4x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float2* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)]);
   float4x2 const l_m = (*p_m);
   float2 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
index dd84081..7893fa7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   float4x2 const l_m = *(tint_symbol_1);
   float2 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 1910797..ec73bb5 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -69,7 +70,9 @@
         %l_m = OpCompositeConstruct %mat4v2float %25 %28 %31 %34
                OpStore %37 %l_m
          %39 = OpFunctionCall %int %i
-         %40 = OpAccessChain %_ptr_Function_v2float %37 %39
-      %l_m_i = OpLoad %v2float %40 None
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %42 UMin %40 %uint_3
+         %43 = OpAccessChain %_ptr_Function_v2float %37 %41
+      %l_m_i = OpLoad %v2float %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
index fa136dd..c861afb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 void main() {
   mat4x2 v_1 = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   mat4x2 l_m = v_1;
-  vec2 l_m_1 = v_1[1];
+  vec2 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 25e560c..607459c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float4x2* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float4x2* const p_m = tint_module_vars.m;
-  const constant float2* const p_m_1 = (&(*p_m)[1]);
+  const constant float2* const p_m_1 = (&(*p_m)[1u]);
   float4x2 const l_m = (*p_m);
   float2 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.glsl
index 618c969..7847a6e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.glsl
@@ -10,6 +10,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 t = transpose(mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  float l = length(mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1]);
-  float a = abs(mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx[0u]);
+  float l = length(mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u]);
+  float a = abs(mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
index f6b62d7..2dbd31b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float4x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float2x4 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].yx[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.glsl
index 65a0d80..71aea22 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.glsl
@@ -16,8 +16,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3));
-  b(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1]);
-  b(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].yx);
-  c(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1][0u]);
-  c(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].yx[0u]);
+  b(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u]);
+  b(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].yx);
+  c(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u][0u]);
+  c(mat4x2(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.ir.msl
index b10fca0..faff209 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float4x2* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].yx);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].yx[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].yx);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].yx[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.glsl
index b022ee8..6e7f840 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  p[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  p[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  p[0][1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  p[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  p[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  p[0u][1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 966eb00..71d2321 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -17,8 +17,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 966eb00..71d2321 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -17,8 +17,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xy);
-  p[int(1)] = asfloat(u[0u].xy).yx;
-  p[int(0)].y = asfloat(u[0u].z);
+  p[1u] = asfloat(u[0u].xy);
+  p[1u] = asfloat(u[0u].xy).yx;
+  p[0u].y = asfloat(u[0u].z);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.msl
index ce27593..548554b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float4x2 p = float4x2(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.spvasm
index 5f45e04..f992242 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -40,9 +40,6 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -57,20 +54,20 @@
          %27 = OpLoad %v2float %25 None
          %28 = OpCompositeConstruct %mat4v2float %18 %21 %24 %27
                OpStore %p %28 None
-         %29 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %34 = OpLoad %v2float %33 None
-               OpStore %29 %34 None
-         %35 = OpAccessChain %_ptr_Private_v2float %p %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %37 = OpLoad %v2float %36 None
-         %38 = OpVectorShuffle %v2float %37 %37 1 0
-               OpStore %35 %38 None
-         %39 = OpAccessChain %_ptr_Private_v2float %p %int_0
-         %41 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %42 = OpAccessChain %_ptr_Uniform_float %41 %int_0
-         %44 = OpLoad %float %42 None
-         %45 = OpAccessChain %_ptr_Private_float %39 %int_1
-               OpStore %45 %44 None
+         %29 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %32 = OpLoad %v2float %31 None
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_Private_v2float %p %uint_1
+         %34 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %35 = OpLoad %v2float %34 None
+         %36 = OpVectorShuffle %v2float %35 %35 1 0
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Private_v2float %p %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpAccessChain %_ptr_Private_float %37 %uint_1
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.glsl
index f1fd5c2..96982f1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.glsl
@@ -14,7 +14,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  v_1.inner[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  v_1.inner[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  v_1.inner[0][1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  v_1.inner[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  v_1.inner[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  v_1.inner[0u][1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.ir.msl
index 9382c4a..70517c1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float4x2* u [[buffer(0)]], device float4x2* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.spvasm
index 21d1277..d8d612b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -49,9 +49,6 @@
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_mat4v2float = OpTypePointer StorageBuffer %mat4v2float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -67,20 +64,20 @@
          %28 = OpCompositeConstruct %mat4v2float %18 %21 %24 %27
          %29 = OpAccessChain %_ptr_StorageBuffer_mat4v2float %6 %uint_0
                OpStore %29 %28 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %36 = OpLoad %v2float %35 None
-               OpStore %31 %36 None
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_1
-         %38 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %39 = OpLoad %v2float %38 None
-         %40 = OpVectorShuffle %v2float %39 %39 1 0
-               OpStore %37 %40 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %44 = OpAccessChain %_ptr_Uniform_float %43 %int_0
-         %46 = OpLoad %float %44 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_float %41 %int_1
-               OpStore %47 %46 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %34 = OpLoad %v2float %33 None
+               OpStore %31 %34 None
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %37 = OpLoad %v2float %36 None
+         %38 = OpVectorShuffle %v2float %37 %37 1 0
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
+         %43 = OpLoad %float %41 None
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.glsl
index 4431089..1f311fc 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.glsl
@@ -14,9 +14,9 @@
   }
   barrier();
   w = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  w[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  w[1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].yx;
-  w[0][1] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  w[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  w[1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].yx;
+  w[0u][1u] = mat4x2(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 380780f..b41e4c6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -24,9 +24,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 380780f..b41e4c6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -24,9 +24,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xy);
-  w[int(1)] = asfloat(u[0u].xy).yx;
-  w[int(0)].y = asfloat(u[0u].z);
+  w[1u] = asfloat(u[0u].xy);
+  w[1u] = asfloat(u[0u].xy).yx;
+  w[0u].y = asfloat(u[0u].z);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
index 4706982..6cf94e7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].yx;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].yx;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float4x2* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
index f4f505e..42bc05e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x2_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -48,12 +48,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %57 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -75,26 +72,26 @@
          %36 = OpLoad %v2float %34 None
          %37 = OpCompositeConstruct %mat4v2float %29 %31 %33 %36
                OpStore %w %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %43 = OpLoad %v2float %42 None
-               OpStore %38 %43 None
-         %44 = OpAccessChain %_ptr_Workgroup_v2float %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %46 = OpLoad %v2float %45 None
-         %47 = OpVectorShuffle %v2float %46 %46 1 0
-               OpStore %44 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v2float %w %int_0
-         %50 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
-         %51 = OpAccessChain %_ptr_Uniform_float %50 %int_0
-         %53 = OpLoad %float %51 None
-         %54 = OpAccessChain %_ptr_Workgroup_float %48 %int_1
-               OpStore %54 %53 None
+         %38 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %41 = OpLoad %v2float %40 None
+               OpStore %38 %41 None
+         %42 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
+         %44 = OpLoad %v2float %43 None
+         %45 = OpVectorShuffle %v2float %44 %44 1 0
+               OpStore %42 %45 None
+         %46 = OpAccessChain %_ptr_Workgroup_v2float %w %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_1
+         %48 = OpAccessChain %_ptr_Uniform_float %47 %uint_0
+         %50 = OpLoad %float %48 None
+         %51 = OpAccessChain %_ptr_Workgroup_float %46 %uint_1
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %58 = OpLabel
-         %59 = OpLoad %uint %f_local_invocation_index_Input None
-         %60 = OpFunctionCall %void %f_inner %59
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index aa00ead..46626f6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -36,7 +36,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 4, 3> l_m = m_load(0u);
-  const uint scalar_offset_4 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((8u * min(uint(p_m_i_save), 3u))) / 4;
   uint4 ubo_load_9 = m[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index 6bb5b0b..8f17a68 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -17,5 +17,5 @@
 void main() {
   f16mat4x3 v_1 = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4x3 l_m = v_1;
-  f16vec3 l_m_i = v_1[i()];
+  f16vec3 l_m_i = v_1[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 799812f..90bd93c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -33,7 +33,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (8u * uint(i()));
+  uint v_12 = (8u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 3> l_m = v_4(0u);
   uint4 v_13 = m[(v_12 / 16u)];
   vector<float16_t, 3> l_m_i = tint_bitcast_to_f16((((((v_12 % 16u) / 4u) == 2u)) ? (v_13.zw) : (v_13.xy))).xyz;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 9c9357f..2de5b93 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_half3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
index aac94fc..13ec545 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   half4x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   half3 const l_m_i = half3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index e4dd89e..befd937 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,7 +73,9 @@
         %l_m = OpCompositeConstruct %mat4v3half %25 %28 %31 %34
                OpStore %37 %l_m
          %39 = OpFunctionCall %int %i
-         %40 = OpAccessChain %_ptr_Function_v3half %37 %39
-      %l_m_i = OpLoad %v3half %40 None
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %42 UMin %40 %uint_3
+         %43 = OpAccessChain %_ptr_Function_v3half %37 %41
+      %l_m_i = OpLoad %v3half %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
index 2b638ce..e1edb1f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -12,5 +12,5 @@
 void main() {
   f16mat4x3 v_1 = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4x3 l_m = v_1;
-  f16vec3 l_m_1 = v_1[1];
+  f16vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 5f69499..dd0f73b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f16_array_element, 4>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f16_array_element, 4>* const p_m = tint_module_vars.m;
-  const constant packed_half3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_half3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f16_array_element, 4> const v = (*p_m);
   half3 const v_1 = half3(v[0u].packed);
   half3 const v_2 = half3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.glsl
index 440cada..c06cfbe 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.glsl
@@ -11,6 +11,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat3x4 t = transpose(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  float16_t l = length(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1]);
-  float16_t a = abs(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy[0u]);
+  float16_t l = length(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u]);
+  float16_t a = abs(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
index d684644..a9f26e4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_builtin.wgsl.expected.ir.msl
@@ -29,6 +29,6 @@
   half3 const v_2 = half3(v[1u].packed);
   half3 const v_3 = half3(v[2u].packed);
   half3x4 const t = transpose(half4x3(v_1, v_2, v_3, half3(v[3u].packed)));
-  half const l = length(half3((*tint_module_vars.u)[1].packed));
-  half const a = abs(half3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  half const l = length(half3((*tint_module_vars.u)[1u].packed));
+  half const a = abs(half3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.glsl
index 97e7872..a17a344 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.glsl
@@ -17,8 +17,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3));
-  b(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1]);
-  b(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].zxy);
-  c(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1][0u]);
-  c(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].zxy[0u]);
+  b(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u]);
+  b(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].zxy);
+  c(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u][0u]);
+  c(f16mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.ir.msl
index 09826f6..fd4db87 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_fn.wgsl.expected.ir.msl
@@ -38,8 +38,8 @@
   half3 const v_3 = half3(v_1[1u].packed);
   half3 const v_4 = half3(v_1[2u].packed);
   a(half4x3(v_2, v_3, v_4, half3(v_1[3u].packed)));
-  b(half3((*tint_module_vars.u)[1].packed));
-  b(half3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(half3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(half3((*tint_module_vars.u)[1u].packed));
+  b(half3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(half3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.glsl
index 1576475..61feacf 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  p[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  p[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  p[0][1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  p[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  p[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  p[0u][1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
index e694825..a0c29fb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -29,8 +29,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.msl
index 95d9e16..43e0c6b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   half3 const v_2 = half3(v[1u].packed);
   half3 const v_3 = half3(v[2u].packed);
   (*tint_module_vars.p) = half4x3(v_1, v_2, v_3, half3(v[3u].packed));
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = half3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = half3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.spvasm
index 84eed21..a84b923 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -43,9 +43,6 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v3half = OpTypePointer Private %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -60,20 +57,20 @@
          %27 = OpLoad %v3half %25 None
          %28 = OpCompositeConstruct %mat4v3half %18 %21 %24 %27
                OpStore %p %28 None
-         %29 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %34 = OpLoad %v3half %33 None
-               OpStore %29 %34 None
-         %35 = OpAccessChain %_ptr_Private_v3half %p %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %37 = OpLoad %v3half %36 None
-         %38 = OpVectorShuffle %v3half %37 %37 2 0 1
-               OpStore %35 %38 None
-         %39 = OpAccessChain %_ptr_Private_v3half %p %int_0
-         %41 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %42 = OpAccessChain %_ptr_Uniform_half %41 %int_0
-         %44 = OpLoad %half %42 None
-         %45 = OpAccessChain %_ptr_Private_half %39 %int_1
-               OpStore %45 %44 None
+         %29 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %32 = OpLoad %v3half %31 None
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_Private_v3half %p %uint_1
+         %34 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %35 = OpLoad %v3half %34 None
+         %36 = OpVectorShuffle %v3half %35 %35 2 0 1
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Private_v3half %p %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_half %38 %uint_0
+         %41 = OpLoad %half %39 None
+         %42 = OpAccessChain %_ptr_Private_half %37 %uint_1
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
index 70242ec..c6c22cb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.glsl
@@ -21,7 +21,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  v_1.inner[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  v_1.inner[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  v_1.inner[0][1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  v_1.inner[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  v_1.inner[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  v_1.inner[0u][1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.ir.msl
index 0f44cc1..905e0cb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.ir.msl
@@ -37,7 +37,7 @@
   half3 const v_2 = half3(v[1u].packed);
   half3 const v_3 = half3(v[2u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, half4x3(v_1, v_2, v_3, half3(v[3u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
index 6f74e65..57ac421 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 57
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -53,12 +53,9 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v3half = OpTypePointer StorageBuffer %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
-         %50 = OpTypeFunction %void %mat4v3half
+         %47 = OpTypeFunction %void %mat4v3half
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
@@ -71,37 +68,37 @@
          %27 = OpLoad %v3half %25 None
          %28 = OpCompositeConstruct %mat4v3half %18 %21 %24 %27
          %29 = OpFunctionCall %void %tint_store_and_preserve_padding %28
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %36 = OpLoad %v3half %35 None
-               OpStore %31 %36 None
-         %37 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_1
-         %38 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %39 = OpLoad %v3half %38 None
-         %40 = OpVectorShuffle %v3half %39 %39 2 0 1
-               OpStore %37 %40 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %44 = OpAccessChain %_ptr_Uniform_half %43 %int_0
-         %46 = OpLoad %half %44 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_half %41 %int_1
-               OpStore %47 %46 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %34 = OpLoad %v3half %33 None
+               OpStore %31 %34 None
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %37 = OpLoad %v3half %36 None
+         %38 = OpVectorShuffle %v3half %37 %37 2 0 1
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_half %40 %uint_0
+         %43 = OpLoad %half %41 None
+         %44 = OpAccessChain %_ptr_StorageBuffer_half %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %50
+%tint_store_and_preserve_padding = OpFunction %void None %47
 %value_param = OpFunctionParameter %mat4v3half
-         %51 = OpLabel
-         %52 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
-         %53 = OpCompositeExtract %v3half %value_param 0
-               OpStore %52 %53 None
-         %54 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
-         %55 = OpCompositeExtract %v3half %value_param 1
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_2
-         %57 = OpCompositeExtract %v3half %value_param 2
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_3
-         %59 = OpCompositeExtract %v3half %value_param 3
-               OpStore %58 %59 None
+         %48 = OpLabel
+         %49 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_0
+         %50 = OpCompositeExtract %v3half %value_param 0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_1
+         %52 = OpCompositeExtract %v3half %value_param 1
+               OpStore %51 %52 None
+         %53 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_2
+         %54 = OpCompositeExtract %v3half %value_param 2
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_StorageBuffer_v3half %6 %uint_0 %uint_3
+         %56 = OpCompositeExtract %v3half %value_param 3
+               OpStore %55 %56 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.glsl
index f2567d1..99dc152 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.glsl
@@ -15,9 +15,9 @@
   }
   barrier();
   w = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  w[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  w[1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  w[0][1] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  w[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  w[1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  w[0u][1u] = f16mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 6ed3117..b177e2a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -36,9 +36,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz;
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz;
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).xyz.zxy;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
index a55b467..6550d62 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.ir.msl
@@ -44,9 +44,9 @@
   (*tint_module_vars.w)[1u].packed = packed_half3(v_4[1u]);
   (*tint_module_vars.w)[2u].packed = packed_half3(v_4[2u]);
   (*tint_module_vars.w)[3u].packed = packed_half3(v_4[3u]);
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_half3(half3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_half3(half3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f16_array_element, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_5 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
index 195ede9..a89bf7e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -51,12 +51,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v3half = OpTypePointer Workgroup %v3half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %57 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -78,26 +75,26 @@
          %36 = OpLoad %v3half %34 None
          %37 = OpCompositeConstruct %mat4v3half %29 %31 %33 %36
                OpStore %w %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %43 = OpLoad %v3half %42 None
-               OpStore %38 %43 None
-         %44 = OpAccessChain %_ptr_Workgroup_v3half %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
-         %46 = OpLoad %v3half %45 None
-         %47 = OpVectorShuffle %v3half %46 %46 2 0 1
-               OpStore %44 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v3half %w %int_0
-         %50 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
-         %51 = OpAccessChain %_ptr_Uniform_half %50 %int_0
-         %53 = OpLoad %half %51 None
-         %54 = OpAccessChain %_ptr_Workgroup_half %48 %int_1
-               OpStore %54 %53 None
+         %38 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %41 = OpLoad %v3half %40 None
+               OpStore %38 %41 None
+         %42 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_0
+         %44 = OpLoad %v3half %43 None
+         %45 = OpVectorShuffle %v3half %44 %44 2 0 1
+               OpStore %42 %45 None
+         %46 = OpAccessChain %_ptr_Workgroup_v3half %w %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v3half %1 %uint_1
+         %48 = OpAccessChain %_ptr_Uniform_half %47 %uint_0
+         %50 = OpLoad %half %48 None
+         %51 = OpAccessChain %_ptr_Workgroup_half %46 %uint_1
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %58 = OpLabel
-         %59 = OpLoad %uint %f_local_invocation_index_Input None
-         %60 = OpFunctionCall %void %f_inner %59
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 77a9f49..b070772 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float4x3 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((16u * min(uint(p_m_i_save), 3u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_4 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index 77a9f49..b070772 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float4x3 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((16u * min(uint(p_m_i_save), 3u))) / 4;
   float3 l_m_i = asfloat(m[scalar_offset_4 / 4].xyz);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index 29d53c1..8a04114 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -19,5 +19,5 @@
 void main() {
   mat4x3 v_1 = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   mat4x3 l_m = v_1;
-  vec3 l_m_i = v_1[i()];
+  vec3 l_m_i = v_1[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index b75fcc2..18f2bf3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 3u)));
   float4x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index b75fcc2..18f2bf3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 3u)));
   float4x3 l_m = v(0u);
   float3 l_m_i = asfloat(m[(v_1 / 16u)].xyz);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 254ad839..cabc546 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_i = (&(*p_m)[i(tint_module_vars)].packed);
+  const constant packed_float3* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)].packed);
   tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 5a4be96..f5e0e75 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -37,7 +37,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   float4x3 const l_m = tint_unpack_vec3_in_composite(*(tint_symbol_1));
   float3 const l_m_i = float3((*(tint_symbol_1))[p_m_i_save].elements);
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index 49d0a62..5dda853 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -69,7 +70,9 @@
         %l_m = OpCompositeConstruct %mat4v3float %25 %28 %31 %34
                OpStore %37 %l_m
          %39 = OpFunctionCall %int %i
-         %40 = OpAccessChain %_ptr_Function_v3float %37 %39
-      %l_m_i = OpLoad %v3float %40 None
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %42 UMin %40 %uint_3
+         %43 = OpAccessChain %_ptr_Function_v3float %37 %41
+      %l_m_i = OpLoad %v3float %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
index a8ffb67..436e9ef 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -14,5 +14,5 @@
 void main() {
   mat4x3 v_1 = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   mat4x3 l_m = v_1;
-  vec3 l_m_1 = v_1[1];
+  vec3 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
index 1ef4dd9..2b8e474 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 kernel void f(const constant tint_array<tint_packed_vec3_f32_array_element, 4>* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant tint_array<tint_packed_vec3_f32_array_element, 4>* const p_m = tint_module_vars.m;
-  const constant packed_float3* const p_m_1 = (&(*p_m)[1].packed);
+  const constant packed_float3* const p_m_1 = (&(*p_m)[1u].packed);
   tint_array<tint_packed_vec3_f32_array_element, 4> const v = (*p_m);
   float3 const v_1 = float3(v[0u].packed);
   float3 const v_2 = float3(v[1u].packed);
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.glsl
index c39b9e1..195ba37 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3x4 t = transpose(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  float l = length(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1]);
-  float a = abs(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy[0u]);
+  float l = length(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u]);
+  float a = abs(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
index 388e3d0..a99b224 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_builtin.wgsl.expected.ir.msl
@@ -29,6 +29,6 @@
   float3 const v_2 = float3(v[1u].packed);
   float3 const v_3 = float3(v[2u].packed);
   float3x4 const t = transpose(float4x3(v_1, v_2, v_3, float3(v[3u].packed)));
-  float const l = length(float3((*tint_module_vars.u)[1].packed));
-  float const a = abs(float3((*tint_module_vars.u)[0].packed).zxy[0u]);
+  float const l = length(float3((*tint_module_vars.u)[1u].packed));
+  float const a = abs(float3((*tint_module_vars.u)[0u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.glsl
index 13a0c86..5b83f71 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.glsl
@@ -19,8 +19,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3));
-  b(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1]);
-  b(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].zxy);
-  c(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1][0u]);
-  c(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].zxy[0u]);
+  b(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u]);
+  b(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].zxy);
+  c(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u][0u]);
+  c(mat4x3(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.ir.msl
index 4bd3b75..ce11f2b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_fn.wgsl.expected.ir.msl
@@ -38,8 +38,8 @@
   float3 const v_3 = float3(v_1[1u].packed);
   float3 const v_4 = float3(v_1[2u].packed);
   a(float4x3(v_2, v_3, v_4, float3(v_1[3u].packed)));
-  b(float3((*tint_module_vars.u)[1].packed));
-  b(float3((*tint_module_vars.u)[1].packed).zxy);
-  c((*tint_module_vars.u)[1].packed[0u]);
-  c(float3((*tint_module_vars.u)[1].packed).zxy[0u]);
+  b(float3((*tint_module_vars.u)[1u].packed));
+  b(float3((*tint_module_vars.u)[1u].packed).zxy);
+  c((*tint_module_vars.u)[1u].packed[0u]);
+  c(float3((*tint_module_vars.u)[1u].packed).zxy[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.glsl
index 95f5303..3879a21 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.glsl
@@ -14,7 +14,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  p[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  p[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  p[0][1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  p[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  p[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  p[0u][1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 1e57a99..0890f21 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 1e57a99..0890f21 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u].xyz);
-  p[int(1)] = asfloat(u[0u].xyz).zxy;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u].xyz);
+  p[1u] = asfloat(u[0u].xyz).zxy;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.msl
index 0f2d76e..9c794d8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
   float3 const v_2 = float3(v[1u].packed);
   float3 const v_3 = float3(v[2u].packed);
   (*tint_module_vars.p) = float4x3(v_1, v_2, v_3, float3(v[3u].packed));
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed);
-  (*tint_module_vars.p)[1] = float3((*tint_module_vars.u)[0].packed).zxy;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed);
+  (*tint_module_vars.p)[1u] = float3((*tint_module_vars.u)[0u].packed).zxy;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.spvasm
index 817fcf1..465eeb3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -40,9 +40,6 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v3float = OpTypePointer Private %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -57,20 +54,20 @@
          %27 = OpLoad %v3float %25 None
          %28 = OpCompositeConstruct %mat4v3float %18 %21 %24 %27
                OpStore %p %28 None
-         %29 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %34 = OpLoad %v3float %33 None
-               OpStore %29 %34 None
-         %35 = OpAccessChain %_ptr_Private_v3float %p %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %37 = OpLoad %v3float %36 None
-         %38 = OpVectorShuffle %v3float %37 %37 2 0 1
-               OpStore %35 %38 None
-         %39 = OpAccessChain %_ptr_Private_v3float %p %int_0
-         %41 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %42 = OpAccessChain %_ptr_Uniform_float %41 %int_0
-         %44 = OpLoad %float %42 None
-         %45 = OpAccessChain %_ptr_Private_float %39 %int_1
-               OpStore %45 %44 None
+         %29 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %32 = OpLoad %v3float %31 None
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_Private_v3float %p %uint_1
+         %34 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %35 = OpLoad %v3float %34 None
+         %36 = OpVectorShuffle %v3float %35 %35 2 0 1
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Private_v3float %p %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpAccessChain %_ptr_Private_float %37 %uint_1
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
index b3f0149..8c402ea 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.glsl
@@ -23,7 +23,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_store_and_preserve_padding(mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  v_1.inner[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  v_1.inner[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  v_1.inner[0][1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  v_1.inner[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  v_1.inner[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  v_1.inner[0u][1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.ir.msl
index eda7457..653cee8 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.ir.msl
@@ -37,7 +37,7 @@
   float3 const v_2 = float3(v[1u].packed);
   float3 const v_3 = float3(v[2u].packed);
   tint_store_and_preserve_padding(tint_module_vars.s, float4x3(v_1, v_2, v_3, float3(v[3u].packed)));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.s)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.s)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.s)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.s)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
index 33d66da..83bf288 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 57
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -50,12 +50,9 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %50 = OpTypeFunction %void %mat4v3float
+         %47 = OpTypeFunction %void %mat4v3float
           %f = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
@@ -68,37 +65,37 @@
          %27 = OpLoad %v3float %25 None
          %28 = OpCompositeConstruct %mat4v3float %18 %21 %24 %27
          %29 = OpFunctionCall %void %tint_store_and_preserve_padding %28
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %36 = OpLoad %v3float %35 None
-               OpStore %31 %36 None
-         %37 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_1
-         %38 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %39 = OpLoad %v3float %38 None
-         %40 = OpVectorShuffle %v3float %39 %39 2 0 1
-               OpStore %37 %40 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %44 = OpAccessChain %_ptr_Uniform_float %43 %int_0
-         %46 = OpLoad %float %44 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_float %41 %int_1
-               OpStore %47 %46 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %34 = OpLoad %v3float %33 None
+               OpStore %31 %34 None
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %37 = OpLoad %v3float %36 None
+         %38 = OpVectorShuffle %v3float %37 %37 2 0 1
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
+         %43 = OpLoad %float %41 None
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %50
+%tint_store_and_preserve_padding = OpFunction %void None %47
 %value_param = OpFunctionParameter %mat4v3float
-         %51 = OpLabel
-         %52 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
-         %53 = OpCompositeExtract %v3float %value_param 0
-               OpStore %52 %53 None
-         %54 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
-         %55 = OpCompositeExtract %v3float %value_param 1
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_2
-         %57 = OpCompositeExtract %v3float %value_param 2
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_3
-         %59 = OpCompositeExtract %v3float %value_param 3
-               OpStore %58 %59 None
+         %48 = OpLabel
+         %49 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_0
+         %50 = OpCompositeExtract %v3float %value_param 0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_1
+         %52 = OpCompositeExtract %v3float %value_param 1
+               OpStore %51 %52 None
+         %53 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_2
+         %54 = OpCompositeExtract %v3float %value_param 2
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_StorageBuffer_v3float %6 %uint_0 %uint_3
+         %56 = OpCompositeExtract %v3float %value_param 3
+               OpStore %55 %56 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.glsl
index ec98e9b..a182bd3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.glsl
@@ -17,9 +17,9 @@
   }
   barrier();
   w = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  w[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  w[1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].zxy;
-  w[0][1] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  w[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  w[1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].zxy;
+  w[0u][1u] = mat4x3(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 643dded..5f9cfa6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 643dded..5f9cfa6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u].xyz);
-  w[int(1)] = asfloat(u[0u].xyz).zxy;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u].xyz);
+  w[1u] = asfloat(u[0u].xyz).zxy;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
index 5184bae..afbcbc1 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.ir.msl
@@ -44,9 +44,9 @@
   (*tint_module_vars.w)[1u].packed = packed_float3(v_4[1u]);
   (*tint_module_vars.w)[2u].packed = packed_float3(v_4[2u]);
   (*tint_module_vars.w)[3u].packed = packed_float3(v_4[3u]);
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed));
-  (*tint_module_vars.w)[1].packed = packed_float3(float3((*tint_module_vars.u)[0].packed).zxy);
-  (*tint_module_vars.w)[0].packed[1] = (*tint_module_vars.u)[1].packed[0];
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed));
+  (*tint_module_vars.w)[1u].packed = packed_float3(float3((*tint_module_vars.u)[0u].packed).zxy);
+  (*tint_module_vars.w)[0u].packed[1u] = (*tint_module_vars.u)[1u].packed[0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant tint_array<tint_packed_vec3_f32_array_element, 4>* u [[buffer(0)]], threadgroup tint_symbol_1* v_5 [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
index a0fd871..432dcae 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x3_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -48,12 +48,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v3float = OpTypePointer Workgroup %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %57 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -75,26 +72,26 @@
          %36 = OpLoad %v3float %34 None
          %37 = OpCompositeConstruct %mat4v3float %29 %31 %33 %36
                OpStore %w %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %43 = OpLoad %v3float %42 None
-               OpStore %38 %43 None
-         %44 = OpAccessChain %_ptr_Workgroup_v3float %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
-         %46 = OpLoad %v3float %45 None
-         %47 = OpVectorShuffle %v3float %46 %46 2 0 1
-               OpStore %44 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v3float %w %int_0
-         %50 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
-         %51 = OpAccessChain %_ptr_Uniform_float %50 %int_0
-         %53 = OpLoad %float %51 None
-         %54 = OpAccessChain %_ptr_Workgroup_float %48 %int_1
-               OpStore %54 %53 None
+         %38 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %41 = OpLoad %v3float %40 None
+               OpStore %38 %41 None
+         %42 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_0
+         %44 = OpLoad %v3float %43 None
+         %45 = OpVectorShuffle %v3float %44 %44 2 0 1
+               OpStore %42 %45 None
+         %46 = OpAccessChain %_ptr_Workgroup_v3float %w %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v3float %1 %uint_1
+         %48 = OpAccessChain %_ptr_Uniform_float %47 %uint_0
+         %50 = OpLoad %float %48 None
+         %51 = OpAccessChain %_ptr_Workgroup_float %46 %uint_1
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %58 = OpLabel
-         %59 = OpLoad %uint %f_local_invocation_index_Input None
-         %60 = OpFunctionCall %void %f_inner %59
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index 5b9017b..b6aa580 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -36,7 +36,7 @@
 void f() {
   int p_m_i_save = i();
   matrix<float16_t, 4, 4> l_m = m_load(0u);
-  const uint scalar_offset_4 = ((8u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((8u * min(uint(p_m_i_save), 3u))) / 4;
   uint4 ubo_load_9 = m[scalar_offset_4 / 4];
   uint2 ubo_load_8 = ((scalar_offset_4 & 2) ? ubo_load_9.zw : ubo_load_9.xy);
   vector<float16_t, 2> ubo_load_8_xz = vector<float16_t, 2>(f16tof32(ubo_load_8 & 0xFFFF));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
index e74dacf..c565af0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -17,5 +17,5 @@
 void main() {
   f16mat4 v_1 = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4 l_m = v_1;
-  f16vec4 l_m_i = v_1[i()];
+  f16vec4 l_m_i = v_1[min(uint(i()), 3u)];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index f5a1a64..e3f325d 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -33,7 +33,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_12 = (8u * uint(i()));
+  uint v_12 = (8u * uint(min(uint(i()), 3u)));
   matrix<float16_t, 4, 4> l_m = v_4(0u);
   uint4 v_13 = m[(v_12 / 16u)];
   vector<float16_t, 4> l_m_i = tint_bitcast_to_f16((((((v_12 % 16u) / 4u) == 2u)) ? (v_13.zw) : (v_13.xy)));
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
index 7dc67e4..86cd236 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant half4x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant half4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)]);
   half4x4 const l_m = (*p_m);
   half4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
index a84f36d..5d5f94b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   half4x4 const l_m = *(tint_symbol_1);
   half4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
index 100224c..9c41614 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,12 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
                OpCapability UniformAndStorageBuffer16BitAccess
                OpCapability StorageBuffer16BitAccess
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -72,7 +73,9 @@
         %l_m = OpCompositeConstruct %mat4v4half %25 %28 %31 %34
                OpStore %37 %l_m
          %39 = OpFunctionCall %int %i
-         %40 = OpAccessChain %_ptr_Function_v4half %37 %39
-      %l_m_i = OpLoad %v4half %40 None
+         %40 = OpBitcast %uint %39
+         %41 = OpExtInst %uint %42 UMin %40 %uint_3
+         %43 = OpAccessChain %_ptr_Function_v4half %37 %41
+      %l_m_i = OpLoad %v4half %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
index 9b77bdf..eb10bd4 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.glsl
@@ -12,5 +12,5 @@
 void main() {
   f16mat4 v_1 = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
   f16mat4 l_m = v_1;
-  f16vec4 l_m_1 = v_1[1];
+  f16vec4 l_m_1 = v_1[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
index 6447028..781520c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant half4x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant half4x4* const p_m = tint_module_vars.m;
-  const constant half4* const p_m_1 = (&(*p_m)[1]);
+  const constant half4* const p_m_1 = (&(*p_m)[1u]);
   half4x4 const l_m = (*p_m);
   half4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.glsl
index ab43248..393090a 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.glsl
@@ -11,6 +11,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   f16mat4 t = transpose(f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3));
-  float16_t l = length(f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1]);
-  float16_t a = abs(f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].ywxz[0u]);
+  float16_t l = length(f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u]);
+  float16_t a = abs(f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
index 29d1eb9..2e4c06b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant half4x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   half4x4 const t = transpose((*tint_module_vars.u));
-  half const l = length((*tint_module_vars.u)[1]);
-  half const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  half const l = length((*tint_module_vars.u)[1u]);
+  half const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.glsl
index cbbeeab..840cb83 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.glsl
@@ -17,8 +17,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3));
-  b(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1]);
-  b(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].ywxz);
-  c(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1][0u]);
-  c(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1].ywxz[0u]);
+  b(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u]);
+  b(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].ywxz);
+  c(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u][0u]);
+  c(f16mat4(v_1.inner_col0, v_1.inner_col1, v_1.inner_col2, v_1.inner_col3)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.ir.msl
index a76157b..09f20ee 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant half4x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.glsl
index d133b5c..9a4d7c2 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  p[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  p[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].ywxz;
-  p[0][1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  p[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  p[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].ywxz;
+  p[0u][1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
index 3730805..c30b532 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.dxc.hlsl
@@ -29,8 +29,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v_4(0u);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  p[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  p[int(0)].y = float16_t(f16tof32(u[0u].z));
+  p[1u] = tint_bitcast_to_f16(u[0u].xy);
+  p[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  p[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.msl
index 9d834e9..d127c76 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread half4x4 p = half4x4(0.0h);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.spvasm
index e191c12..05e657c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 47
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -43,9 +43,6 @@
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
 %_ptr_Private_v4half = OpTypePointer Private %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Private_half = OpTypePointer Private %half
           %f = OpFunction %void None %12
@@ -60,20 +57,20 @@
          %27 = OpLoad %v4half %25 None
          %28 = OpCompositeConstruct %mat4v4half %18 %21 %24 %27
                OpStore %p %28 None
-         %29 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %34 = OpLoad %v4half %33 None
-               OpStore %29 %34 None
-         %35 = OpAccessChain %_ptr_Private_v4half %p %int_1
-         %36 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %37 = OpLoad %v4half %36 None
-         %38 = OpVectorShuffle %v4half %37 %37 1 3 0 2
-               OpStore %35 %38 None
-         %39 = OpAccessChain %_ptr_Private_v4half %p %int_0
-         %41 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %42 = OpAccessChain %_ptr_Uniform_half %41 %int_0
-         %44 = OpLoad %half %42 None
-         %45 = OpAccessChain %_ptr_Private_half %39 %int_1
-               OpStore %45 %44 None
+         %29 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %32 = OpLoad %v4half %31 None
+               OpStore %29 %32 None
+         %33 = OpAccessChain %_ptr_Private_v4half %p %uint_1
+         %34 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %35 = OpLoad %v4half %34 None
+         %36 = OpVectorShuffle %v4half %35 %35 1 3 0 2
+               OpStore %33 %36 None
+         %37 = OpAccessChain %_ptr_Private_v4half %p %uint_0
+         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_half %38 %uint_0
+         %41 = OpLoad %half %39 None
+         %42 = OpAccessChain %_ptr_Private_half %37 %uint_1
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.glsl
index 053e9f2..4f18995 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.glsl
@@ -15,7 +15,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  v_1.inner[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  v_1.inner[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].ywxz;
-  v_1.inner[0][1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  v_1.inner[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  v_1.inner[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].ywxz;
+  v_1.inner[0u][1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.ir.msl
index 713e80d..97e5255 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant half4x4* u [[buffer(0)]], device half4x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.spvasm
index 19b38ad..6c5143f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -52,9 +52,6 @@
      %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_mat4v4half = OpTypePointer StorageBuffer %mat4v4half
 %_ptr_StorageBuffer_v4half = OpTypePointer StorageBuffer %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
           %f = OpFunction %void None %12
@@ -70,20 +67,20 @@
          %28 = OpCompositeConstruct %mat4v4half %18 %21 %24 %27
          %29 = OpAccessChain %_ptr_StorageBuffer_mat4v4half %6 %uint_0
                OpStore %29 %28 None
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %36 = OpLoad %v4half %35 None
-               OpStore %31 %36 None
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_1
-         %38 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %39 = OpLoad %v4half %38 None
-         %40 = OpVectorShuffle %v4half %39 %39 1 3 0 2
-               OpStore %37 %40 None
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %44 = OpAccessChain %_ptr_Uniform_half %43 %int_0
-         %46 = OpLoad %half %44 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_half %41 %int_1
-               OpStore %47 %46 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %34 = OpLoad %v4half %33 None
+               OpStore %31 %34 None
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %37 = OpLoad %v4half %36 None
+         %38 = OpVectorShuffle %v4half %37 %37 1 3 0 2
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4half %6 %uint_0 %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_half %40 %uint_0
+         %43 = OpLoad %half %41 None
+         %44 = OpAccessChain %_ptr_StorageBuffer_half %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.glsl
index d5c0d5a..f319db6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.glsl
@@ -15,9 +15,9 @@
   }
   barrier();
   w = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3);
-  w[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0];
-  w[1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0].ywxz;
-  w[0][1] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1][0];
+  w[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u];
+  w[1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[0u].ywxz;
+  w[0u][1u] = f16mat4(v.inner_col0, v.inner_col1, v.inner_col2, v.inner_col3)[1u][0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 051393c..090515f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -36,9 +36,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v_4(0u);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy);
-  w[int(1)] = tint_bitcast_to_f16(u[0u].xy).ywxz;
-  w[int(0)].y = float16_t(f16tof32(u[0u].z));
+  w[1u] = tint_bitcast_to_f16(u[0u].xy);
+  w[1u] = tint_bitcast_to_f16(u[0u].xy).ywxz;
+  w[0u].y = float16_t(f16tof32(u[0u].z));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
index 14f05fa..9726b59 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant half4x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
index 590c66e..4d308d7 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f16/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -51,12 +51,9 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_v4half = OpTypePointer Workgroup %v4half
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_half = OpTypePointer Uniform %half
 %_ptr_Workgroup_half = OpTypePointer Workgroup %half
-         %57 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -78,26 +75,26 @@
          %36 = OpLoad %v4half %34 None
          %37 = OpCompositeConstruct %mat4v4half %29 %31 %33 %36
                OpStore %w %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %42 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %43 = OpLoad %v4half %42 None
-               OpStore %38 %43 None
-         %44 = OpAccessChain %_ptr_Workgroup_v4half %w %int_1
-         %45 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
-         %46 = OpLoad %v4half %45 None
-         %47 = OpVectorShuffle %v4half %46 %46 1 3 0 2
-               OpStore %44 %47 None
-         %48 = OpAccessChain %_ptr_Workgroup_v4half %w %int_0
-         %50 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
-         %51 = OpAccessChain %_ptr_Uniform_half %50 %int_0
-         %53 = OpLoad %half %51 None
-         %54 = OpAccessChain %_ptr_Workgroup_half %48 %int_1
-               OpStore %54 %53 None
+         %38 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %40 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %41 = OpLoad %v4half %40 None
+               OpStore %38 %41 None
+         %42 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_1
+         %43 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_0
+         %44 = OpLoad %v4half %43 None
+         %45 = OpVectorShuffle %v4half %44 %44 1 3 0 2
+               OpStore %42 %45 None
+         %46 = OpAccessChain %_ptr_Workgroup_v4half %w %uint_0
+         %47 = OpAccessChain %_ptr_Uniform_v4half %1 %uint_1
+         %48 = OpAccessChain %_ptr_Uniform_half %47 %uint_0
+         %50 = OpLoad %half %48 None
+         %51 = OpAccessChain %_ptr_Workgroup_half %46 %uint_1
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %57
-         %58 = OpLabel
-         %59 = OpLoad %uint %f_local_invocation_index_Input None
-         %60 = OpFunctionCall %void %f_inner %59
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
index c5c08ea..5e4ff9e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.dxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float4x4 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((16u * min(uint(p_m_i_save), 3u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_4 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
index c5c08ea..5e4ff9e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.fxc.hlsl
@@ -20,7 +20,7 @@
 void f() {
   int p_m_i_save = i();
   float4x4 l_m = m_load(0u);
-  const uint scalar_offset_4 = ((16u * uint(p_m_i_save))) / 4;
+  const uint scalar_offset_4 = ((16u * min(uint(p_m_i_save), 3u))) / 4;
   float4 l_m_i = asfloat(m[scalar_offset_4 / 4]);
   return;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
index f777874..bb405d0 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_1 = i();
+  uint v_1 = min(uint(i()), 3u);
   mat4 l_m = v.inner;
   vec4 l_m_i = v.inner[v_1];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
index 7ea5f8f..a6ed3cb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 3u)));
   float4x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
index 7ea5f8f..a6ed3cb 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  uint v_1 = (16u * uint(i()));
+  uint v_1 = (16u * uint(min(uint(i()), 3u)));
   float4x4 l_m = v(0u);
   float4 l_m_i = asfloat(m[(v_1 / 16u)]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
index b0c6478..6fbbd3e 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.ir.msl
@@ -15,7 +15,7 @@
   thread int counter = 0;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m, .counter=(&counter)};
   const constant float4x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_i = (&(*p_m)[i(tint_module_vars)]);
+  const constant float4* const p_m_i = (&(*p_m)[min(uint(i(tint_module_vars)), 3u)]);
   float4x4 const l_m = (*p_m);
   float4 const l_m_i = (*p_m_i);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
index 5650441..c893043 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.msl
@@ -14,7 +14,7 @@
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.counter = 0;
   int const tint_symbol = i(&(tint_private_vars));
-  int const p_m_i_save = tint_symbol;
+  uint const p_m_i_save = min(uint(tint_symbol), 3u);
   float4x4 const l_m = *(tint_symbol_1);
   float4 const l_m_i = (*(tint_symbol_1))[p_m_i_save];
   return;
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
index f7edb93..4b68d0f 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/dynamic_index_via_ptr.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -40,6 +41,7 @@
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
           %i = OpFunction %int None %12
          %13 = OpLabel
@@ -53,7 +55,9 @@
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
          %26 = OpFunctionCall %int %i
-      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %26
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_3
+      %p_m_i = OpAccessChain %_ptr_Uniform_v4float %p_m %28
         %l_m = OpLoad %mat4v4float %p_m None
       %l_m_i = OpLoad %v4float %p_m_i None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
index c407f35..ddbd859 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.glsl
@@ -7,5 +7,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat4 l_m = v.inner;
-  vec4 l_m_1 = v.inner[1];
+  vec4 l_m_1 = v.inner[1u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
index d487cc2..874dfe3 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
 kernel void f(const constant float4x4* m [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.m=m};
   const constant float4x4* const p_m = tint_module_vars.m;
-  const constant float4* const p_m_1 = (&(*p_m)[1]);
+  const constant float4* const p_m_1 = (&(*p_m)[1u]);
   float4x4 const l_m = (*p_m);
   float4 const l_m_1 = (*p_m_1);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
index 8315186..ba1d072 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/static_index_via_ptr.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -41,6 +41,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+     %uint_1 = OpConstant %uint 1
           %i = OpFunction %int None %12
          %13 = OpLabel
          %14 = OpLoad %int %counter None
@@ -52,7 +53,7 @@
           %f = OpFunction %void None %20
          %21 = OpLabel
         %p_m = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
-      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %int_1
+      %p_m_1 = OpAccessChain %_ptr_Uniform_v4float %p_m %uint_1
         %l_m = OpLoad %mat4v4float %p_m None
       %l_m_1 = OpLoad %v4float %p_m_1 None
                OpReturn
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.glsl
index f5d7063..139f579 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.glsl
@@ -7,6 +7,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat4 t = transpose(v.inner);
-  float l = length(v.inner[1]);
-  float a = abs(v.inner[0].ywxz[0u]);
+  float l = length(v.inner[1u]);
+  float a = abs(v.inner[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
index fdf565b..34725ed 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.ir.msl
@@ -8,6 +8,6 @@
 kernel void f(const constant float4x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   float4x4 const t = transpose((*tint_module_vars.u));
-  float const l = length((*tint_module_vars.u)[1]);
-  float const a = abs((*tint_module_vars.u)[0].ywxz[0u]);
+  float const l = length((*tint_module_vars.u)[1u]);
+  float const a = abs((*tint_module_vars.u)[0u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.spvasm
index 95fa745..d66de79 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_builtin.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
-         %23 = OpExtInstImport "GLSL.std.450"
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -33,21 +33,19 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
           %f = OpFunction %void None %9
          %10 = OpLabel
          %11 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
          %15 = OpLoad %mat4v4float %11 None
           %t = OpTranspose %mat4v4float %15
-         %17 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %21 = OpLoad %v4float %17 None
-          %l = OpExtInst %float %23 Length %21
-         %24 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %26 = OpLoad %v4float %24 None
-         %27 = OpVectorShuffle %v4float %26 %26 1 3 0 2
-         %28 = OpCompositeExtract %float %27 0
-          %a = OpExtInst %float %23 FAbs %28
+         %17 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %20 = OpLoad %v4float %17 None
+          %l = OpExtInst %float %22 Length %20
+         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %24 = OpLoad %v4float %23 None
+         %25 = OpVectorShuffle %v4float %24 %24 1 3 0 2
+         %26 = OpCompositeExtract %float %25 0
+          %a = OpExtInst %float %22 FAbs %26
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.glsl
index 7412f5b..b44f718 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.glsl
@@ -13,8 +13,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   a(v_1.inner);
-  b(v_1.inner[1]);
-  b(v_1.inner[1].ywxz);
-  c(v_1.inner[1].x);
-  c(v_1.inner[1].ywxz[0u]);
+  b(v_1.inner[1u]);
+  b(v_1.inner[1u].ywxz);
+  c(v_1.inner[1u].x);
+  c(v_1.inner[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.ir.msl
index c948a20..35e5389 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.ir.msl
@@ -17,8 +17,8 @@
 kernel void f(const constant float4x4* u [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u};
   a((*tint_module_vars.u));
-  b((*tint_module_vars.u)[1]);
-  b((*tint_module_vars.u)[1].ywxz);
-  c((*tint_module_vars.u)[1][0u]);
-  c((*tint_module_vars.u)[1].ywxz[0u]);
+  b((*tint_module_vars.u)[1u]);
+  b((*tint_module_vars.u)[1u].ywxz);
+  c((*tint_module_vars.u)[1u][0u]);
+  c((*tint_module_vars.u)[1u].ywxz[0u]);
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.spvasm
index 84d3c81..7bb8e3b 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_fn.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,8 +38,7 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_float = OpTypePointer Uniform %float
           %a = OpFunction %void None %10
           %m = OpFunctionParameter %mat4v4float
@@ -61,21 +60,21 @@
          %23 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
          %27 = OpLoad %mat4v4float %23 None
          %28 = OpFunctionCall %void %a %27
-         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpLoad %v4float %29 None
-         %34 = OpFunctionCall %void %b %33
-         %35 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %36 = OpLoad %v4float %35 None
-         %37 = OpVectorShuffle %v4float %36 %36 1 3 0 2
-         %38 = OpFunctionCall %void %b %37
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %40 = OpAccessChain %_ptr_Uniform_float %39 %uint_0
-         %42 = OpLoad %float %40 None
-         %43 = OpFunctionCall %void %c %42
-         %44 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %45 = OpLoad %v4float %44 None
-         %46 = OpVectorShuffle %v4float %45 %45 1 3 0 2
-         %47 = OpCompositeExtract %float %46 0
-         %48 = OpFunctionCall %void %c %47
+         %29 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %32 = OpLoad %v4float %29 None
+         %33 = OpFunctionCall %void %b %32
+         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %35 = OpLoad %v4float %34 None
+         %36 = OpVectorShuffle %v4float %35 %35 1 3 0 2
+         %37 = OpFunctionCall %void %b %36
+         %38 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %39 = OpAccessChain %_ptr_Uniform_float %38 %uint_0
+         %41 = OpLoad %float %39 None
+         %42 = OpFunctionCall %void %c %41
+         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %44 = OpLoad %v4float %43 None
+         %45 = OpVectorShuffle %v4float %44 %44 1 3 0 2
+         %46 = OpCompositeExtract %float %45 0
+         %47 = OpFunctionCall %void %c %46
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.glsl
index 431640a..bcd1d61 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   p = v.inner;
-  p[1] = v.inner[0];
-  p[1] = v.inner[0].ywxz;
-  p[0][1] = v.inner[1].x;
+  p[1u] = v.inner[0u];
+  p[1u] = v.inner[0u].ywxz;
+  p[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
index 9e75ac2..eddaa36 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
index 9e75ac2..eddaa36 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.fxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   p = v(0u);
-  p[int(1)] = asfloat(u[0u]);
-  p[int(1)] = asfloat(u[0u]).ywxz;
-  p[int(0)].y = asfloat(u[1u].x);
+  p[1u] = asfloat(u[0u]);
+  p[1u] = asfloat(u[0u]).ywxz;
+  p[0u].y = asfloat(u[1u].x);
 }
 
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.msl
index c48b4b0..5f09a38 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.ir.msl
@@ -10,7 +10,7 @@
   thread float4x4 p = float4x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .p=(&p)};
   (*tint_module_vars.p) = (*tint_module_vars.u);
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.p)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.p)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.p)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.p)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.spvasm
index b08abe2..7e85184 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_private.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -33,10 +33,8 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Private_float = OpTypePointer Private %float
           %f = OpFunction %void None %12
@@ -44,20 +42,20 @@
          %14 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
          %18 = OpLoad %mat4v4float %14 None
                OpStore %p %18 None
-         %19 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %23 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %26 = OpLoad %v4float %23 None
-               OpStore %19 %26 None
-         %27 = OpAccessChain %_ptr_Private_v4float %p %int_1
-         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %29 = OpLoad %v4float %28 None
-         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
-               OpStore %27 %30 None
-         %31 = OpAccessChain %_ptr_Private_v4float %p %int_0
-         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %33 = OpAccessChain %_ptr_Uniform_float %32 %int_0
-         %35 = OpLoad %float %33 None
-         %36 = OpAccessChain %_ptr_Private_float %31 %int_1
-               OpStore %36 %35 None
+         %19 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %22 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %24 = OpLoad %v4float %22 None
+               OpStore %19 %24 None
+         %25 = OpAccessChain %_ptr_Private_v4float %p %uint_1
+         %26 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %27 = OpLoad %v4float %26 None
+         %28 = OpVectorShuffle %v4float %27 %27 1 3 0 2
+               OpStore %25 %28 None
+         %29 = OpAccessChain %_ptr_Private_v4float %p %uint_0
+         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %31 = OpAccessChain %_ptr_Uniform_float %30 %uint_0
+         %33 = OpLoad %float %31 None
+         %34 = OpAccessChain %_ptr_Private_float %29 %uint_1
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.glsl
index d07c264..f0e802c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.glsl
@@ -11,7 +11,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   v_1.inner = v.inner;
-  v_1.inner[1] = v.inner[0];
-  v_1.inner[1] = v.inner[0].ywxz;
-  v_1.inner[0][1] = v.inner[1].x;
+  v_1.inner[1u] = v.inner[0u];
+  v_1.inner[1u] = v.inner[0u].ywxz;
+  v_1.inner[0u][1u] = v.inner[1u].x;
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.ir.msl
index 825145f..236d1e6 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.ir.msl
@@ -9,7 +9,7 @@
 kernel void f(const constant float4x4* u [[buffer(0)]], device float4x4* s [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.u=u, .s=s};
   (*tint_module_vars.s) = (*tint_module_vars.u);
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.s)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.s)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.s)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.s)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.spvasm
index 64ba7ba..4d725fa 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_storage.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -42,10 +42,8 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
           %f = OpFunction %void None %12
@@ -54,20 +52,20 @@
          %18 = OpLoad %mat4v4float %14 None
          %19 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %7 %uint_0
                OpStore %19 %18 None
-         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %25 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %28 = OpLoad %v4float %25 None
-               OpStore %21 %28 None
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_1
-         %30 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %31 = OpLoad %v4float %30 None
-         %32 = OpVectorShuffle %v4float %31 %31 1 3 0 2
-               OpStore %29 %32 None
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %int_0
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %35 = OpAccessChain %_ptr_Uniform_float %34 %int_0
-         %37 = OpLoad %float %35 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %33 %int_1
-               OpStore %38 %37 None
+         %21 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %24 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %26 = OpLoad %v4float %24 None
+               OpStore %21 %26 None
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_1
+         %28 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %29 = OpLoad %v4float %28 None
+         %30 = OpVectorShuffle %v4float %29 %29 1 3 0 2
+               OpStore %27 %30 None
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %7 %uint_0 %uint_0
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %33 = OpAccessChain %_ptr_Uniform_float %32 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpAccessChain %_ptr_StorageBuffer_float %31 %uint_1
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.glsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.glsl
index 0b67423..4754b44 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.glsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.glsl
@@ -11,9 +11,9 @@
   }
   barrier();
   w = v.inner;
-  w[1] = v.inner[0];
-  w[1] = v.inner[0].ywxz;
-  w[0][1] = v.inner[1].x;
+  w[1u] = v.inner[0u];
+  w[1u] = v.inner[0u].ywxz;
+  w[0u][1u] = v.inner[1u].x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
index 3a5da76..ff12163 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.dxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
index 3a5da76..ff12163 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.fxc.hlsl
@@ -17,9 +17,9 @@
   }
   GroupMemoryBarrierWithGroupSync();
   w = v(0u);
-  w[int(1)] = asfloat(u[0u]);
-  w[int(1)] = asfloat(u[0u]).ywxz;
-  w[int(0)].y = asfloat(u[1u].x);
+  w[1u] = asfloat(u[0u]);
+  w[1u] = asfloat(u[0u]).ywxz;
+  w[0u].y = asfloat(u[1u].x);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
index d94ad9c..5421a4c 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.ir.msl
@@ -16,9 +16,9 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   (*tint_module_vars.w) = (*tint_module_vars.u);
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0];
-  (*tint_module_vars.w)[1] = (*tint_module_vars.u)[0].ywxz;
-  (*tint_module_vars.w)[0][1] = (*tint_module_vars.u)[1][0];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u];
+  (*tint_module_vars.w)[1u] = (*tint_module_vars.u)[0u].ywxz;
+  (*tint_module_vars.w)[0u][1u] = (*tint_module_vars.u)[1u][0u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant float4x4* u [[buffer(0)]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.spvasm b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
index 1d8e9c4..8120a23 100644
--- a/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
+++ b/test/tint/buffer/uniform/std140/unnested/mat4x4_f32/to_workgroup.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -43,13 +43,10 @@
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
      %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_v4float = OpTypePointer Workgroup %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-         %50 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
     %f_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -64,26 +61,26 @@
          %26 = OpAccessChain %_ptr_Uniform_mat4v4float %1 %uint_0
          %29 = OpLoad %mat4v4float %26 None
                OpStore %w %29 None
-         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %34 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %37 = OpLoad %v4float %34 None
-               OpStore %30 %37 None
-         %38 = OpAccessChain %_ptr_Workgroup_v4float %w %int_1
-         %39 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_0
-         %40 = OpLoad %v4float %39 None
-         %41 = OpVectorShuffle %v4float %40 %40 1 3 0 2
-               OpStore %38 %41 None
-         %42 = OpAccessChain %_ptr_Workgroup_v4float %w %int_0
-         %43 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %int_1
-         %44 = OpAccessChain %_ptr_Uniform_float %43 %int_0
-         %46 = OpLoad %float %44 None
-         %47 = OpAccessChain %_ptr_Workgroup_float %42 %int_1
-               OpStore %47 %46 None
+         %30 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %32 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %34 = OpLoad %v4float %32 None
+               OpStore %30 %34 None
+         %35 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_1
+         %36 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0
+         %37 = OpLoad %v4float %36 None
+         %38 = OpVectorShuffle %v4float %37 %37 1 3 0 2
+               OpStore %35 %38 None
+         %39 = OpAccessChain %_ptr_Workgroup_v4float %w %uint_0
+         %40 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_1
+         %41 = OpAccessChain %_ptr_Uniform_float %40 %uint_0
+         %43 = OpLoad %float %41 None
+         %44 = OpAccessChain %_ptr_Workgroup_float %39 %uint_1
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %50
-         %51 = OpLabel
-         %52 = OpLoad %uint %f_local_invocation_index_Input None
-         %53 = OpFunctionCall %void %f_inner %52
+          %f = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpLoad %uint %f_local_invocation_index_Input None
+         %50 = OpFunctionCall %void %f_inner %49
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl
index 85cafd7..9db0e46 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.dxc.hlsl
@@ -47,7 +47,10 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((4u * ((3u * vertexIndex) + 0u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 1u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 2u)))));
+  uint tint_symbol_3 = 0u;
+  positions.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+  float3 position = float3(asfloat(positions.Load((4u * min(((3u * vertexIndex) + 0u), (tint_symbol_4 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 1u), (tint_symbol_4 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 2u), (tint_symbol_4 - 1u))))));
   return position;
 }
 
@@ -66,12 +69,24 @@
 
 
 void doIgnore() {
+  uint tint_symbol_6 = 0u;
+  counters.GetDimensions(tint_symbol_6);
+  uint tint_symbol_7 = ((tint_symbol_6 - 0u) / 4u);
+  uint tint_symbol_9 = 0u;
+  indices.GetDimensions(tint_symbol_9);
+  uint tint_symbol_10 = ((tint_symbol_9 - 0u) / 4u);
+  uint tint_symbol_11 = 0u;
+  positions.GetDimensions(tint_symbol_11);
+  uint tint_symbol_12 = ((tint_symbol_11 - 0u) / 4u);
+  uint tint_symbol_14 = 0u;
+  LUT.GetDimensions(tint_symbol_14);
+  uint tint_symbol_15 = ((tint_symbol_14 - 0u) / 4u);
   uint g43 = uniforms[0].x;
   uint kj6 = dbg.Load(20u);
-  uint b53 = countersatomicLoad(0u);
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int g55 = LUTatomicLoad(0u);
+  uint b53 = countersatomicLoad((4u * min(0u, (tint_symbol_7 - 1u))));
+  uint rwg = indices.Load((4u * min(0u, (tint_symbol_10 - 1u))));
+  float rb5 = asfloat(positions.Load((4u * min(0u, (tint_symbol_12 - 1u)))));
+  int g55 = LUTatomicLoad((4u * min(0u, (tint_symbol_15 - 1u))));
 }
 
 struct tint_symbol_1 {
@@ -86,21 +101,27 @@
 
 
 void main_count_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_16 = 0u;
+  indices.GetDimensions(tint_symbol_16);
+  uint tint_symbol_17 = ((tint_symbol_16 - 0u) / 4u);
+  uint tint_symbol_18 = 0u;
+  LUT.GetDimensions(tint_symbol_18);
+  uint tint_symbol_19 = ((tint_symbol_18 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * i0) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * i0) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_17 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * i0) + 1u), (tint_symbol_17 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * i0) + 2u), (tint_symbol_17 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i0);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0].y, p0);
-  int triangleOffset = LUTatomicAdd((4u * i1), 1);
+  int triangleOffset = LUTatomicAdd((4u * min(i1, (tint_symbol_19 - 1u))), 1);
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl
index 85cafd7..9db0e46 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.fxc.hlsl
@@ -47,7 +47,10 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((4u * ((3u * vertexIndex) + 0u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 1u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 2u)))));
+  uint tint_symbol_3 = 0u;
+  positions.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+  float3 position = float3(asfloat(positions.Load((4u * min(((3u * vertexIndex) + 0u), (tint_symbol_4 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 1u), (tint_symbol_4 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 2u), (tint_symbol_4 - 1u))))));
   return position;
 }
 
@@ -66,12 +69,24 @@
 
 
 void doIgnore() {
+  uint tint_symbol_6 = 0u;
+  counters.GetDimensions(tint_symbol_6);
+  uint tint_symbol_7 = ((tint_symbol_6 - 0u) / 4u);
+  uint tint_symbol_9 = 0u;
+  indices.GetDimensions(tint_symbol_9);
+  uint tint_symbol_10 = ((tint_symbol_9 - 0u) / 4u);
+  uint tint_symbol_11 = 0u;
+  positions.GetDimensions(tint_symbol_11);
+  uint tint_symbol_12 = ((tint_symbol_11 - 0u) / 4u);
+  uint tint_symbol_14 = 0u;
+  LUT.GetDimensions(tint_symbol_14);
+  uint tint_symbol_15 = ((tint_symbol_14 - 0u) / 4u);
   uint g43 = uniforms[0].x;
   uint kj6 = dbg.Load(20u);
-  uint b53 = countersatomicLoad(0u);
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int g55 = LUTatomicLoad(0u);
+  uint b53 = countersatomicLoad((4u * min(0u, (tint_symbol_7 - 1u))));
+  uint rwg = indices.Load((4u * min(0u, (tint_symbol_10 - 1u))));
+  float rb5 = asfloat(positions.Load((4u * min(0u, (tint_symbol_12 - 1u)))));
+  int g55 = LUTatomicLoad((4u * min(0u, (tint_symbol_15 - 1u))));
 }
 
 struct tint_symbol_1 {
@@ -86,21 +101,27 @@
 
 
 void main_count_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_16 = 0u;
+  indices.GetDimensions(tint_symbol_16);
+  uint tint_symbol_17 = ((tint_symbol_16 - 0u) / 4u);
+  uint tint_symbol_18 = 0u;
+  LUT.GetDimensions(tint_symbol_18);
+  uint tint_symbol_19 = ((tint_symbol_18 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * i0) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * i0) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_17 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * i0) + 1u), (tint_symbol_17 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * i0) + 2u), (tint_symbol_17 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i0);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0].y, p0);
-  int triangleOffset = LUTatomicAdd((4u * i1), 1);
+  int triangleOffset = LUTatomicAdd((4u * min(i1, (tint_symbol_19 - 1u))), 1);
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.glsl b/test/tint/bug/chromium/1273230.wgsl.expected.glsl
index edec4a1..6402170 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.glsl
@@ -70,16 +70,29 @@
   return ((icoord.x + (gridSize * icoord.y)) + ((gridSize * gridSize) * icoord.z));
 }
 vec3 loadPosition(uint vertexIndex) {
-  vec3 position = vec3(positions.values[((3u * vertexIndex) + 0u)], positions.values[((3u * vertexIndex) + 1u)], positions.values[((3u * vertexIndex) + 2u)]);
+  uint v_2 = min(((3u * vertexIndex) + 0u), (uint(positions.values.length()) - 1u));
+  float v_3 = positions.values[v_2];
+  uint v_4 = min(((3u * vertexIndex) + 1u), (uint(positions.values.length()) - 1u));
+  float v_5 = positions.values[v_4];
+  uint v_6 = min(((3u * vertexIndex) + 2u), (uint(positions.values.length()) - 1u));
+  vec3 position = vec3(v_3, v_5, positions.values[v_6]);
   return position;
 }
 void doIgnore() {
   uint g43 = v.inner.numTriangles;
   uint kj6 = v_1.inner.value1;
-  uint b53 = atomicOr(counters.values[0], 0u);
-  uint rwg = indices.values[0];
-  float rb5 = positions.values[0];
-  int g55 = atomicOr(LUT.values[0], 0);
+  uint v_7 = (uint(counters.values.length()) - 1u);
+  uint v_8 = min(uint(0), v_7);
+  uint b53 = atomicOr(counters.values[v_8], 0u);
+  uint v_9 = (uint(indices.values.length()) - 1u);
+  uint v_10 = min(uint(0), v_9);
+  uint rwg = indices.values[v_10];
+  uint v_11 = (uint(positions.values.length()) - 1u);
+  uint v_12 = min(uint(0), v_11);
+  float rb5 = positions.values[v_12];
+  uint v_13 = (uint(LUT.values.length()) - 1u);
+  uint v_14 = min(uint(0), v_13);
+  int g55 = atomicOr(LUT.values[v_14], 0);
 }
 void main_count_inner(uvec3 GlobalInvocationID) {
   uint triangleIndex = GlobalInvocationID[0u];
@@ -87,20 +100,24 @@
     return;
   }
   doIgnore();
-  uint v_2 = ((3u * triangleIndex) + 0u);
-  uint i0 = indices.values[v_2];
-  uint v_3 = ((3u * i0) + 1u);
-  uint i1 = indices.values[v_3];
-  uint v_4 = ((3u * i0) + 2u);
-  uint i2 = indices.values[v_4];
+  uint v_15 = ((3u * triangleIndex) + 0u);
+  uint v_16 = min(v_15, (uint(indices.values.length()) - 1u));
+  uint i0 = indices.values[v_16];
+  uint v_17 = ((3u * i0) + 1u);
+  uint v_18 = min(v_17, (uint(indices.values.length()) - 1u));
+  uint i1 = indices.values[v_18];
+  uint v_19 = ((3u * i0) + 2u);
+  uint v_20 = min(v_19, (uint(indices.values.length()) - 1u));
+  uint i2 = indices.values[v_20];
   vec3 p0 = loadPosition(i0);
   vec3 p1 = loadPosition(i0);
   vec3 p2 = loadPosition(i2);
   vec3 center = (((p0 + p2) + p1) / 3.0f);
   vec3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(v.inner.gridSize, p0);
-  uint v_5 = i1;
-  int triangleOffset = atomicAdd(LUT.values[v_5], 1);
+  uint v_21 = i1;
+  uint v_22 = min(v_21, (uint(LUT.values.length()) - 1u));
+  int triangleOffset = atomicAdd(LUT.values[v_22], 1);
 }
 layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
index 74902a5..b84362f 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.ir.dxc.hlsl
@@ -52,21 +52,39 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((0u + (((3u * vertexIndex) + 0u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 1u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 2u) * 4u)))));
+  uint v_1 = 0u;
+  positions.GetDimensions(v_1);
+  uint v_2 = 0u;
+  positions.GetDimensions(v_2);
+  uint v_3 = 0u;
+  positions.GetDimensions(v_3);
+  float3 position = float3(asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 0u), ((v_1 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 1u), ((v_2 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 2u), ((v_3 / 4u) - 1u)) * 4u)))));
   return position;
 }
 
 void doIgnore() {
   uint g43 = uniforms[0u].x;
   uint kj6 = dbg.Load(20u);
-  uint v_1 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_1);
-  uint b53 = v_1;
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int v_2 = int(0);
-  LUT.InterlockedOr(int(0u), int(0), v_2);
-  int g55 = v_2;
+  uint v_4 = 0u;
+  counters.GetDimensions(v_4);
+  uint v_5 = ((v_4 / 4u) - 1u);
+  uint v_6 = 0u;
+  counters.InterlockedOr(uint((0u + (min(uint(int(0)), v_5) * 4u))), 0u, v_6);
+  uint b53 = v_6;
+  uint v_7 = 0u;
+  indices.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 4u) - 1u);
+  uint rwg = indices.Load((0u + (min(uint(int(0)), v_8) * 4u)));
+  uint v_9 = 0u;
+  positions.GetDimensions(v_9);
+  uint v_10 = ((v_9 / 4u) - 1u);
+  float rb5 = asfloat(positions.Load((0u + (min(uint(int(0)), v_10) * 4u))));
+  uint v_11 = 0u;
+  LUT.GetDimensions(v_11);
+  uint v_12 = ((v_11 / 4u) - 1u);
+  int v_13 = int(0);
+  LUT.InterlockedOr(int((0u + (min(uint(int(0)), v_12) * 4u))), int(0), v_13);
+  int g55 = v_13;
 }
 
 void main_count_inner(uint3 GlobalInvocationID) {
@@ -75,18 +93,26 @@
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * i0) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * i0) + 2u) * 4u)));
+  uint v_14 = 0u;
+  indices.GetDimensions(v_14);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_14 / 4u) - 1u)) * 4u)));
+  uint v_15 = 0u;
+  indices.GetDimensions(v_15);
+  uint i1 = indices.Load((0u + (min(((3u * i0) + 1u), ((v_15 / 4u) - 1u)) * 4u)));
+  uint v_16 = 0u;
+  indices.GetDimensions(v_16);
+  uint i2 = indices.Load((0u + (min(((3u * i0) + 2u), ((v_16 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i0);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0u].y, p0);
-  int v_3 = int(0);
-  LUT.InterlockedAdd(int((0u + (i1 * 4u))), int(1), v_3);
-  int triangleOffset = v_3;
+  uint v_17 = 0u;
+  LUT.GetDimensions(v_17);
+  int v_18 = int(0);
+  LUT.InterlockedAdd(int((0u + (min(i1, ((v_17 / 4u) - 1u)) * 4u))), int(1), v_18);
+  int triangleOffset = v_18;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
index 74902a5..b84362f 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.ir.fxc.hlsl
@@ -52,21 +52,39 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((0u + (((3u * vertexIndex) + 0u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 1u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 2u) * 4u)))));
+  uint v_1 = 0u;
+  positions.GetDimensions(v_1);
+  uint v_2 = 0u;
+  positions.GetDimensions(v_2);
+  uint v_3 = 0u;
+  positions.GetDimensions(v_3);
+  float3 position = float3(asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 0u), ((v_1 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 1u), ((v_2 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 2u), ((v_3 / 4u) - 1u)) * 4u)))));
   return position;
 }
 
 void doIgnore() {
   uint g43 = uniforms[0u].x;
   uint kj6 = dbg.Load(20u);
-  uint v_1 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_1);
-  uint b53 = v_1;
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int v_2 = int(0);
-  LUT.InterlockedOr(int(0u), int(0), v_2);
-  int g55 = v_2;
+  uint v_4 = 0u;
+  counters.GetDimensions(v_4);
+  uint v_5 = ((v_4 / 4u) - 1u);
+  uint v_6 = 0u;
+  counters.InterlockedOr(uint((0u + (min(uint(int(0)), v_5) * 4u))), 0u, v_6);
+  uint b53 = v_6;
+  uint v_7 = 0u;
+  indices.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 4u) - 1u);
+  uint rwg = indices.Load((0u + (min(uint(int(0)), v_8) * 4u)));
+  uint v_9 = 0u;
+  positions.GetDimensions(v_9);
+  uint v_10 = ((v_9 / 4u) - 1u);
+  float rb5 = asfloat(positions.Load((0u + (min(uint(int(0)), v_10) * 4u))));
+  uint v_11 = 0u;
+  LUT.GetDimensions(v_11);
+  uint v_12 = ((v_11 / 4u) - 1u);
+  int v_13 = int(0);
+  LUT.InterlockedOr(int((0u + (min(uint(int(0)), v_12) * 4u))), int(0), v_13);
+  int g55 = v_13;
 }
 
 void main_count_inner(uint3 GlobalInvocationID) {
@@ -75,18 +93,26 @@
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * i0) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * i0) + 2u) * 4u)));
+  uint v_14 = 0u;
+  indices.GetDimensions(v_14);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_14 / 4u) - 1u)) * 4u)));
+  uint v_15 = 0u;
+  indices.GetDimensions(v_15);
+  uint i1 = indices.Load((0u + (min(((3u * i0) + 1u), ((v_15 / 4u) - 1u)) * 4u)));
+  uint v_16 = 0u;
+  indices.GetDimensions(v_16);
+  uint i2 = indices.Load((0u + (min(((3u * i0) + 2u), ((v_16 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i0);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1);
   uint lIndex = toIndex1D(uniforms[0u].y, p0);
-  int v_3 = int(0);
-  LUT.InterlockedAdd(int((0u + (i1 * 4u))), int(1), v_3);
-  int triangleOffset = v_3;
+  uint v_17 = 0u;
+  LUT.GetDimensions(v_17);
+  int v_18 = int(0);
+  LUT.InterlockedAdd(int((0u + (min(i1, ((v_17 / 4u) - 1u)) * 4u))), int(1), v_18);
+  int triangleOffset = v_18;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.ir.msl b/test/tint/bug/chromium/1273230.wgsl.expected.ir.msl
index 7b8e619..e7e893f 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.ir.msl
@@ -62,6 +62,7 @@
   device AU32s* counters;
   device AI32s* LUT;
   device Dbg* dbg;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void marg8uintin() {
@@ -104,17 +105,21 @@
 }
 
 float3 loadPosition(uint vertexIndex, tint_module_vars_struct tint_module_vars) {
-  float3 position = float3((*tint_module_vars.positions).values[((3u * vertexIndex) + 0u)], (*tint_module_vars.positions).values[((3u * vertexIndex) + 1u)], (*tint_module_vars.positions).values[((3u * vertexIndex) + 2u)]);
+  float3 position = float3((*tint_module_vars.positions).values[min(((3u * vertexIndex) + 0u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))], (*tint_module_vars.positions).values[min(((3u * vertexIndex) + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))], (*tint_module_vars.positions).values[min(((3u * vertexIndex) + 2u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))]);
   return position;
 }
 
 void doIgnore(tint_module_vars_struct tint_module_vars) {
   uint g43 = (*tint_module_vars.uniforms).numTriangles;
   uint kj6 = (*tint_module_vars.dbg).value1;
-  uint b53 = atomic_load_explicit((&(*tint_module_vars.counters).values[0]), memory_order_relaxed);
-  uint rwg = (*tint_module_vars.indices).values[0];
-  float rb5 = (*tint_module_vars.positions).values[0];
-  int g55 = atomic_load_explicit((&(*tint_module_vars.LUT).values[0]), memory_order_relaxed);
+  uint const v = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u);
+  uint b53 = atomic_load_explicit((&(*tint_module_vars.counters).values[min(uint(0), v)]), memory_order_relaxed);
+  uint const v_1 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u);
+  uint rwg = (*tint_module_vars.indices).values[min(uint(0), v_1)];
+  uint const v_2 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u);
+  float rb5 = (*tint_module_vars.positions).values[min(uint(0), v_2)];
+  uint const v_3 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][3u] - 0u) / 4u) - 1u);
+  int g55 = atomic_load_explicit((&(*tint_module_vars.LUT).values[min(uint(0), v_3)]), memory_order_relaxed);
 }
 
 void main_count_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
@@ -123,19 +128,19 @@
     return;
   }
   doIgnore(tint_module_vars);
-  uint i0 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*tint_module_vars.indices).values[((3u * i0) + 1u)];
-  uint i2 = (*tint_module_vars.indices).values[((3u * i0) + 2u)];
+  uint i0 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 0u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*tint_module_vars.indices).values[min(((3u * i0) + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*tint_module_vars.indices).values[min(((3u * i0) + 2u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
   float3 p0 = loadPosition(i0, tint_module_vars);
   float3 p1 = loadPosition(i0, tint_module_vars);
   float3 p2 = loadPosition(i2, tint_module_vars);
   float3 center = (((p0 + p2) + p1) / 3.0f);
   float3 voxelPos = toVoxelPos(p1, tint_module_vars);
   uint lIndex = toIndex1D((*tint_module_vars.uniforms).gridSize, p0);
-  int triangleOffset = atomic_fetch_add_explicit((&(*tint_module_vars.LUT).values[i1]), 1, memory_order_relaxed);
+  int triangleOffset = atomic_fetch_add_explicit((&(*tint_module_vars.LUT).values[min(i1, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][3u] - 0u) / 4u) - 1u))]), 1, memory_order_relaxed);
 }
 
-kernel void main_count(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg};
+kernel void main_count(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   main_count_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.msl b/test/tint/bug/chromium/1273230.wgsl.expected.msl
index 6300a9d..463ec02 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.msl
@@ -25,6 +25,10 @@
   /* 0x002c */ tint_array<int8_t, 4> tint_pad_1;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 uint3 tint_ftou(float3 v) {
   return select(uint3(4294967295u), select(uint3(v), uint3(0u), (v < float3(0.0f))), (v <= float3(4294967040.0f)));
 }
@@ -108,40 +112,40 @@
   return uint3(z, y, y);
 }
 
-float3 loadPosition(uint vertexIndex, device F32s* const tint_symbol_1) {
-  float3 position = float3((*(tint_symbol_1)).values[((3u * vertexIndex) + 0u)], (*(tint_symbol_1)).values[((3u * vertexIndex) + 1u)], (*(tint_symbol_1)).values[((3u * vertexIndex) + 2u)]);
+float3 loadPosition(uint vertexIndex, device F32s* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  float3 position = float3((*(tint_symbol_1)).values[min(((3u * vertexIndex) + 0u), ((((*(tint_symbol_2)).array_lengths[0u][1u] - 0u) / 4u) - 1u))], (*(tint_symbol_1)).values[min(((3u * vertexIndex) + 1u), ((((*(tint_symbol_2)).array_lengths[0u][1u] - 0u) / 4u) - 1u))], (*(tint_symbol_1)).values[min(((3u * vertexIndex) + 2u), ((((*(tint_symbol_2)).array_lengths[0u][1u] - 0u) / 4u) - 1u))]);
   return position;
 }
 
-void doIgnore(const constant Uniforms_tint_packed_vec3* const tint_symbol_2, device Dbg* const tint_symbol_3, device AU32s* const tint_symbol_4, device U32s* const tint_symbol_5, device F32s* const tint_symbol_6, device AI32s* const tint_symbol_7) {
-  uint g43 = (*(tint_symbol_2)).numTriangles;
-  uint kj6 = (*(tint_symbol_3)).value1;
-  uint b53 = atomic_load_explicit(&((*(tint_symbol_4)).values[0]), memory_order_relaxed);
-  uint rwg = (*(tint_symbol_5)).values[0];
-  float rb5 = (*(tint_symbol_6)).values[0];
-  int g55 = atomic_load_explicit(&((*(tint_symbol_7)).values[0]), memory_order_relaxed);
+void doIgnore(const constant Uniforms_tint_packed_vec3* const tint_symbol_3, device Dbg* const tint_symbol_4, device AU32s* const tint_symbol_5, const constant TintArrayLengths* const tint_symbol_6, device U32s* const tint_symbol_7, device F32s* const tint_symbol_8, device AI32s* const tint_symbol_9) {
+  uint g43 = (*(tint_symbol_3)).numTriangles;
+  uint kj6 = (*(tint_symbol_4)).value1;
+  uint b53 = atomic_load_explicit(&((*(tint_symbol_5)).values[min(0u, ((((*(tint_symbol_6)).array_lengths[0u][2u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
+  uint rwg = (*(tint_symbol_7)).values[min(0u, ((((*(tint_symbol_6)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  float rb5 = (*(tint_symbol_8)).values[min(0u, ((((*(tint_symbol_6)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
+  int g55 = atomic_load_explicit(&((*(tint_symbol_9)).values[min(0u, ((((*(tint_symbol_6)).array_lengths[0u][3u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
 }
 
-void main_count_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_8, device Dbg* const tint_symbol_9, device AU32s* const tint_symbol_10, device U32s* const tint_symbol_11, device F32s* const tint_symbol_12, device AI32s* const tint_symbol_13) {
+void main_count_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_10, device Dbg* const tint_symbol_11, device AU32s* const tint_symbol_12, const constant TintArrayLengths* const tint_symbol_13, device U32s* const tint_symbol_14, device F32s* const tint_symbol_15, device AI32s* const tint_symbol_16) {
   uint triangleIndex = GlobalInvocationID[0];
-  if ((triangleIndex >= (*(tint_symbol_8)).numTriangles)) {
+  if ((triangleIndex >= (*(tint_symbol_10)).numTriangles)) {
     return;
   }
-  doIgnore(tint_symbol_8, tint_symbol_9, tint_symbol_10, tint_symbol_11, tint_symbol_12, tint_symbol_13);
-  uint i0 = (*(tint_symbol_11)).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*(tint_symbol_11)).values[((3u * i0) + 1u)];
-  uint i2 = (*(tint_symbol_11)).values[((3u * i0) + 2u)];
-  float3 p0 = loadPosition(i0, tint_symbol_12);
-  float3 p1 = loadPosition(i0, tint_symbol_12);
-  float3 p2 = loadPosition(i2, tint_symbol_12);
+  doIgnore(tint_symbol_10, tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16);
+  uint i0 = (*(tint_symbol_14)).values[min(((3u * triangleIndex) + 0u), ((((*(tint_symbol_13)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*(tint_symbol_14)).values[min(((3u * i0) + 1u), ((((*(tint_symbol_13)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*(tint_symbol_14)).values[min(((3u * i0) + 2u), ((((*(tint_symbol_13)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  float3 p0 = loadPosition(i0, tint_symbol_15, tint_symbol_13);
+  float3 p1 = loadPosition(i0, tint_symbol_15, tint_symbol_13);
+  float3 p2 = loadPosition(i2, tint_symbol_15, tint_symbol_13);
   float3 center = (((p0 + p2) + p1) / 3.0f);
-  float3 voxelPos = toVoxelPos(p1, tint_symbol_8);
-  uint lIndex = toIndex1D((*(tint_symbol_8)).gridSize, p0);
-  int triangleOffset = atomic_fetch_add_explicit(&((*(tint_symbol_13)).values[i1]), 1, memory_order_relaxed);
+  float3 voxelPos = toVoxelPos(p1, tint_symbol_10);
+  uint lIndex = toIndex1D((*(tint_symbol_10)).gridSize, p0);
+  int triangleOffset = atomic_fetch_add_explicit(&((*(tint_symbol_16)).values[min(i1, ((((*(tint_symbol_13)).array_lengths[0u][3u] - 0u) / 4u) - 1u))]), 1, memory_order_relaxed);
 }
 
-kernel void main_count(const constant Uniforms_tint_packed_vec3* tint_symbol_14 [[buffer(0)]], device Dbg* tint_symbol_15 [[buffer(1)]], device AU32s* tint_symbol_16 [[buffer(2)]], device U32s* tint_symbol_17 [[buffer(3)]], device F32s* tint_symbol_18 [[buffer(4)]], device AI32s* tint_symbol_19 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  main_count_inner(GlobalInvocationID, tint_symbol_14, tint_symbol_15, tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19);
+kernel void main_count(const constant Uniforms_tint_packed_vec3* tint_symbol_17 [[buffer(0)]], device Dbg* tint_symbol_18 [[buffer(1)]], device AU32s* tint_symbol_19 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_20 [[buffer(30)]], device U32s* tint_symbol_21 [[buffer(3)]], device F32s* tint_symbol_22 [[buffer(4)]], device AI32s* tint_symbol_23 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  main_count_inner(GlobalInvocationID, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23);
   return;
 }
 
diff --git a/test/tint/bug/chromium/1273230.wgsl.expected.spvasm b/test/tint/bug/chromium/1273230.wgsl.expected.spvasm
index 81f2d4f..1eb05b5 100644
--- a/test/tint/bug/chromium/1273230.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/1273230.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 310
+; Bound: 362
 ; Schema: 0
                OpCapability Shader
          %80 = OpExtInstImport "GLSL.std.450"
@@ -201,25 +201,29 @@
         %148 = OpTypeFunction %v3uint %uint %uint
         %169 = OpTypeFunction %v3float %uint
      %uint_3 = OpConstant %uint 3
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint_0 = OpTypePointer StorageBuffer %_runtimearr_uint_0
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
+%_ptr_StorageBuffer__runtimearr_int = OpTypePointer StorageBuffer %_runtimearr_int
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_Function_int = OpTypePointer Function %int
-        %215 = OpTypeFunction %void %v3uint
+        %251 = OpTypeFunction %void %v3uint
        %bool = OpTypeBool
     %float_3 = OpConstant %float 3
       %int_1 = OpConstant %int 1
-        %278 = OpTypeFunction %uint %uint %uint
-        %292 = OpTypeFunction %v3uint %v3float
-        %296 = OpConstantNull %v3float
+        %330 = OpTypeFunction %uint %uint %uint
+        %344 = OpTypeFunction %v3uint %v3float
+        %348 = OpConstantNull %v3float
      %v3bool = OpTypeVector %bool 3
-        %299 = OpConstantNull %v3uint
+        %351 = OpConstantNull %v3uint
 %float_4_29496704e_09 = OpConstant %float 4.29496704e+09
-        %301 = OpConstantComposite %v3float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
+        %353 = OpConstantComposite %v3float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
 %uint_4294967295 = OpConstant %uint 4294967295
-        %304 = OpConstantComposite %v3uint %uint_4294967295 %uint_4294967295 %uint_4294967295
+        %356 = OpConstantComposite %v3uint %uint_4294967295 %uint_4294967295 %uint_4294967295
 %marg8uintin = OpFunction %void None %34
          %35 = OpLabel
                OpReturn
@@ -360,52 +364,84 @@
  %position_0 = OpVariable %_ptr_Function_v3float Function
         %171 = OpIMul %uint %uint_3 %vertexIndex
         %173 = OpIAdd %uint %171 %uint_0
-        %174 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %173
-        %176 = OpLoad %float %174 None
-        %177 = OpIMul %uint %uint_3 %vertexIndex
-        %178 = OpIAdd %uint %177 %uint_1
+        %174 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %176 = OpArrayLength %uint %positions 0
+        %177 = OpISub %uint %176 %uint_1
+        %178 = OpExtInst %uint %80 UMin %173 %177
         %179 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %178
-        %180 = OpLoad %float %179 None
-        %181 = OpIMul %uint %uint_3 %vertexIndex
-        %182 = OpIAdd %uint %181 %uint_2
-        %183 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %182
-        %184 = OpLoad %float %183 None
-        %185 = OpCompositeConstruct %v3float %176 %180 %184
-               OpStore %position_0 %185
-        %187 = OpLoad %v3float %position_0 None
-               OpReturnValue %187
+        %181 = OpLoad %float %179 None
+        %182 = OpIMul %uint %uint_3 %vertexIndex
+        %183 = OpIAdd %uint %182 %uint_1
+        %184 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %185 = OpArrayLength %uint %positions 0
+        %186 = OpISub %uint %185 %uint_1
+        %187 = OpExtInst %uint %80 UMin %183 %186
+        %188 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %187
+        %189 = OpLoad %float %188 None
+        %190 = OpIMul %uint %uint_3 %vertexIndex
+        %191 = OpIAdd %uint %190 %uint_2
+        %192 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %193 = OpArrayLength %uint %positions 0
+        %194 = OpISub %uint %193 %uint_1
+        %195 = OpExtInst %uint %80 UMin %191 %194
+        %196 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %195
+        %197 = OpLoad %float %196 None
+        %198 = OpCompositeConstruct %v3float %181 %189 %197
+               OpStore %position_0 %198
+        %200 = OpLoad %v3float %position_0 None
+               OpReturnValue %200
                OpFunctionEnd
    %doIgnore = OpFunction %void None %34
-        %189 = OpLabel
+        %202 = OpLabel
         %g43 = OpVariable %_ptr_Function_uint Function
         %kj6 = OpVariable %_ptr_Function_uint Function
         %b53 = OpVariable %_ptr_Function_uint Function
         %rwg = OpVariable %_ptr_Function_uint Function
         %rb5 = OpVariable %_ptr_Function_float Function
         %g55 = OpVariable %_ptr_Function_int Function
-        %190 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-        %191 = OpLoad %uint %190 None
-               OpStore %g43 %191
-        %193 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_5
-        %195 = OpLoad %uint %193 None
-               OpStore %kj6 %195
-        %197 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %int_0
-        %200 = OpAtomicLoad %uint %197 %uint_1 %uint_0
-               OpStore %b53 %200
-        %202 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %int_0
-        %203 = OpLoad %uint %202 None
-               OpStore %rwg %203
-        %205 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %int_0
-        %206 = OpLoad %float %205 None
-               OpStore %rb5 %206
-        %208 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %int_0
-        %210 = OpAtomicLoad %int %208 %uint_1 %uint_0
-               OpStore %g55 %210
+        %203 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+        %204 = OpLoad %uint %203 None
+               OpStore %g43 %204
+        %206 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_5
+        %208 = OpLoad %uint %206 None
+               OpStore %kj6 %208
+        %210 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint_0 %counters %uint_0
+        %212 = OpArrayLength %uint %counters 0
+        %213 = OpISub %uint %212 %uint_1
+        %214 = OpBitcast %uint %int_0
+        %216 = OpExtInst %uint %80 UMin %214 %213
+        %217 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %216
+        %219 = OpAtomicLoad %uint %217 %uint_1 %uint_0
+               OpStore %b53 %219
+        %221 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %223 = OpArrayLength %uint %indices 0
+        %224 = OpISub %uint %223 %uint_1
+        %225 = OpBitcast %uint %int_0
+        %226 = OpExtInst %uint %80 UMin %225 %224
+        %227 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %226
+        %228 = OpLoad %uint %227 None
+               OpStore %rwg %228
+        %230 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %231 = OpArrayLength %uint %positions 0
+        %232 = OpISub %uint %231 %uint_1
+        %233 = OpBitcast %uint %int_0
+        %234 = OpExtInst %uint %80 UMin %233 %232
+        %235 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %234
+        %236 = OpLoad %float %235 None
+               OpStore %rb5 %236
+        %238 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %LUT %uint_0
+        %240 = OpArrayLength %uint %LUT 0
+        %241 = OpISub %uint %240 %uint_1
+        %242 = OpBitcast %uint %int_0
+        %243 = OpExtInst %uint %80 UMin %242 %241
+        %244 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %243
+        %246 = OpAtomicLoad %int %244 %uint_1 %uint_0
+               OpStore %g55 %246
                OpReturn
                OpFunctionEnd
-%main_count_inner = OpFunction %void None %215
+%main_count_inner = OpFunction %void None %251
 %GlobalInvocationID = OpFunctionParameter %v3uint
-        %216 = OpLabel
+        %252 = OpLabel
 %triangleIndex = OpVariable %_ptr_Function_uint Function
          %i0 = OpVariable %_ptr_Function_uint Function
          %i1 = OpVariable %_ptr_Function_uint Function
@@ -417,100 +453,116 @@
  %voxelPos_0 = OpVariable %_ptr_Function_v3float Function
      %lIndex = OpVariable %_ptr_Function_uint Function
 %triangleOffset = OpVariable %_ptr_Function_int Function
-        %217 = OpCompositeExtract %uint %GlobalInvocationID 0
-               OpStore %triangleIndex %217
-        %219 = OpLoad %uint %triangleIndex None
-        %220 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-        %221 = OpLoad %uint %220 None
-        %222 = OpUGreaterThanEqual %bool %219 %221
-               OpSelectionMerge %224 None
-               OpBranchConditional %222 %225 %224
-        %225 = OpLabel
+        %253 = OpCompositeExtract %uint %GlobalInvocationID 0
+               OpStore %triangleIndex %253
+        %255 = OpLoad %uint %triangleIndex None
+        %256 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+        %257 = OpLoad %uint %256 None
+        %258 = OpUGreaterThanEqual %bool %255 %257
+               OpSelectionMerge %260 None
+               OpBranchConditional %258 %261 %260
+        %261 = OpLabel
                OpReturn
-        %224 = OpLabel
-        %226 = OpFunctionCall %void %doIgnore
-        %227 = OpLoad %uint %triangleIndex None
-        %228 = OpIMul %uint %uint_3 %227
-        %229 = OpIAdd %uint %228 %uint_0
-        %230 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %229
-        %231 = OpLoad %uint %230 None
-               OpStore %i0 %231
-        %233 = OpLoad %uint %i0 None
-        %234 = OpIMul %uint %uint_3 %233
-        %235 = OpIAdd %uint %234 %uint_1
-        %236 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %235
-        %237 = OpLoad %uint %236 None
-               OpStore %i1 %237
-        %239 = OpLoad %uint %i0 None
-        %240 = OpIMul %uint %uint_3 %239
-        %241 = OpIAdd %uint %240 %uint_2
-        %242 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %241
-        %243 = OpLoad %uint %242 None
-               OpStore %i2 %243
-        %245 = OpLoad %uint %i0 None
-        %246 = OpFunctionCall %v3float %loadPosition %245
-               OpStore %p0 %246
-        %248 = OpLoad %uint %i0 None
-        %249 = OpFunctionCall %v3float %loadPosition %248
-               OpStore %p1 %249
-        %251 = OpLoad %uint %i2 None
-        %252 = OpFunctionCall %v3float %loadPosition %251
-               OpStore %p2 %252
-        %254 = OpLoad %v3float %p0 None
-        %255 = OpLoad %v3float %p2 None
-        %256 = OpFAdd %v3float %254 %255
-        %257 = OpLoad %v3float %p1 None
-        %258 = OpFAdd %v3float %256 %257
-        %259 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
-        %261 = OpFDiv %v3float %258 %259
-               OpStore %center %261
-        %263 = OpLoad %v3float %p1 None
-        %264 = OpFunctionCall %v3float %toVoxelPos %263
-               OpStore %voxelPos_0 %264
-        %266 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %267 = OpLoad %uint %266 None
-        %268 = OpLoad %v3float %p0 None
-        %269 = OpFunctionCall %uint %toIndex1D %267 %268
-               OpStore %lIndex %269
-        %271 = OpLoad %uint %i1 None
-        %272 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %271
-        %273 = OpAtomicIAdd %int %272 %uint_1 %uint_0 %int_1
-               OpStore %triangleOffset %273
+        %260 = OpLabel
+        %262 = OpFunctionCall %void %doIgnore
+        %263 = OpLoad %uint %triangleIndex None
+        %264 = OpIMul %uint %uint_3 %263
+        %265 = OpIAdd %uint %264 %uint_0
+        %266 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %267 = OpArrayLength %uint %indices 0
+        %268 = OpISub %uint %267 %uint_1
+        %269 = OpExtInst %uint %80 UMin %265 %268
+        %270 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %269
+        %271 = OpLoad %uint %270 None
+               OpStore %i0 %271
+        %273 = OpLoad %uint %i0 None
+        %274 = OpIMul %uint %uint_3 %273
+        %275 = OpIAdd %uint %274 %uint_1
+        %276 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %277 = OpArrayLength %uint %indices 0
+        %278 = OpISub %uint %277 %uint_1
+        %279 = OpExtInst %uint %80 UMin %275 %278
+        %280 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %279
+        %281 = OpLoad %uint %280 None
+               OpStore %i1 %281
+        %283 = OpLoad %uint %i0 None
+        %284 = OpIMul %uint %uint_3 %283
+        %285 = OpIAdd %uint %284 %uint_2
+        %286 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %287 = OpArrayLength %uint %indices 0
+        %288 = OpISub %uint %287 %uint_1
+        %289 = OpExtInst %uint %80 UMin %285 %288
+        %290 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %289
+        %291 = OpLoad %uint %290 None
+               OpStore %i2 %291
+        %293 = OpLoad %uint %i0 None
+        %294 = OpFunctionCall %v3float %loadPosition %293
+               OpStore %p0 %294
+        %296 = OpLoad %uint %i0 None
+        %297 = OpFunctionCall %v3float %loadPosition %296
+               OpStore %p1 %297
+        %299 = OpLoad %uint %i2 None
+        %300 = OpFunctionCall %v3float %loadPosition %299
+               OpStore %p2 %300
+        %302 = OpLoad %v3float %p0 None
+        %303 = OpLoad %v3float %p2 None
+        %304 = OpFAdd %v3float %302 %303
+        %305 = OpLoad %v3float %p1 None
+        %306 = OpFAdd %v3float %304 %305
+        %307 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
+        %309 = OpFDiv %v3float %306 %307
+               OpStore %center %309
+        %311 = OpLoad %v3float %p1 None
+        %312 = OpFunctionCall %v3float %toVoxelPos %311
+               OpStore %voxelPos_0 %312
+        %314 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %315 = OpLoad %uint %314 None
+        %316 = OpLoad %v3float %p0 None
+        %317 = OpFunctionCall %uint %toIndex1D %315 %316
+               OpStore %lIndex %317
+        %319 = OpLoad %uint %i1 None
+        %320 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %LUT %uint_0
+        %321 = OpArrayLength %uint %LUT 0
+        %322 = OpISub %uint %321 %uint_1
+        %323 = OpExtInst %uint %80 UMin %319 %322
+        %324 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %323
+        %325 = OpAtomicIAdd %int %324 %uint_1 %uint_0 %int_1
+               OpStore %triangleOffset %325
                OpReturn
                OpFunctionEnd
-%tint_div_u32 = OpFunction %uint None %278
+%tint_div_u32 = OpFunction %uint None %330
         %lhs = OpFunctionParameter %uint
         %rhs = OpFunctionParameter %uint
-        %279 = OpLabel
-        %280 = OpIEqual %bool %rhs %uint_0
-        %281 = OpSelect %uint %280 %uint_1 %rhs
-        %282 = OpUDiv %uint %lhs %281
-               OpReturnValue %282
+        %331 = OpLabel
+        %332 = OpIEqual %bool %rhs %uint_0
+        %333 = OpSelect %uint %332 %uint_1 %rhs
+        %334 = OpUDiv %uint %lhs %333
+               OpReturnValue %334
                OpFunctionEnd
-%tint_mod_u32 = OpFunction %uint None %278
+%tint_mod_u32 = OpFunction %uint None %330
       %lhs_0 = OpFunctionParameter %uint
       %rhs_0 = OpFunctionParameter %uint
-        %285 = OpLabel
-        %286 = OpIEqual %bool %rhs_0 %uint_0
-        %287 = OpSelect %uint %286 %uint_1 %rhs_0
-        %288 = OpUDiv %uint %lhs_0 %287
-        %289 = OpIMul %uint %288 %287
-        %290 = OpISub %uint %lhs_0 %289
-               OpReturnValue %290
+        %337 = OpLabel
+        %338 = OpIEqual %bool %rhs_0 %uint_0
+        %339 = OpSelect %uint %338 %uint_1 %rhs_0
+        %340 = OpUDiv %uint %lhs_0 %339
+        %341 = OpIMul %uint %340 %339
+        %342 = OpISub %uint %lhs_0 %341
+               OpReturnValue %342
                OpFunctionEnd
-%tint_v3f32_to_v3u32 = OpFunction %v3uint None %292
+%tint_v3f32_to_v3u32 = OpFunction %v3uint None %344
       %value = OpFunctionParameter %v3float
-        %293 = OpLabel
-        %294 = OpConvertFToU %v3uint %value
-        %295 = OpFOrdGreaterThanEqual %v3bool %value %296
-        %298 = OpSelect %v3uint %295 %294 %299
-        %300 = OpFOrdLessThanEqual %v3bool %value %301
-        %303 = OpSelect %v3uint %300 %298 %304
-               OpReturnValue %303
+        %345 = OpLabel
+        %346 = OpConvertFToU %v3uint %value
+        %347 = OpFOrdGreaterThanEqual %v3bool %value %348
+        %350 = OpSelect %v3uint %347 %346 %351
+        %352 = OpFOrdLessThanEqual %v3bool %value %353
+        %355 = OpSelect %v3uint %352 %350 %356
+               OpReturnValue %355
                OpFunctionEnd
  %main_count = OpFunction %void None %34
-        %307 = OpLabel
-        %308 = OpLoad %v3uint %main_count_global_invocation_id_Input None
-        %309 = OpFunctionCall %void %main_count_inner %308
+        %359 = OpLabel
+        %360 = OpLoad %v3uint %main_count_global_invocation_id_Input None
+        %361 = OpFunctionCall %void %main_count_inner %360
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1345468.wgsl.expected.dxc.hlsl
index 6b3556b..43574aa 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.dxc.hlsl
@@ -5,6 +5,6 @@
 
 void f() {
   int i = 1;
-  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[i];
-  int b = int2(0, 1)[i];
+  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[min(uint(i), 3u)];
+  int b = int2(0, 1)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/1345468.wgsl.expected.fxc.hlsl
index 6b3556b..43574aa 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.fxc.hlsl
@@ -5,6 +5,6 @@
 
 void f() {
   int i = 1;
-  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[i];
-  int b = int2(0, 1)[i];
+  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[min(uint(i), 3u)];
+  int b = int2(0, 1)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.glsl b/test/tint/bug/chromium/1345468.wgsl.expected.glsl
index 8843500..a97589a 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.glsl
@@ -2,8 +2,8 @@
 
 void f() {
   int i = 1;
-  vec2 a = mat4x2(vec2(0.0f), vec2(0.0f), vec2(4.0f, 0.0f), vec2(0.0f))[i];
-  int b = ivec2(0, 1)[i];
+  vec2 a = mat4x2(vec2(0.0f), vec2(0.0f), vec2(4.0f, 0.0f), vec2(0.0f))[min(uint(i), 3u)];
+  int b = ivec2(0, 1)[min(uint(i), 1u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1345468.wgsl.expected.ir.dxc.hlsl
index 92ec7b2..28359c7 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.ir.dxc.hlsl
@@ -1,8 +1,8 @@
 
 void f() {
   int i = int(1);
-  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[i];
-  int b = int2(int(0), int(1))[i];
+  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[min(uint(i), 3u)];
+  int b = int2(int(0), int(1))[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1345468.wgsl.expected.ir.fxc.hlsl
index 92ec7b2..28359c7 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.ir.fxc.hlsl
@@ -1,8 +1,8 @@
 
 void f() {
   int i = int(1);
-  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[i];
-  int b = int2(int(0), int(1))[i];
+  float2 a = float4x2((0.0f).xx, (0.0f).xx, float2(4.0f, 0.0f), (0.0f).xx)[min(uint(i), 3u)];
+  int b = int2(int(0), int(1))[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.ir.msl b/test/tint/bug/chromium/1345468.wgsl.expected.ir.msl
index 5fadc62..52a8b9b 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.ir.msl
@@ -3,6 +3,6 @@
 
 void f() {
   int i = 1;
-  float2 a = float4x2(float2(0.0f), float2(0.0f), float2(4.0f, 0.0f), float2(0.0f))[i];
-  int b = int2(0, 1)[i];
+  float2 a = float4x2(float2(0.0f), float2(0.0f), float2(4.0f, 0.0f), float2(0.0f))[min(uint(i), 3u)];
+  int b = int2(0, 1)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.msl b/test/tint/bug/chromium/1345468.wgsl.expected.msl
index c0c1a74..5ba8d18 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 void f() {
   int i = 1;
-  float2 a = float4x2(float2(0.0f), float2(0.0f), float2(4.0f, 0.0f), float2(0.0f))[i];
-  int b = int2(0, 1)[i];
+  float2 a = float4x2(float2(0.0f), float2(0.0f), float2(4.0f, 0.0f), float2(0.0f))[min(uint(i), 3u)];
+  int b = int2(0, 1)[min(uint(i), 1u)];
 }
 
diff --git a/test/tint/bug/chromium/1345468.wgsl.expected.spvasm b/test/tint/bug/chromium/1345468.wgsl.expected.spvasm
index 2f22514..dcdedf5 100644
--- a/test/tint/bug/chromium/1345468.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/1345468.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -27,11 +28,14 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_v2float = OpTypePointer Private %v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
+     %uint_1 = OpConstant %uint 1
       %v2int = OpTypeVector %int 2
       %int_0 = OpConstant %int 0
-         %27 = OpConstantComposite %v2int %int_0 %int_1
+         %35 = OpConstantComposite %v2int %int_0 %int_1
           %f = OpFunction %void None %13
          %14 = OpLabel
           %i = OpVariable %_ptr_Function_int Function
@@ -39,15 +43,19 @@
           %b = OpVariable %_ptr_Function_int Function
                OpStore %i %int_1
          %19 = OpLoad %int %i None
-         %20 = OpAccessChain %_ptr_Private_v2float %1 %19
-         %22 = OpLoad %v2float %20 None
-               OpStore %a %22
-         %25 = OpLoad %int %i None
-         %26 = OpVectorExtractDynamic %int %27 %25
-               OpStore %b %26
+         %21 = OpBitcast %uint %19
+         %22 = OpExtInst %uint %23 UMin %21 %uint_3
+         %25 = OpAccessChain %_ptr_Private_v2float %1 %22
+         %27 = OpLoad %v2float %25 None
+               OpStore %a %27
+         %30 = OpLoad %int %i None
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %23 UMin %31 %uint_1
+         %34 = OpVectorExtractDynamic %int %35 %32
+               OpStore %b %34
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %13
-         %32 = OpLabel
+         %40 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1403752.wgsl.expected.ir.msl b/test/tint/bug/chromium/1403752.wgsl.expected.ir.msl
index 0362f07..e8c2e82 100644
--- a/test/tint/bug/chromium/1403752.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1403752.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void d() {
   int j = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/bug/chromium/1403752.wgsl.expected.msl b/test/tint/bug/chromium/1403752.wgsl.expected.msl
index d427a04..bbfdc8b 100644
--- a/test/tint/bug/chromium/1403752.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1403752.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void d() {
   int j = 0;
   for(; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.glsl b/test/tint/bug/chromium/1405676.wgsl.expected.glsl
index 709e4bc..1c889de 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.glsl
@@ -1,9 +1,21 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 void d() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  texelFetch(arg_0, v, int(0));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(0), v_1);
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  texelFetch(arg_0, v_4, int(v_2));
   float l = 0.14112000167369842529f;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
index 516f7cf..4c6ff02 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.ir.dxc.hlsl
@@ -1,8 +1,14 @@
 
 Texture1D<int4> arg_0 : register(t0);
 void d() {
-  int v = int(int(1));
-  int4 v_1 = int4(arg_0.Load(int2(v, int(int(0)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(0)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  int4 v_5 = int4(arg_0.Load(int2(v_4, int(v_1))));
   float l = 0.14112000167369842529f;
 }
 
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
index 516f7cf..4c6ff02 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.ir.fxc.hlsl
@@ -1,8 +1,14 @@
 
 Texture1D<int4> arg_0 : register(t0);
 void d() {
-  int v = int(int(1));
-  int4 v_1 = int4(arg_0.Load(int2(v, int(int(0)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(0)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  int4 v_5 = int4(arg_0.Load(int2(v_4, int(v_1))));
   float l = 0.14112000167369842529f;
 }
 
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.ir.msl b/test/tint/bug/chromium/1405676.wgsl.expected.ir.msl
index 6d75383..6de5617 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.ir.msl
@@ -6,6 +6,8 @@
 };
 
 void d(tint_module_vars_struct tint_module_vars) {
-  tint_module_vars.arg_0.read(uint(1));
+  min(uint(0), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  tint_module_vars.arg_0.read(min(uint(1), v));
   float const l = 0.14112000167369842529f;
 }
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.msl b/test/tint/bug/chromium/1405676.wgsl.expected.msl
index 6101357..09442b8 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.msl
@@ -1,7 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
-void d() {
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
+void d(texture1d<int, access::sample> tint_symbol) {
+  uint const level_idx = min(0u, (tint_symbol.get_num_mip_levels() - 1u));
+  int4 const tint_phony = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))), 0);
   float const l = 0.14112000167369842529f;
 }
 
diff --git a/test/tint/bug/chromium/1405676.wgsl.expected.spvasm b/test/tint/bug/chromium/1405676.wgsl.expected.spvasm
index b9a06f2..9727ab5 100644
--- a/test/tint/bug/chromium/1405676.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/1405676.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 18
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -20,18 +22,28 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_3 UniformConstant
        %void = OpTypeVoid
           %7 = OpTypeFunction %void
-      %v4int = OpTypeVector %int 4
-      %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_0 = OpConstant %int 0
+      %int_1 = OpConstant %int 1
+      %v4int = OpTypeVector %int 4
       %float = OpTypeFloat 32
           %l = OpConstant %float 0.141120002
           %d = OpFunction %void None %7
           %8 = OpLabel
           %9 = OpLoad %3 %arg_0 None
-         %10 = OpImageFetch %v4int %9 %int_1 Lod %int_0
+         %10 = OpImageQueryLevels %uint %9
+         %12 = OpISub %uint %10 %uint_1
+         %14 = OpBitcast %uint %int_0
+         %16 = OpExtInst %uint %17 UMin %14 %12
+         %18 = OpImageQuerySizeLod %uint %9 %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %17 UMin %20 %19
+         %23 = OpImageFetch %v4int %9 %22 Lod %16
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %7
-         %17 = OpLabel
+         %28 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
index f8c2892..3e39f2d 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.dxc.hlsl
@@ -2,6 +2,13 @@
   return param_0 < 0 ? ceil(param_0) : floor(param_0);
 }
 
+struct Particle {
+  float3 position;
+  float lifetime;
+  float4 color;
+  float2 velocity;
+};
+
 float16_t tint_sinh(float16_t x) {
   return log((x + sqrt(((x * x) + float16_t(1.0h)))));
 }
@@ -84,8 +91,8 @@
 }
 
 tint_symbol_7 vs_main(tint_symbol_6 tint_symbol_5) {
-  VertexInput tint_symbol_12 = {tint_symbol_5.position, tint_symbol_5.color, tint_symbol_5.quad_pos};
-  VertexOutput inner_result_1 = vs_main_inner(tint_symbol_12);
+  VertexInput tint_symbol_21 = {tint_symbol_5.position, tint_symbol_5.color, tint_symbol_5.quad_pos};
+  VertexOutput inner_result_1 = vs_main_inner(tint_symbol_21);
   tint_symbol_7 wrapper_result_1 = (tint_symbol_7)0;
   wrapper_result_1.position = inner_result_1.position;
   wrapper_result_1.color = inner_result_1.color;
@@ -93,13 +100,6 @@
   return wrapper_result_1;
 }
 
-struct Particle {
-  float3 position;
-  float lifetime;
-  float4 color;
-  float2 velocity;
-};
-
 cbuffer cbuffer_sim_params : register(b0) {
   uint4 sim_params[2];
 };
@@ -111,8 +111,8 @@
 };
 
 Particle data_load(uint offset) {
-  Particle tint_symbol_13 = {asfloat(data.Load3((offset + 0u))), asfloat(data.Load((offset + 12u))), asfloat(data.Load4((offset + 16u))), asfloat(data.Load2((offset + 32u)))};
-  return tint_symbol_13;
+  Particle tint_symbol_22 = {asfloat(data.Load3((offset + 0u))), asfloat(data.Load((offset + 12u))), asfloat(data.Load4((offset + 16u))), asfloat(data.Load2((offset + 32u)))};
+  return tint_symbol_22;
 }
 
 void data_store(uint offset, Particle value) {
@@ -123,10 +123,13 @@
 }
 
 void simulate_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_13 = 0u;
+  data.GetDimensions(tint_symbol_13);
+  uint tint_symbol_14 = ((tint_symbol_13 - 0u) / 48u);
   rand_seed = ((asfloat(sim_params[1]).xy * float2(GlobalInvocationID.xy)) * asfloat(sim_params[1]).zw);
   uint idx = GlobalInvocationID.x;
-  Particle particle = data_load((48u * idx));
-  data_store((48u * idx), particle);
+  Particle particle = data_load((48u * min(idx, (tint_symbol_14 - 1u))));
+  data_store((48u * min(idx, (tint_symbol_14 - 1u))), particle);
 }
 
 [numthreads(64, 1, 1)]
@@ -155,14 +158,20 @@
   uint2 tint_tmp;
   tex_out.GetDimensions(tint_tmp.x, tint_tmp.y);
   if (all((coord.xy < uint2(tint_tmp)))) {
+    uint tint_symbol_16 = 0u;
+    buf_in.GetDimensions(tint_symbol_16);
+    uint tint_symbol_17 = ((tint_symbol_16 - 0u) / 4u);
+    uint tint_symbol_19 = 0u;
+    buf_out.GetDimensions(tint_symbol_19);
+    uint tint_symbol_20 = ((tint_symbol_19 - 0u) / 4u);
     uint dst_offset = (coord.x << ((coord.y * ubo[0].x) & 31u));
     uint src_offset = ((coord.x - 2u) + ((coord.y >> 2u) * ubo[0].x));
-    float a = asfloat(buf_in.Load((4u * (src_offset << 0u))));
-    float b = asfloat(buf_in.Load((4u * (src_offset + 1u))));
-    float c = asfloat(buf_in.Load((4u * ((src_offset + 1u) + ubo[0].x))));
-    float d = asfloat(buf_in.Load((4u * ((src_offset + 1u) + ubo[0].x))));
+    float a = asfloat(buf_in.Load((4u * min((src_offset << 0u), (tint_symbol_17 - 1u)))));
+    float b = asfloat(buf_in.Load((4u * min((src_offset + 1u), (tint_symbol_17 - 1u)))));
+    float c = asfloat(buf_in.Load((4u * min(((src_offset + 1u) + ubo[0].x), (tint_symbol_17 - 1u)))));
+    float d = asfloat(buf_in.Load((4u * min(((src_offset + 1u) + ubo[0].x), (tint_symbol_17 - 1u)))));
     float sum = dot(float4(a, b, c, d), (1.0f).xxxx);
-    buf_out.Store((4u * dst_offset), asuint(tint_float_mod(sum, 4.0f)));
+    buf_out.Store((4u * min(dst_offset, (tint_symbol_20 - 1u))), asuint(tint_float_mod(sum, 4.0f)));
     float4 probabilities = (float4(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0f));
     tex_out[int2(coord.xy)] = probabilities;
   }
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.glsl b/test/tint/bug/chromium/1434271.wgsl.expected.glsl
index 9ea1c71..9e751c0 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.glsl
@@ -129,9 +129,11 @@
   vec2 v_2 = (v_1 * vec2(GlobalInvocationID.xy));
   rand_seed = (v_2 * v.inner.seed.zw);
   uint idx = GlobalInvocationID[0u];
-  Particle particle = data.particles[idx];
-  Particle v_3 = particle;
-  tint_store_and_preserve_padding(uint[1](idx), v_3);
+  uint v_3 = min(idx, (uint(data.particles.length()) - 1u));
+  Particle particle = data.particles[v_3];
+  uint v_4 = min(idx, (uint(data.particles.length()) - 1u));
+  Particle v_5 = particle;
+  tint_store_and_preserve_padding(uint[1](v_4), v_5);
 }
 layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -164,14 +166,19 @@
   if (all(lessThan(coord.xy, uvec2(uvec2(imageSize(tex_out)))))) {
     uint dst_offset = (coord[0u] << ((coord[1u] * v.inner.width) & 31u));
     uint src_offset = ((coord[0u] - 2u) + ((coord[1u] >> (2u & 31u)) * v.inner.width));
-    float a = buf_in.weights[(src_offset << (0u & 31u))];
-    float b = buf_in.weights[(src_offset + 1u)];
-    uint v_1 = ((src_offset + 1u) + v.inner.width);
-    float c = buf_in.weights[v_1];
-    uint v_2 = ((src_offset + 1u) + v.inner.width);
-    float d = buf_in.weights[v_2];
+    uint v_1 = min((src_offset << (0u & 31u)), (uint(buf_in.weights.length()) - 1u));
+    float a = buf_in.weights[v_1];
+    uint v_2 = min((src_offset + 1u), (uint(buf_in.weights.length()) - 1u));
+    float b = buf_in.weights[v_2];
+    uint v_3 = ((src_offset + 1u) + v.inner.width);
+    uint v_4 = min(v_3, (uint(buf_in.weights.length()) - 1u));
+    float c = buf_in.weights[v_4];
+    uint v_5 = ((src_offset + 1u) + v.inner.width);
+    uint v_6 = min(v_5, (uint(buf_in.weights.length()) - 1u));
+    float d = buf_in.weights[v_6];
     float sum = dot(vec4(a, b, c, d), vec4(1.0f));
-    buf_out.weights[dst_offset] = tint_float_modulo(sum, 4.0f);
+    uint v_7 = min(dst_offset, (uint(buf_out.weights.length()) - 1u));
+    buf_out.weights[v_7] = tint_float_modulo(sum, 4.0f);
     vec4 probabilities = (vec4(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0f));
     imageStore(tex_out, ivec2(coord.xy), probabilities);
   }
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1434271.wgsl.expected.ir.dxc.hlsl
index ad1d8c7..022c2ea 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.ir.dxc.hlsl
@@ -111,39 +111,54 @@
   float2 v_8 = (v_7 * float2(GlobalInvocationID.xy));
   rand_seed = (v_8 * asfloat(sim_params[1u]).zw);
   uint idx = GlobalInvocationID.x;
-  Particle particle = v_5((0u + (idx * 48u)));
-  Particle v_9 = particle;
-  v_4((0u + (idx * 48u)), v_9);
+  uint v_9 = 0u;
+  data.GetDimensions(v_9);
+  Particle particle = v_5((0u + (min(idx, ((v_9 / 48u) - 1u)) * 48u)));
+  uint v_10 = 0u;
+  data.GetDimensions(v_10);
+  Particle v_11 = particle;
+  v_4((0u + (min(idx, ((v_10 / 48u) - 1u)) * 48u)), v_11);
 }
 
 void export_level_inner(uint3 coord) {
-  uint2 v_10 = (0u).xx;
-  tex_out.GetDimensions(v_10.x, v_10.y);
-  if (all((coord.xy < uint2(v_10)))) {
+  uint2 v_12 = (0u).xx;
+  tex_out.GetDimensions(v_12.x, v_12.y);
+  if (all((coord.xy < uint2(v_12)))) {
     uint dst_offset = (coord.x << ((coord.y * ubo[0u].x) & 31u));
     uint src_offset = ((coord.x - 2u) + ((coord.y >> (2u & 31u)) * ubo[0u].x));
-    float a = asfloat(buf_in.Load((0u + ((src_offset << (0u & 31u)) * 4u))));
-    float b = asfloat(buf_in.Load((0u + ((src_offset + 1u) * 4u))));
-    float c = asfloat(buf_in.Load((0u + (((src_offset + 1u) + ubo[0u].x) * 4u))));
-    float d = asfloat(buf_in.Load((0u + (((src_offset + 1u) + ubo[0u].x) * 4u))));
+    uint v_13 = 0u;
+    buf_in.GetDimensions(v_13);
+    float a = asfloat(buf_in.Load((0u + (min((src_offset << (0u & 31u)), ((v_13 / 4u) - 1u)) * 4u))));
+    uint v_14 = 0u;
+    buf_in.GetDimensions(v_14);
+    float b = asfloat(buf_in.Load((0u + (min((src_offset + 1u), ((v_14 / 4u) - 1u)) * 4u))));
+    uint v_15 = 0u;
+    buf_in.GetDimensions(v_15);
+    float c = asfloat(buf_in.Load((0u + (min(((src_offset + 1u) + ubo[0u].x), ((v_15 / 4u) - 1u)) * 4u))));
+    uint v_16 = 0u;
+    buf_in.GetDimensions(v_16);
+    float d = asfloat(buf_in.Load((0u + (min(((src_offset + 1u) + ubo[0u].x), ((v_16 / 4u) - 1u)) * 4u))));
     float sum = dot(float4(a, b, c, d), (1.0f).xxxx);
-    float v_11 = (sum / 4.0f);
-    buf_out.Store((0u + (dst_offset * 4u)), asuint((sum - ((((v_11 < 0.0f)) ? (ceil(v_11)) : (floor(v_11))) * 4.0f))));
+    uint v_17 = 0u;
+    buf_out.GetDimensions(v_17);
+    uint v_18 = (min(dst_offset, ((v_17 / 4u) - 1u)) * 4u);
+    float v_19 = (sum / 4.0f);
+    buf_out.Store((0u + v_18), asuint((sum - ((((v_19 < 0.0f)) ? (ceil(v_19)) : (floor(v_19))) * 4.0f))));
     float4 probabilities = (float4(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0f));
     tex_out[int2(coord.xy)] = probabilities;
   }
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_outputs v_12 = {vertex_main_inner()};
-  return v_12;
+  vertex_main_outputs v_20 = {vertex_main_inner()};
+  return v_20;
 }
 
 vs_main_outputs vs_main(vs_main_inputs inputs) {
-  VertexInput v_13 = {inputs.VertexInput_position, inputs.VertexInput_color, inputs.VertexInput_quad_pos};
-  VertexOutput v_14 = vs_main_inner(v_13);
-  vs_main_outputs v_15 = {v_14.color, v_14.quad_pos, v_14.position};
-  return v_15;
+  VertexInput v_21 = {inputs.VertexInput_position, inputs.VertexInput_color, inputs.VertexInput_quad_pos};
+  VertexOutput v_22 = vs_main_inner(v_21);
+  vs_main_outputs v_23 = {v_22.color, v_22.quad_pos, v_22.position};
+  return v_23;
 }
 
 [numthreads(64, 1, 1)]
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.ir.msl b/test/tint/bug/chromium/1434271.wgsl.expected.ir.msl
index 905dbd8..0f9025e 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.ir.msl
@@ -70,6 +70,7 @@
   device Buffer* buf_out;
   texture2d<float, access::sample> tex_in;
   texture2d<float, access::write> tex_out;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 struct Particle {
@@ -142,20 +143,20 @@
   float2 const v_4 = (v_3 * float2(GlobalInvocationID.xy));
   (*tint_module_vars.rand_seed) = (v_4 * (*tint_module_vars.sim_params).seed.zw);
   uint const idx = GlobalInvocationID[0u];
-  Particle particle = tint_load_struct_packed_vec3((&(*tint_module_vars.data).particles[idx]));
-  tint_store_and_preserve_padding((&(*tint_module_vars.data).particles[idx]), particle);
+  Particle particle = tint_load_struct_packed_vec3((&(*tint_module_vars.data).particles[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 48u) - 1u))]));
+  tint_store_and_preserve_padding((&(*tint_module_vars.data).particles[min(idx, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 48u) - 1u))]), particle);
 }
 
 void export_level_inner(uint3 coord, tint_module_vars_struct tint_module_vars) {
   if (all((coord.xy < uint2(uint2(tint_module_vars.tex_out.get_width(0u), tint_module_vars.tex_out.get_height(0u)))))) {
     uint const dst_offset = (coord[0u] << ((coord[1u] * (*tint_module_vars.ubo).width) & 31u));
     uint const src_offset = ((coord[0u] - 2u) + ((coord[1u] >> (2u & 31u)) * (*tint_module_vars.ubo).width));
-    float const a = (*tint_module_vars.buf_in).weights[(src_offset << (0u & 31u))];
-    float const b = (*tint_module_vars.buf_in).weights[(src_offset + 1u)];
-    float const c = (*tint_module_vars.buf_in).weights[((src_offset + 1u) + (*tint_module_vars.ubo).width)];
-    float const d = (*tint_module_vars.buf_in).weights[((src_offset + 1u) + (*tint_module_vars.ubo).width)];
+    float const a = (*tint_module_vars.buf_in).weights[min((src_offset << (0u & 31u)), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))];
+    float const b = (*tint_module_vars.buf_in).weights[min((src_offset + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))];
+    float const c = (*tint_module_vars.buf_in).weights[min(((src_offset + 1u) + (*tint_module_vars.ubo).width), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))];
+    float const d = (*tint_module_vars.buf_in).weights[min(((src_offset + 1u) + (*tint_module_vars.ubo).width), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))];
     float const sum = dot(float4(a, b, c, d), float4(1.0f));
-    (*tint_module_vars.buf_out).weights[dst_offset] = fmod(sum, 4.0f);
+    (*tint_module_vars.buf_out).weights[min(dst_offset, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u))] = fmod(sum, 4.0f);
     float4 const probabilities = (float4(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0f));
     tint_module_vars.tex_out.write(probabilities, uint2(int2(coord.xy)));
   }
@@ -177,13 +178,13 @@
   return tint_wrapper_result;
 }
 
-kernel void simulate(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant SimulationParams* sim_params [[buffer(1)]], device Particles_packed_vec3* data [[buffer(2)]]) {
+kernel void simulate(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant SimulationParams* sim_params [[buffer(1)]], device Particles_packed_vec3* data [[buffer(2)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread float2 rand_seed = 0.0f;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.rand_seed=(&rand_seed), .sim_params=sim_params, .data=data};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.rand_seed=(&rand_seed), .sim_params=sim_params, .data=data, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   simulate_inner(GlobalInvocationID, tint_module_vars);
 }
 
-kernel void export_level(uint3 coord [[thread_position_in_grid]], const constant UBO* ubo [[buffer(3)]], const device Buffer* buf_in [[buffer(4)]], device Buffer* buf_out [[buffer(0)]], texture2d<float, access::write> tex_out [[texture(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .buf_in=buf_in, .buf_out=buf_out, .tex_out=tex_out};
+kernel void export_level(uint3 coord [[thread_position_in_grid]], const constant UBO* ubo [[buffer(3)]], const device Buffer* buf_in [[buffer(4)]], device Buffer* buf_out [[buffer(0)]], texture2d<float, access::write> tex_out [[texture(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .buf_in=buf_in, .buf_out=buf_out, .tex_out=tex_out, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   export_level_inner(coord, tint_module_vars);
 }
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.msl b/test/tint/bug/chromium/1434271.wgsl.expected.msl
index 2e42a11..d19b74f 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.msl
@@ -54,6 +54,10 @@
   return result;
 }
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 void asinh_468a48() {
   half arg_0 = 0.0h;
   half res = asinh(arg_0);
@@ -156,16 +160,16 @@
   (*(dest)).velocity = value.velocity;
 }
 
-void simulate_inner(uint3 GlobalInvocationID, thread tint_private_vars_struct* const tint_private_vars, const constant SimulationParams* const tint_symbol_8, device Particles_tint_packed_vec3* const tint_symbol_9) {
+void simulate_inner(uint3 GlobalInvocationID, thread tint_private_vars_struct* const tint_private_vars, const constant SimulationParams* const tint_symbol_8, device Particles_tint_packed_vec3* const tint_symbol_9, const constant TintArrayLengths* const tint_symbol_10) {
   (*(tint_private_vars)).rand_seed = (((*(tint_symbol_8)).seed.xy * float2(GlobalInvocationID.xy)) * (*(tint_symbol_8)).seed.zw);
   uint const idx = GlobalInvocationID[0];
-  Particle particle = tint_unpack_vec3_in_composite((*(tint_symbol_9)).particles[idx]);
-  assign_and_preserve_padding(&((*(tint_symbol_9)).particles[idx]), particle);
+  Particle particle = tint_unpack_vec3_in_composite((*(tint_symbol_9)).particles[min(idx, ((((*(tint_symbol_10)).array_lengths[0u][0u] - 0u) / 48u) - 1u))]);
+  assign_and_preserve_padding(&((*(tint_symbol_9)).particles[min(idx, ((((*(tint_symbol_10)).array_lengths[0u][0u] - 0u) / 48u) - 1u))]), particle);
 }
 
-kernel void simulate(const constant SimulationParams* tint_symbol_10 [[buffer(1)]], device Particles_tint_packed_vec3* tint_symbol_11 [[buffer(2)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+kernel void simulate(const constant SimulationParams* tint_symbol_11 [[buffer(1)]], device Particles_tint_packed_vec3* tint_symbol_12 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_13 [[buffer(30)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  simulate_inner(GlobalInvocationID, &(tint_private_vars), tint_symbol_10, tint_symbol_11);
+  simulate_inner(GlobalInvocationID, &(tint_private_vars), tint_symbol_11, tint_symbol_12, tint_symbol_13);
   return;
 }
 
@@ -177,23 +181,23 @@
   /* 0x0000 */ tint_array<float, 1> weights;
 };
 
-void export_level_inner(uint3 coord, texture2d<float, access::write> tint_symbol_12, const constant UBO* const tint_symbol_13, const device Buffer* const tint_symbol_14, device Buffer* const tint_symbol_15) {
-  if (all((coord.xy < uint2(uint2(tint_symbol_12.get_width(), tint_symbol_12.get_height()))))) {
-    uint const dst_offset = (coord[0] << ((coord[1] * (*(tint_symbol_13)).width) & 31u));
-    uint const src_offset = ((coord[0] - 2u) + ((coord[1] >> 2u) * (*(tint_symbol_13)).width));
-    float const a = (*(tint_symbol_14)).weights[(src_offset << 0u)];
-    float const b = (*(tint_symbol_14)).weights[(src_offset + 1u)];
-    float const c = (*(tint_symbol_14)).weights[((src_offset + 1u) + (*(tint_symbol_13)).width)];
-    float const d = (*(tint_symbol_14)).weights[((src_offset + 1u) + (*(tint_symbol_13)).width)];
+void export_level_inner(uint3 coord, texture2d<float, access::write> tint_symbol_14, const constant UBO* const tint_symbol_15, const device Buffer* const tint_symbol_16, const constant TintArrayLengths* const tint_symbol_17, device Buffer* const tint_symbol_18) {
+  if (all((coord.xy < uint2(uint2(tint_symbol_14.get_width(), tint_symbol_14.get_height()))))) {
+    uint const dst_offset = (coord[0] << ((coord[1] * (*(tint_symbol_15)).width) & 31u));
+    uint const src_offset = ((coord[0] - 2u) + ((coord[1] >> 2u) * (*(tint_symbol_15)).width));
+    float const a = (*(tint_symbol_16)).weights[min((src_offset << 0u), ((((*(tint_symbol_17)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
+    float const b = (*(tint_symbol_16)).weights[min((src_offset + 1u), ((((*(tint_symbol_17)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
+    float const c = (*(tint_symbol_16)).weights[min(((src_offset + 1u) + (*(tint_symbol_15)).width), ((((*(tint_symbol_17)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
+    float const d = (*(tint_symbol_16)).weights[min(((src_offset + 1u) + (*(tint_symbol_15)).width), ((((*(tint_symbol_17)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
     float const sum = dot(float4(a, b, c, d), float4(1.0f));
-    (*(tint_symbol_15)).weights[dst_offset] = fmod(sum, 4.0f);
+    (*(tint_symbol_18)).weights[min(dst_offset, ((((*(tint_symbol_17)).array_lengths[0u][2u] - 0u) / 4u) - 1u))] = fmod(sum, 4.0f);
     float4 const probabilities = (float4(a, (a * b), ((a / b) + c), sum) + fmax(sum, 0.0f));
-    tint_symbol_12.write(probabilities, uint2(int2(coord.xy)));
+    tint_symbol_14.write(probabilities, uint2(int2(coord.xy)));
   }
 }
 
-kernel void export_level(texture2d<float, access::write> tint_symbol_16 [[texture(0)]], const constant UBO* tint_symbol_17 [[buffer(3)]], const device Buffer* tint_symbol_18 [[buffer(4)]], device Buffer* tint_symbol_19 [[buffer(0)]], uint3 coord [[thread_position_in_grid]]) {
-  export_level_inner(coord, tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19);
+kernel void export_level(texture2d<float, access::write> tint_symbol_19 [[texture(0)]], const constant UBO* tint_symbol_20 [[buffer(3)]], const device Buffer* tint_symbol_21 [[buffer(4)]], const constant TintArrayLengths* tint_symbol_22 [[buffer(30)]], device Buffer* tint_symbol_23 [[buffer(0)]], uint3 coord [[thread_position_in_grid]]) {
+  export_level_inner(coord, tint_symbol_19, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23);
   return;
 }
 
diff --git a/test/tint/bug/chromium/1434271.wgsl.expected.spvasm b/test/tint/bug/chromium/1434271.wgsl.expected.spvasm
index 957db0a..770e4b1 100644
--- a/test/tint/bug/chromium/1434271.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/1434271.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 265
+; Bound: 296
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
@@ -256,6 +256,7 @@
         %131 = OpTypeFunction %void %v3uint
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
      %v2uint = OpTypeVector %uint 2
+%_ptr_StorageBuffer__runtimearr_Particle = OpTypePointer StorageBuffer %_runtimearr_Particle
 %_ptr_StorageBuffer_Particle = OpTypePointer StorageBuffer %Particle
 %_ptr_Function_Particle = OpTypePointer Function %Particle
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
@@ -263,14 +264,16 @@
      %v2bool = OpTypeVector %bool 2
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
     %uint_31 = OpConstant %uint 31
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-        %208 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+        %234 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_StorageBuffer__runtimearr_float_0 = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float_0 = OpTypePointer StorageBuffer %float
     %float_4 = OpConstant %float 4
     %float_0 = OpConstant %float 0
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
-        %229 = OpTypeFunction %void %_arr_uint_uint_1 %Particle
+        %260 = OpTypeFunction %void %_arr_uint_uint_1 %Particle
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
@@ -352,131 +355,159 @@
         %144 = OpFMul %v2float %140 %143
                OpStore %rand_seed %144 None
         %idx = OpCompositeExtract %uint %GlobalInvocationID 0
-        %146 = OpAccessChain %_ptr_StorageBuffer_Particle %data %uint_0 %idx
-        %148 = OpLoad %Particle %146 None
-               OpStore %particle %148
-        %151 = OpLoad %Particle %particle None
-        %153 = OpCompositeConstruct %_arr_uint_uint_1 %idx
-        %154 = OpFunctionCall %void %tint_store_and_preserve_padding %153 %151
+        %146 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Particle %data %uint_0
+        %148 = OpArrayLength %uint %data 0
+        %149 = OpISub %uint %148 %uint_1
+        %150 = OpExtInst %uint %71 UMin %idx %149
+        %151 = OpAccessChain %_ptr_StorageBuffer_Particle %data %uint_0 %150
+        %153 = OpLoad %Particle %151 None
+               OpStore %particle %153
+        %156 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Particle %data %uint_0
+        %157 = OpArrayLength %uint %data 0
+        %158 = OpISub %uint %157 %uint_1
+        %159 = OpExtInst %uint %71 UMin %idx %158
+        %160 = OpLoad %Particle %particle None
+        %162 = OpCompositeConstruct %_arr_uint_uint_1 %159
+        %163 = OpFunctionCall %void %tint_store_and_preserve_padding %162 %160
                OpReturn
                OpFunctionEnd
 %export_level_inner = OpFunction %void None %131
       %coord = OpFunctionParameter %v3uint
-        %158 = OpLabel
-        %159 = OpVectorShuffle %v2uint %coord %coord 0 1
-        %160 = OpLoad %41 %tex_out None
-        %161 = OpImageQuerySize %v2uint %160
-        %162 = OpULessThan %v2bool %159 %161
-        %165 = OpAll %bool %162
-               OpSelectionMerge %166 None
-               OpBranchConditional %165 %167 %166
         %167 = OpLabel
-        %168 = OpCompositeExtract %uint %coord 0
-        %169 = OpCompositeExtract %uint %coord 1
-        %170 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
-        %172 = OpLoad %uint %170 None
-        %173 = OpIMul %uint %169 %172
-        %174 = OpBitwiseAnd %uint %173 %uint_31
- %dst_offset = OpShiftLeftLogical %uint %168 %174
+        %168 = OpVectorShuffle %v2uint %coord %coord 0 1
+        %169 = OpLoad %41 %tex_out None
+        %170 = OpImageQuerySize %v2uint %169
+        %171 = OpULessThan %v2bool %168 %170
+        %174 = OpAll %bool %171
+               OpSelectionMerge %175 None
+               OpBranchConditional %174 %176 %175
+        %176 = OpLabel
         %177 = OpCompositeExtract %uint %coord 0
-        %178 = OpISub %uint %177 %uint_2
-        %179 = OpCompositeExtract %uint %coord 1
-        %180 = OpBitwiseAnd %uint %uint_2 %uint_31
-        %181 = OpShiftRightLogical %uint %179 %180
-        %182 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
-        %183 = OpLoad %uint %182 None
-        %184 = OpIMul %uint %181 %183
- %src_offset = OpIAdd %uint %178 %184
-        %186 = OpBitwiseAnd %uint %uint_0 %uint_31
-        %187 = OpShiftLeftLogical %uint %src_offset %186
-        %188 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %187
-          %a = OpLoad %float %188 None
-        %191 = OpIAdd %uint %src_offset %uint_1
-        %192 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %191
-          %b = OpLoad %float %192 None
-        %194 = OpIAdd %uint %src_offset %uint_1
-        %195 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
-        %196 = OpLoad %uint %195 None
-        %197 = OpIAdd %uint %194 %196
-        %198 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %197
-          %c = OpLoad %float %198 None
-        %200 = OpIAdd %uint %src_offset %uint_1
-        %201 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
-        %202 = OpLoad %uint %201 None
-        %203 = OpIAdd %uint %200 %202
-        %204 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %203
-          %d = OpLoad %float %204 None
-        %206 = OpCompositeConstruct %v4float %a %b %c %d
-        %sum = OpDot %float %206 %208
-        %209 = OpAccessChain %_ptr_StorageBuffer_float_0 %buf_out %uint_0 %dst_offset
-        %211 = OpFRem %float %sum %float_4
-               OpStore %209 %211 None
-        %213 = OpFMul %float %a %b
-        %214 = OpFDiv %float %a %b
-        %215 = OpFAdd %float %214 %c
-        %216 = OpCompositeConstruct %v4float %a %213 %215 %sum
-        %217 = OpExtInst %float %71 FMax %sum %float_0
-        %219 = OpCompositeConstruct %v4float %217 %217 %217 %217
-%probabilities = OpFAdd %v4float %216 %219
-        %221 = OpLoad %41 %tex_out None
-        %222 = OpVectorShuffle %v2uint %coord %coord 0 1
-        %225 = OpBitcast %v2int %222
-               OpImageWrite %221 %225 %probabilities None
-               OpBranch %166
-        %166 = OpLabel
+        %178 = OpCompositeExtract %uint %coord 1
+        %179 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
+        %181 = OpLoad %uint %179 None
+        %182 = OpIMul %uint %178 %181
+        %183 = OpBitwiseAnd %uint %182 %uint_31
+ %dst_offset = OpShiftLeftLogical %uint %177 %183
+        %186 = OpCompositeExtract %uint %coord 0
+        %187 = OpISub %uint %186 %uint_2
+        %188 = OpCompositeExtract %uint %coord 1
+        %189 = OpBitwiseAnd %uint %uint_2 %uint_31
+        %190 = OpShiftRightLogical %uint %188 %189
+        %191 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
+        %192 = OpLoad %uint %191 None
+        %193 = OpIMul %uint %190 %192
+ %src_offset = OpIAdd %uint %187 %193
+        %195 = OpBitwiseAnd %uint %uint_0 %uint_31
+        %196 = OpShiftLeftLogical %uint %src_offset %195
+        %197 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %buf_in %uint_0
+        %199 = OpArrayLength %uint %buf_in 0
+        %200 = OpISub %uint %199 %uint_1
+        %201 = OpExtInst %uint %71 UMin %196 %200
+        %202 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %201
+          %a = OpLoad %float %202 None
+        %205 = OpIAdd %uint %src_offset %uint_1
+        %206 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %buf_in %uint_0
+        %207 = OpArrayLength %uint %buf_in 0
+        %208 = OpISub %uint %207 %uint_1
+        %209 = OpExtInst %uint %71 UMin %205 %208
+        %210 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %209
+          %b = OpLoad %float %210 None
+        %212 = OpIAdd %uint %src_offset %uint_1
+        %213 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
+        %214 = OpLoad %uint %213 None
+        %215 = OpIAdd %uint %212 %214
+        %216 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %buf_in %uint_0
+        %217 = OpArrayLength %uint %buf_in 0
+        %218 = OpISub %uint %217 %uint_1
+        %219 = OpExtInst %uint %71 UMin %215 %218
+        %220 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %219
+          %c = OpLoad %float %220 None
+        %222 = OpIAdd %uint %src_offset %uint_1
+        %223 = OpAccessChain %_ptr_Uniform_uint %25 %uint_0 %uint_0
+        %224 = OpLoad %uint %223 None
+        %225 = OpIAdd %uint %222 %224
+        %226 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %buf_in %uint_0
+        %227 = OpArrayLength %uint %buf_in 0
+        %228 = OpISub %uint %227 %uint_1
+        %229 = OpExtInst %uint %71 UMin %225 %228
+        %230 = OpAccessChain %_ptr_StorageBuffer_float %buf_in %uint_0 %229
+          %d = OpLoad %float %230 None
+        %232 = OpCompositeConstruct %v4float %a %b %c %d
+        %sum = OpDot %float %232 %234
+        %235 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float_0 %buf_out %uint_0
+        %237 = OpArrayLength %uint %buf_out 0
+        %238 = OpISub %uint %237 %uint_1
+        %239 = OpExtInst %uint %71 UMin %dst_offset %238
+        %240 = OpAccessChain %_ptr_StorageBuffer_float_0 %buf_out %uint_0 %239
+        %242 = OpFRem %float %sum %float_4
+               OpStore %240 %242 None
+        %244 = OpFMul %float %a %b
+        %245 = OpFDiv %float %a %b
+        %246 = OpFAdd %float %245 %c
+        %247 = OpCompositeConstruct %v4float %a %244 %246 %sum
+        %248 = OpExtInst %float %71 FMax %sum %float_0
+        %250 = OpCompositeConstruct %v4float %248 %248 %248 %248
+%probabilities = OpFAdd %v4float %247 %250
+        %252 = OpLoad %41 %tex_out None
+        %253 = OpVectorShuffle %v2uint %coord %coord 0 1
+        %256 = OpBitcast %v2int %253
+               OpImageWrite %252 %256 %probabilities None
+               OpBranch %175
+        %175 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %229
+%tint_store_and_preserve_padding = OpFunction %void None %260
 %target_indices = OpFunctionParameter %_arr_uint_uint_1
 %value_param = OpFunctionParameter %Particle
-        %230 = OpLabel
-        %231 = OpCompositeExtract %uint %target_indices 0
-        %232 = OpAccessChain %_ptr_StorageBuffer_v3float %data %uint_0 %231 %uint_0
-        %234 = OpCompositeExtract %v3float %value_param 0
-               OpStore %232 %234 None
-        %235 = OpAccessChain %_ptr_StorageBuffer_float_0 %data %uint_0 %231 %uint_1
-        %236 = OpCompositeExtract %float %value_param 1
-               OpStore %235 %236 None
-        %237 = OpAccessChain %_ptr_StorageBuffer_v4float %data %uint_0 %231 %uint_2
-        %239 = OpCompositeExtract %v4float %value_param 2
-               OpStore %237 %239 None
-        %240 = OpAccessChain %_ptr_StorageBuffer_v2float %data %uint_0 %231 %uint_3
-        %243 = OpCompositeExtract %v2float %value_param 3
-               OpStore %240 %243 None
+        %261 = OpLabel
+        %262 = OpCompositeExtract %uint %target_indices 0
+        %263 = OpAccessChain %_ptr_StorageBuffer_v3float %data %uint_0 %262 %uint_0
+        %265 = OpCompositeExtract %v3float %value_param 0
+               OpStore %263 %265 None
+        %266 = OpAccessChain %_ptr_StorageBuffer_float_0 %data %uint_0 %262 %uint_1
+        %267 = OpCompositeExtract %float %value_param 1
+               OpStore %266 %267 None
+        %268 = OpAccessChain %_ptr_StorageBuffer_v4float %data %uint_0 %262 %uint_2
+        %270 = OpCompositeExtract %v4float %value_param 2
+               OpStore %268 %270 None
+        %271 = OpAccessChain %_ptr_StorageBuffer_v2float %data %uint_0 %262 %uint_3
+        %274 = OpCompositeExtract %v2float %value_param 3
+               OpStore %271 %274 None
                OpReturn
                OpFunctionEnd
 %vertex_main = OpFunction %void None %63
-        %245 = OpLabel
-        %246 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %vertex_main_position_Output %246 None
+        %276 = OpLabel
+        %277 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %vertex_main_position_Output %277 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
     %vs_main = OpFunction %void None %63
-        %248 = OpLabel
-        %249 = OpLoad %v3float %vs_main_loc0_Input None
-        %250 = OpLoad %v4float %vs_main_loc1_Input None
-        %251 = OpLoad %v2float %vs_main_loc2_Input None
-        %252 = OpCompositeConstruct %VertexInput %249 %250 %251
-        %253 = OpFunctionCall %VertexOutput %vs_main_inner %252
-        %254 = OpCompositeExtract %v4float %253 0
-               OpStore %vs_main_position_Output %254 None
-        %255 = OpCompositeExtract %v4float %253 1
-               OpStore %vs_main_loc0_Output %255 None
-        %256 = OpCompositeExtract %v2float %253 2
-               OpStore %vs_main_loc1_Output %256 None
+        %279 = OpLabel
+        %280 = OpLoad %v3float %vs_main_loc0_Input None
+        %281 = OpLoad %v4float %vs_main_loc1_Input None
+        %282 = OpLoad %v2float %vs_main_loc2_Input None
+        %283 = OpCompositeConstruct %VertexInput %280 %281 %282
+        %284 = OpFunctionCall %VertexOutput %vs_main_inner %283
+        %285 = OpCompositeExtract %v4float %284 0
+               OpStore %vs_main_position_Output %285 None
+        %286 = OpCompositeExtract %v4float %284 1
+               OpStore %vs_main_loc0_Output %286 None
+        %287 = OpCompositeExtract %v2float %284 2
+               OpStore %vs_main_loc1_Output %287 None
                OpStore %vs_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
    %simulate = OpFunction %void None %63
-        %258 = OpLabel
-        %259 = OpLoad %v3uint %simulate_global_invocation_id_Input None
-        %260 = OpFunctionCall %void %simulate_inner %259
+        %289 = OpLabel
+        %290 = OpLoad %v3uint %simulate_global_invocation_id_Input None
+        %291 = OpFunctionCall %void %simulate_inner %290
                OpReturn
                OpFunctionEnd
 %export_level = OpFunction %void None %63
-        %262 = OpLabel
-        %263 = OpLoad %v3uint %export_level_global_invocation_id_Input None
-        %264 = OpFunctionCall %void %export_level_inner %263
+        %293 = OpLabel
+        %294 = OpLoad %v3uint %export_level_global_invocation_id_Input None
+        %295 = OpFunctionCall %void %export_level_inner %294
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1442551.wgsl.expected.dxc.hlsl
index 22ea0d0..99ae751 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 void f() {
   int i = 1;
-  int b = int2(1, 2)[i];
+  int b = int2(1, 2)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/1442551.wgsl.expected.fxc.hlsl
index 22ea0d0..99ae751 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 void f() {
   int i = 1;
-  int b = int2(1, 2)[i];
+  int b = int2(1, 2)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.glsl b/test/tint/bug/chromium/1442551.wgsl.expected.glsl
index 8b5a970..12596d0 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 void f() {
   int i = 1;
-  int b = ivec2(1, 2)[i];
+  int b = ivec2(1, 2)[min(uint(i), 1u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/1442551.wgsl.expected.ir.dxc.hlsl
index 03a804d..4557ae9 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 void f() {
   int i = int(1);
-  int b = int2(int(1), int(2))[i];
+  int b = int2(int(1), int(2))[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/1442551.wgsl.expected.ir.fxc.hlsl
index 03a804d..4557ae9 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 void f() {
   int i = int(1);
-  int b = int2(int(1), int(2))[i];
+  int b = int2(int(1), int(2))[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.ir.msl b/test/tint/bug/chromium/1442551.wgsl.expected.ir.msl
index c7f2058..7fa14f7 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 void f() {
   int const i = 1;
-  int b = int2(1, 2)[i];
+  int b = int2(1, 2)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.msl b/test/tint/bug/chromium/1442551.wgsl.expected.msl
index 2f68586..ff944da 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 void f() {
   int const i = 1;
-  int b = int2(1, 2)[i];
+  int b = int2(1, 2)[min(uint(i), 1u)];
 }
 
diff --git a/test/tint/bug/chromium/1442551.wgsl.expected.spvasm b/test/tint/bug/chromium/1442551.wgsl.expected.spvasm
index e2895d7..5747ad5 100644
--- a/test/tint/bug/chromium/1442551.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/1442551.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 15
+; Bound: 20
 ; Schema: 0
                OpCapability Shader
+         %10 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -15,18 +16,22 @@
           %3 = OpTypeFunction %void
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %v2int = OpTypeVector %int 2
       %int_2 = OpConstant %int 2
-          %8 = OpConstantComposite %v2int %i %int_2
+         %13 = OpConstantComposite %v2int %i %int_2
 %_ptr_Function_int = OpTypePointer Function %int
           %f = OpFunction %void None %3
           %4 = OpLabel
           %b = OpVariable %_ptr_Function_int Function
-          %7 = OpVectorExtractDynamic %int %8 %i
-               OpStore %b %7
+          %8 = OpBitcast %uint %i
+          %9 = OpExtInst %uint %10 UMin %8 %uint_1
+         %12 = OpVectorExtractDynamic %int %13 %9
+               OpStore %b %12
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %3
-         %14 = OpLabel
+         %19 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/1449538.wgsl.expected.ir.msl b/test/tint/bug/chromium/1449538.wgsl.expected.ir.msl
index d0ebe5e..b6f1da3 100644
--- a/test/tint/bug/chromium/1449538.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/1449538.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int i0520 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
@@ -17,6 +21,7 @@
   {
     int i62 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       if (false) {
       } else {
         break;
@@ -29,6 +34,7 @@
   {
     int i0520 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_2)
       if (false) {
       } else {
         break;
@@ -41,6 +47,7 @@
   {
     int i62 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_3)
       if (false) {
       } else {
         break;
@@ -53,6 +60,7 @@
   {
     int i62 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_4)
       if (false) {
       } else {
         break;
@@ -65,6 +73,7 @@
   {
     int i60 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_5)
       if (false) {
       } else {
         break;
@@ -77,6 +86,7 @@
   {
     int i62 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_6)
       if (false) {
       } else {
         break;
@@ -89,6 +99,7 @@
   {
     int i60 = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_7)
       if (false) {
       } else {
         break;
diff --git a/test/tint/bug/chromium/1449538.wgsl.expected.msl b/test/tint/bug/chromium/1449538.wgsl.expected.msl
index 81a4429..be2c460 100644
--- a/test/tint/bug/chromium/1449538.wgsl.expected.msl
+++ b/test/tint/bug/chromium/1449538.wgsl.expected.msl
@@ -1,22 +1,34 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   for(int i0520 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
   for(int i62 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
   }
   for(int i0520 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_2);
   }
   for(int i62 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_3);
   }
   for(int i62 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_4);
   }
   for(int i60 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_5);
   }
   for(int i62 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_6);
   }
   for(int i60 = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false_7);
   }
 }
 
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/344265982.wgsl.expected.dxc.hlsl
index ed83a31..f1d22c8 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.dxc.hlsl
@@ -5,13 +5,13 @@
   {
     for(int i = 0; (i < 4); i = (i + 1)) {
       tint_continue = false;
-      switch(asint(buffer.Load((4u * uint(i))))) {
+      switch(asint(buffer.Load((4u * min(uint(i), 3u))))) {
         case 1: {
           tint_continue = true;
           break;
         }
         default: {
-          buffer.Store((4u * uint(i)), asuint(2));
+          buffer.Store((4u * min(uint(i), 3u)), asuint(2));
           break;
         }
       }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/344265982.wgsl.expected.fxc.hlsl
index ed83a31..f1d22c8 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.fxc.hlsl
@@ -5,13 +5,13 @@
   {
     for(int i = 0; (i < 4); i = (i + 1)) {
       tint_continue = false;
-      switch(asint(buffer.Load((4u * uint(i))))) {
+      switch(asint(buffer.Load((4u * min(uint(i), 3u))))) {
         case 1: {
           tint_continue = true;
           break;
         }
         default: {
-          buffer.Store((4u * uint(i)), asuint(2));
+          buffer.Store((4u * min(uint(i), 3u)), asuint(2));
           break;
         }
       }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.glsl b/test/tint/bug/chromium/344265982.wgsl.expected.glsl
index 06be1e3..25ff013 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.glsl
@@ -14,7 +14,7 @@
       } else {
         break;
       }
-      int v_1 = i;
+      uint v_1 = min(uint(i), 3u);
       bool tint_continue = false;
       switch(v.inner[v_1]) {
         case 1:
@@ -24,7 +24,7 @@
         }
         default:
         {
-          int v_2 = i;
+          uint v_2 = min(uint(i), 3u);
           v.inner[v_2] = 2;
           break;
         }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/344265982.wgsl.expected.ir.dxc.hlsl
index fec9e75..eae6651 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.ir.dxc.hlsl
@@ -9,7 +9,7 @@
         break;
       }
       bool tint_continue = false;
-      switch(asint(buffer.Load((0u + (uint(i) * 4u))))) {
+      switch(asint(buffer.Load((0u + (min(uint(i), 3u) * 4u))))) {
         case int(1):
         {
           tint_continue = true;
@@ -17,7 +17,7 @@
         }
         default:
         {
-          buffer.Store((0u + (uint(i) * 4u)), asuint(int(2)));
+          buffer.Store((0u + (min(uint(i), 3u) * 4u)), asuint(int(2)));
           break;
         }
       }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/344265982.wgsl.expected.ir.fxc.hlsl
index fec9e75..eae6651 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.ir.fxc.hlsl
@@ -9,7 +9,7 @@
         break;
       }
       bool tint_continue = false;
-      switch(asint(buffer.Load((0u + (uint(i) * 4u))))) {
+      switch(asint(buffer.Load((0u + (min(uint(i), 3u) * 4u))))) {
         case int(1):
         {
           tint_continue = true;
@@ -17,7 +17,7 @@
         }
         default:
         {
-          buffer.Store((0u + (uint(i) * 4u)), asuint(int(2)));
+          buffer.Store((0u + (min(uint(i), 3u) * 4u)), asuint(int(2)));
           break;
         }
       }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.ir.msl b/test/tint/bug/chromium/344265982.wgsl.expected.ir.msl
index ba10e70..817e5dd 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.ir.msl
@@ -26,7 +26,7 @@
         break;
       }
       bool tint_continue = false;
-      switch((*arg)[i]) {
+      switch((*arg)[min(uint(i), 3u)]) {
         case 1:
         {
           tint_continue = true;
@@ -34,7 +34,7 @@
         }
         default:
         {
-          (*arg)[i] = 2;
+          (*arg)[min(uint(i), 3u)] = 2;
           break;
         }
       }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.msl b/test/tint/bug/chromium/344265982.wgsl.expected.msl
index dcd8732..19834ac 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.msl
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.msl
@@ -14,17 +14,21 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void foo(device tint_array<int, 4>* const arg) {
   bool tint_continue = false;
   for(int i = 0; (i < 4); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
-    switch((*(arg))[i]) {
+    switch((*(arg))[min(uint(i), 3u)]) {
       case 1: {
         tint_continue = true;
         break;
       }
       default: {
-        (*(arg))[i] = 2;
+        (*(arg))[min(uint(i), 3u)] = 2;
         break;
       }
     }
diff --git a/test/tint/bug/chromium/344265982.wgsl.expected.spvasm b/test/tint/bug/chromium/344265982.wgsl.expected.spvasm
index 9dca7b7..65876c3 100644
--- a/test/tint/bug/chromium/344265982.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/344265982.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main"
                OpExecutionMode %main OriginUpperLeft
@@ -31,6 +32,7 @@
       %int_0 = OpConstant %int 0
       %int_4 = OpConstant %int 4
        %bool = OpTypeBool
+     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_0 = OpConstant %uint 0
       %int_2 = OpConstant %int 2
@@ -54,29 +56,33 @@
                OpBranch %16
          %24 = OpLabel
          %26 = OpLoad %int %i None
-         %27 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %26
-         %30 = OpLoad %int %27 None
-               OpSelectionMerge %33 None
-               OpSwitch %30 %31 1 %32
-         %32 = OpLabel
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_3
+         %31 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %28
+         %34 = OpLoad %int %31 None
+               OpSelectionMerge %37 None
+               OpSwitch %34 %35 1 %36
+         %36 = OpLabel
                OpBranch %14
-         %31 = OpLabel
-         %34 = OpLoad %int %i None
-         %35 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %34
-               OpStore %35 %int_2 None
-               OpBranch %33
-         %33 = OpLabel
+         %35 = OpLabel
+         %38 = OpLoad %int %i None
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %29 UMin %39 %uint_3
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %40
+               OpStore %41 %int_2 None
+               OpBranch %37
+         %37 = OpLabel
                OpBranch %14
          %14 = OpLabel
-         %37 = OpLoad %int %i None
-         %38 = OpIAdd %int %37 %int_1
-               OpStore %i %38 None
+         %43 = OpLoad %int %i None
+         %44 = OpIAdd %int %43 %int_1
+               OpStore %i %44 None
                OpBranch %15
          %16 = OpLabel
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %10
-         %41 = OpLabel
-         %42 = OpFunctionCall %void %foo
+         %47 = OpLabel
+         %48 = OpFunctionCall %void %foo
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/chromium/378541479.wgsl b/test/tint/bug/chromium/378541479.wgsl
index 8badf52..e019ef8 100644
--- a/test/tint/bug/chromium/378541479.wgsl
+++ b/test/tint/bug/chromium/378541479.wgsl
@@ -1,5 +1,3 @@
-// flags: --transform robustness
-
 @group(0) @binding(0) var<uniform> level : u32;
 @group(0) @binding(1) var<uniform> coords : vec2<u32>;
 @group(0) @binding(2) var tex: texture_depth_2d;
diff --git a/test/tint/bug/chromium/40943165.wgsl.expected.glsl b/test/tint/bug/chromium/40943165.wgsl.expected.glsl
index e30660d..7d6121b 100644
--- a/test/tint/bug/chromium/40943165.wgsl.expected.glsl
+++ b/test/tint/bug/chromium/40943165.wgsl.expected.glsl
@@ -6,7 +6,7 @@
     W = mat2(vec2(0.0f), vec2(0.0f));
   }
   barrier();
-  W[0] = (W[0] + 0.0f);
+  W[0u] = (W[0u] + 0.0f);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/chromium/40943165.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/chromium/40943165.wgsl.expected.ir.dxc.hlsl
index 75cd365..8626f8d 100644
--- a/test/tint/bug/chromium/40943165.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/chromium/40943165.wgsl.expected.ir.dxc.hlsl
@@ -9,7 +9,7 @@
     W = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  W[int(0)] = (W[int(0)] + 0.0f);
+  W[0u] = (W[0u] + 0.0f);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/40943165.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/chromium/40943165.wgsl.expected.ir.fxc.hlsl
index 75cd365..8626f8d 100644
--- a/test/tint/bug/chromium/40943165.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/chromium/40943165.wgsl.expected.ir.fxc.hlsl
@@ -9,7 +9,7 @@
     W = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  W[int(0)] = (W[int(0)] + 0.0f);
+  W[0u] = (W[0u] + 0.0f);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/chromium/40943165.wgsl.expected.ir.msl b/test/tint/bug/chromium/40943165.wgsl.expected.ir.msl
index aa9c206..5ea09eb 100644
--- a/test/tint/bug/chromium/40943165.wgsl.expected.ir.msl
+++ b/test/tint/bug/chromium/40943165.wgsl.expected.ir.msl
@@ -14,7 +14,7 @@
     (*tint_module_vars.W) = float2x2(float2(0.0f), float2(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  (*tint_module_vars.W)[0] = ((*tint_module_vars.W)[0] + 0.0f);
+  (*tint_module_vars.W)[0u] = ((*tint_module_vars.W)[0u] + 0.0f);
 }
 
 kernel void F(uint mat2x2 [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v [[threadgroup(0)]]) {
diff --git a/test/tint/bug/chromium/40943165.wgsl.expected.spvasm b/test/tint/bug/chromium/40943165.wgsl.expected.spvasm
index 99ffd3a..6c2ff9f 100644
--- a/test/tint/bug/chromium/40943165.wgsl.expected.spvasm
+++ b/test/tint/bug/chromium/40943165.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -29,10 +29,9 @@
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
     %float_0 = OpConstant %float 0
-         %32 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
     %F_inner = OpFunction %void None %12
      %mat2x2 = OpFunctionParameter %uint
          %13 = OpLabel
@@ -44,16 +43,16 @@
                OpBranch %17
          %17 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %23 = OpAccessChain %_ptr_Workgroup_v2float %W %int_0
-         %27 = OpLoad %v2float %23 None
-         %28 = OpCompositeConstruct %v2float %float_0 %float_0
-         %30 = OpFAdd %v2float %27 %28
-               OpStore %23 %30 None
+         %23 = OpAccessChain %_ptr_Workgroup_v2float %W %uint_0
+         %26 = OpLoad %v2float %23 None
+         %27 = OpCompositeConstruct %v2float %float_0 %float_0
+         %29 = OpFAdd %v2float %26 %27
+               OpStore %23 %29 None
                OpReturn
                OpFunctionEnd
-          %F = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpLoad %uint %F_local_invocation_index_Input None
-         %35 = OpFunctionCall %void %F_inner %34
+          %F = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpLoad %uint %F_local_invocation_index_Input None
+         %34 = OpFunctionCall %void %F_inner %33
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/dawn/947.wgsl.expected.dxc.hlsl b/test/tint/bug/dawn/947.wgsl.expected.dxc.hlsl
index 6a203d8..50d08b6 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/dawn/947.wgsl.expected.dxc.hlsl
@@ -17,12 +17,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex) {
   float2 texcoord[3] = {float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = (VertexOutputs)0;
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
   bool flipY = (asfloat(uniforms[0].y) < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw));
   }
   return output;
 }
diff --git a/test/tint/bug/dawn/947.wgsl.expected.fxc.hlsl b/test/tint/bug/dawn/947.wgsl.expected.fxc.hlsl
index 8259eb7..8c26af6 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/dawn/947.wgsl.expected.fxc.hlsl
@@ -19,12 +19,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex) {
   float2 texcoord[3] = {float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = (VertexOutputs)0;
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
   bool flipY = (asfloat(uniforms[0].y) < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0].xy)) + asfloat(uniforms[0].zw));
   }
   return output;
 }
diff --git a/test/tint/bug/dawn/947.wgsl.expected.glsl b/test/tint/bug/dawn/947.wgsl.expected.glsl
index 49e7533..a6f6575 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.glsl
+++ b/test/tint/bug/dawn/947.wgsl.expected.glsl
@@ -19,12 +19,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex) {
   vec2 texcoord[3] = vec2[3](vec2(-0.5f, 0.0f), vec2(1.5f, 0.0f), vec2(0.5f, 2.0f));
   VertexOutputs tint_symbol = VertexOutputs(vec2(0.0f), vec4(0.0f));
-  tint_symbol.position = vec4(((texcoord[VertexIndex] * 2.0f) - vec2(1.0f)), 0.0f, 1.0f);
+  tint_symbol.position = vec4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - vec2(1.0f)), 0.0f, 1.0f);
   bool flipY = (v.inner.u_scale.y < 0.0f);
   if (flipY) {
-    tint_symbol.texcoords = ((((texcoord[VertexIndex] * v.inner.u_scale) + v.inner.u_offset) * vec2(1.0f, -1.0f)) + vec2(0.0f, 1.0f));
+    tint_symbol.texcoords = ((((texcoord[min(VertexIndex, 2u)] * v.inner.u_scale) + v.inner.u_offset) * vec2(1.0f, -1.0f)) + vec2(0.0f, 1.0f));
   } else {
-    tint_symbol.texcoords = ((((texcoord[VertexIndex] * vec2(1.0f, -1.0f)) + vec2(0.0f, 1.0f)) * v.inner.u_scale) + v.inner.u_offset);
+    tint_symbol.texcoords = ((((texcoord[min(VertexIndex, 2u)] * vec2(1.0f, -1.0f)) + vec2(0.0f, 1.0f)) * v.inner.u_scale) + v.inner.u_offset);
   }
   return tint_symbol;
 }
diff --git a/test/tint/bug/dawn/947.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/dawn/947.wgsl.expected.ir.dxc.hlsl
index 28ae80a..4bf4b89 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/dawn/947.wgsl.expected.ir.dxc.hlsl
@@ -29,12 +29,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex) {
   float2 texcoord[3] = {float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = (VertexOutputs)0;
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
   bool flipY = (asfloat(uniforms[0u].y) < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw));
   }
   VertexOutputs v = output;
   return v;
diff --git a/test/tint/bug/dawn/947.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/dawn/947.wgsl.expected.ir.fxc.hlsl
index f8f9577..be640e9 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/dawn/947.wgsl.expected.ir.fxc.hlsl
@@ -30,12 +30,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex) {
   float2 texcoord[3] = {float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = (VertexOutputs)0;
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - (1.0f).xx), 0.0f, 1.0f);
   bool flipY = (asfloat(uniforms[0u].y) < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw)) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * asfloat(uniforms[0u].xy)) + asfloat(uniforms[0u].zw));
   }
   VertexOutputs v = output;
   return v;
diff --git a/test/tint/bug/dawn/947.wgsl.expected.ir.msl b/test/tint/bug/dawn/947.wgsl.expected.ir.msl
index a6ccc01..37ec91d 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.ir.msl
+++ b/test/tint/bug/dawn/947.wgsl.expected.ir.msl
@@ -46,12 +46,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex, tint_module_vars_struct tint_module_vars) {
   tint_array<float2, 3> texcoord = tint_array<float2, 3>{float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = {};
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - float2(1.0f)), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - float2(1.0f)), 0.0f, 1.0f);
   bool flipY = ((*tint_module_vars.uniforms).u_scale[1u] < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * (*tint_module_vars.uniforms).u_scale) + (*tint_module_vars.uniforms).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * (*tint_module_vars.uniforms).u_scale) + (*tint_module_vars.uniforms).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*tint_module_vars.uniforms).u_scale) + (*tint_module_vars.uniforms).u_offset);
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*tint_module_vars.uniforms).u_scale) + (*tint_module_vars.uniforms).u_offset);
   }
   return output;
 }
diff --git a/test/tint/bug/dawn/947.wgsl.expected.msl b/test/tint/bug/dawn/947.wgsl.expected.msl
index be7f37f..ec84778 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.msl
+++ b/test/tint/bug/dawn/947.wgsl.expected.msl
@@ -36,12 +36,12 @@
 VertexOutputs vs_main_inner(uint VertexIndex, const constant Uniforms* const tint_symbol_4) {
   tint_array<float2, 3> texcoord = tint_array<float2, 3>{float2(-0.5f, 0.0f), float2(1.5f, 0.0f), float2(0.5f, 2.0f)};
   VertexOutputs output = {};
-  output.position = float4(((texcoord[VertexIndex] * 2.0f) - float2(1.0f)), 0.0f, 1.0f);
+  output.position = float4(((texcoord[min(VertexIndex, 2u)] * 2.0f) - float2(1.0f)), 0.0f, 1.0f);
   bool flipY = ((*(tint_symbol_4)).u_scale[1] < 0.0f);
   if (flipY) {
-    output.texcoords = ((((texcoord[VertexIndex] * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset) * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f));
   } else {
-    output.texcoords = ((((texcoord[VertexIndex] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset);
+    output.texcoords = ((((texcoord[min(VertexIndex, 2u)] * float2(1.0f, -1.0f)) + float2(0.0f, 1.0f)) * (*(tint_symbol_4)).u_scale) + (*(tint_symbol_4)).u_offset);
   }
   return output;
 }
diff --git a/test/tint/bug/dawn/947.wgsl.expected.spvasm b/test/tint/bug/dawn/947.wgsl.expected.spvasm
index 6ded191..dae0c70 100644
--- a/test/tint/bug/dawn/947.wgsl.expected.spvasm
+++ b/test/tint/bug/dawn/947.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 136
+; Bound: 140
 ; Schema: 0
                OpCapability Shader
-        %106 = OpExtInstImport "GLSL.std.450"
+         %55 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vs_main "vs_main" %vs_main_vertex_index_Input %vs_main_loc0_Output %vs_main_position_Output %vs_main___point_size_Output
                OpEntryPoint Fragment %fs_main "fs_main" %fs_main_loc0_Input %fs_main_loc0_Output
@@ -104,23 +104,24 @@
          %50 = OpConstantNull %VertexOutputs
 %_ptr_Function_v4float = OpTypePointer Function %v4float
      %uint_1 = OpConstant %uint 1
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v2float = OpTypePointer Function %v2float
     %float_1 = OpConstant %float 1
-         %59 = OpConstantComposite %v2float %float_1 %float_1
+         %62 = OpConstantComposite %v2float %float_1 %float_1
 %_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
 %_ptr_Function_bool = OpTypePointer Function %bool
    %float_n1 = OpConstant %float -1
-         %85 = OpConstantComposite %v2float %float_1 %float_n1
-         %88 = OpConstantComposite %v2float %float_0 %float_1
-        %103 = OpTypeFunction %v4float %v2float
-        %107 = OpConstantNull %v2float
+         %89 = OpConstantComposite %v2float %float_1 %float_n1
+         %92 = OpConstantComposite %v2float %float_0 %float_1
+        %108 = OpTypeFunction %v4float %v2float
+        %111 = OpConstantNull %v2float
      %v2bool = OpTypeVector %bool 2
       %false = OpConstantFalse %bool
-        %118 = OpConstantNull %v4float
+        %122 = OpConstantNull %v4float
        %void = OpTypeVoid
-        %126 = OpTypeFunction %void
+        %130 = OpTypeFunction %void
 %vs_main_inner = OpFunction %VertexOutputs None %33
 %VertexIndex = OpFunctionParameter %uint
          %34 = OpLabel
@@ -129,95 +130,98 @@
       %flipY = OpVariable %_ptr_Function_bool Function
                OpStore %texcoord %39
          %51 = OpAccessChain %_ptr_Function_v4float %output %uint_1
-         %54 = OpAccessChain %_ptr_Function_v2float %texcoord %VertexIndex
-         %56 = OpLoad %v2float %54 None
-         %57 = OpVectorTimesScalar %v2float %56 %float_2
-         %58 = OpFSub %v2float %57 %59
-         %61 = OpCompositeConstruct %v4float %58 %float_0 %float_1
-               OpStore %51 %61 None
-         %62 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
-         %65 = OpAccessChain %_ptr_Uniform_float %62 %uint_1
-         %67 = OpLoad %float %65 None
-         %68 = OpFOrdLessThan %bool %67 %float_0
-               OpStore %flipY %68
-         %71 = OpLoad %bool %flipY None
-               OpSelectionMerge %72 None
-               OpBranchConditional %71 %73 %74
-         %73 = OpLabel
-         %75 = OpAccessChain %_ptr_Function_v2float %output %uint_0
-         %76 = OpAccessChain %_ptr_Function_v2float %texcoord %VertexIndex
-         %77 = OpLoad %v2float %76 None
-         %78 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
-         %79 = OpLoad %v2float %78 None
-         %80 = OpFMul %v2float %77 %79
-         %81 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1
-         %82 = OpLoad %v2float %81 None
-         %83 = OpFAdd %v2float %80 %82
-         %84 = OpFMul %v2float %83 %85
-         %87 = OpFAdd %v2float %84 %88
-               OpStore %75 %87 None
-               OpBranch %72
-         %74 = OpLabel
-         %89 = OpAccessChain %_ptr_Function_v2float %output %uint_0
-         %90 = OpAccessChain %_ptr_Function_v2float %texcoord %VertexIndex
-         %91 = OpLoad %v2float %90 None
-         %92 = OpFMul %v2float %91 %85
-         %93 = OpFAdd %v2float %92 %88
-         %94 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
-         %95 = OpLoad %v2float %94 None
-         %96 = OpFMul %v2float %93 %95
-         %97 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1
-         %98 = OpLoad %v2float %97 None
-         %99 = OpFAdd %v2float %96 %98
-               OpStore %89 %99 None
-               OpBranch %72
-         %72 = OpLabel
-        %100 = OpLoad %VertexOutputs %output None
-               OpReturnValue %100
+         %54 = OpExtInst %uint %55 UMin %VertexIndex %uint_2
+         %57 = OpAccessChain %_ptr_Function_v2float %texcoord %54
+         %59 = OpLoad %v2float %57 None
+         %60 = OpVectorTimesScalar %v2float %59 %float_2
+         %61 = OpFSub %v2float %60 %62
+         %64 = OpCompositeConstruct %v4float %61 %float_0 %float_1
+               OpStore %51 %64 None
+         %65 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
+         %68 = OpAccessChain %_ptr_Uniform_float %65 %uint_1
+         %70 = OpLoad %float %68 None
+         %71 = OpFOrdLessThan %bool %70 %float_0
+               OpStore %flipY %71
+         %74 = OpLoad %bool %flipY None
+               OpSelectionMerge %75 None
+               OpBranchConditional %74 %76 %77
+         %76 = OpLabel
+         %78 = OpAccessChain %_ptr_Function_v2float %output %uint_0
+         %79 = OpExtInst %uint %55 UMin %VertexIndex %uint_2
+         %80 = OpAccessChain %_ptr_Function_v2float %texcoord %79
+         %81 = OpLoad %v2float %80 None
+         %82 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
+         %83 = OpLoad %v2float %82 None
+         %84 = OpFMul %v2float %81 %83
+         %85 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1
+         %86 = OpLoad %v2float %85 None
+         %87 = OpFAdd %v2float %84 %86
+         %88 = OpFMul %v2float %87 %89
+         %91 = OpFAdd %v2float %88 %92
+               OpStore %78 %91 None
+               OpBranch %75
+         %77 = OpLabel
+         %93 = OpAccessChain %_ptr_Function_v2float %output %uint_0
+         %94 = OpExtInst %uint %55 UMin %VertexIndex %uint_2
+         %95 = OpAccessChain %_ptr_Function_v2float %texcoord %94
+         %96 = OpLoad %v2float %95 None
+         %97 = OpFMul %v2float %96 %89
+         %98 = OpFAdd %v2float %97 %92
+         %99 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_0
+        %100 = OpLoad %v2float %99 None
+        %101 = OpFMul %v2float %98 %100
+        %102 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_1
+        %103 = OpLoad %v2float %102 None
+        %104 = OpFAdd %v2float %101 %103
+               OpStore %93 %104 None
+               OpBranch %75
+         %75 = OpLabel
+        %105 = OpLoad %VertexOutputs %output None
+               OpReturnValue %105
                OpFunctionEnd
-%fs_main_inner = OpFunction %v4float None %103
+%fs_main_inner = OpFunction %v4float None %108
  %texcoord_0 = OpFunctionParameter %v2float
-        %104 = OpLabel
+        %109 = OpLabel
 %clampedTexcoord = OpVariable %_ptr_Function_v2float Function
    %srcColor = OpVariable %_ptr_Function_v4float Function
-        %105 = OpExtInst %v2float %106 NClamp %texcoord_0 %107 %59
-               OpStore %clampedTexcoord %105
-        %109 = OpLoad %v2float %clampedTexcoord None
-        %110 = OpFOrdEqual %v2bool %109 %texcoord_0
-        %112 = OpAll %bool %110
-        %113 = OpLogicalNot %bool %112
-               OpSelectionMerge %114 None
-               OpBranchConditional %113 %115 %114
-        %115 = OpLabel
+        %110 = OpExtInst %v2float %55 NClamp %texcoord_0 %111 %62
+               OpStore %clampedTexcoord %110
+        %113 = OpLoad %v2float %clampedTexcoord None
+        %114 = OpFOrdEqual %v2bool %113 %texcoord_0
+        %116 = OpAll %bool %114
+        %117 = OpLogicalNot %bool %116
+               OpSelectionMerge %118 None
+               OpBranchConditional %117 %119 %118
+        %119 = OpLabel
                OpStore %continue_execution %false None
-               OpBranch %114
-        %114 = OpLabel
-               OpStore %srcColor %118
-        %119 = OpLoad %v4float %srcColor None
-        %120 = OpLoad %bool %continue_execution None
-        %121 = OpLogicalNot %bool %120
-               OpSelectionMerge %122 None
-               OpBranchConditional %121 %123 %122
-        %123 = OpLabel
-               OpKill
-        %122 = OpLabel
-               OpReturnValue %119
-               OpFunctionEnd
-    %vs_main = OpFunction %void None %126
+               OpBranch %118
+        %118 = OpLabel
+               OpStore %srcColor %122
+        %123 = OpLoad %v4float %srcColor None
+        %124 = OpLoad %bool %continue_execution None
+        %125 = OpLogicalNot %bool %124
+               OpSelectionMerge %126 None
+               OpBranchConditional %125 %127 %126
         %127 = OpLabel
-        %128 = OpLoad %uint %vs_main_vertex_index_Input None
-        %129 = OpFunctionCall %VertexOutputs %vs_main_inner %128
-        %130 = OpCompositeExtract %v2float %129 0
-               OpStore %vs_main_loc0_Output %130 None
-        %131 = OpCompositeExtract %v4float %129 1
-               OpStore %vs_main_position_Output %131 None
+               OpKill
+        %126 = OpLabel
+               OpReturnValue %123
+               OpFunctionEnd
+    %vs_main = OpFunction %void None %130
+        %131 = OpLabel
+        %132 = OpLoad %uint %vs_main_vertex_index_Input None
+        %133 = OpFunctionCall %VertexOutputs %vs_main_inner %132
+        %134 = OpCompositeExtract %v2float %133 0
+               OpStore %vs_main_loc0_Output %134 None
+        %135 = OpCompositeExtract %v4float %133 1
+               OpStore %vs_main_position_Output %135 None
                OpStore %vs_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-    %fs_main = OpFunction %void None %126
-        %133 = OpLabel
-        %134 = OpLoad %v2float %fs_main_loc0_Input None
-        %135 = OpFunctionCall %v4float %fs_main_inner %134
-               OpStore %fs_main_loc0_Output %135 None
+    %fs_main = OpFunction %void None %130
+        %137 = OpLabel
+        %138 = OpLoad %v2float %fs_main_loc0_Input None
+        %139 = OpFunctionCall %v4float %fs_main_inner %138
+               OpStore %fs_main_loc0_Output %139 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.dxc.hlsl
index b3cc31b..16e82e0 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.dxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.fxc.hlsl
index b3cc31b..16e82e0 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.fxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.glsl
index 0f405be..cf6c592 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.glsl
@@ -24,6 +24,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   v_1.inner.tint_symbol = s.data[v_2];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.dxc.hlsl
index 862961f..6ccbcb1 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.fxc.hlsl
index 862961f..6ccbcb1 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.msl
index 499af21..0e55b68 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.ir.msl
@@ -33,5 +33,5 @@
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result};
   S s = {};
-  (*tint_module_vars.result).out = s.data[(*tint_module_vars.ubo).dynamic_idx];
+  (*tint_module_vars.result).out = s.data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.msl
index 8f724a6..a6653c3 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.msl
@@ -28,7 +28,7 @@
 
 kernel void f(device Result* tint_symbol [[buffer(1)]], const constant UBO* tint_symbol_1 [[buffer(0)]]) {
   S s = {};
-  (*(tint_symbol)).out = s.data[(*(tint_symbol_1)).dynamic_idx];
+  (*(tint_symbol)).out = s.data[min(uint((*(tint_symbol_1)).dynamic_idx), 63u)];
   return;
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.spvasm
index 5c846bc..f0fd2a0 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/read/function.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -53,6 +54,7 @@
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
+    %uint_63 = OpConstant %uint 63
 %_ptr_Function_int = OpTypePointer Function %int
           %f = OpFunction %void None %12
          %13 = OpLabel
@@ -60,8 +62,10 @@
          %21 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
          %24 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %26 = OpLoad %int %24 None
-         %27 = OpAccessChain %_ptr_Function_int %s %uint_0 %26
-         %29 = OpLoad %int %27 None
-               OpStore %21 %29 None
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_63
+         %31 = OpAccessChain %_ptr_Function_int %s %uint_0 %28
+         %33 = OpLoad %int %31 None
+               OpStore %21 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.dxc.hlsl
index e450f0f..88cf240 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.dxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.fxc.hlsl
index e450f0f..88cf240 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.fxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.glsl
index 31215c5..2ed6884 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.glsl
@@ -24,6 +24,6 @@
 S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   v_1.inner.tint_symbol = s.data[v_2];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.dxc.hlsl
index 1180c04..433625a 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 static S s = (S)0;
 [numthreads(1, 1, 1)]
 void f() {
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.fxc.hlsl
index 1180c04..433625a 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 static S s = (S)0;
 [numthreads(1, 1, 1)]
 void f() {
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.msl
index 58ed7d8..defda94 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.ir.msl
@@ -34,5 +34,5 @@
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   thread S s = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result, .s=(&s)};
-  (*tint_module_vars.result).out = (*tint_module_vars.s).data[(*tint_module_vars.ubo).dynamic_idx];
+  (*tint_module_vars.result).out = (*tint_module_vars.s).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.msl
index b21bb5e..4fa758f 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.msl
@@ -32,7 +32,7 @@
 
 kernel void f(device Result* tint_symbol [[buffer(1)]], const constant UBO* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  (*(tint_symbol)).out = tint_private_vars.s.data[(*(tint_symbol_1)).dynamic_idx];
+  (*(tint_symbol)).out = tint_private_vars.s.data[min(uint((*(tint_symbol_1)).dynamic_idx), 63u)];
   return;
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.spvasm
index 996ef06..eddfd86 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/read/private.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -54,14 +55,17 @@
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
+    %uint_63 = OpConstant %uint 63
 %_ptr_Private_int = OpTypePointer Private %int
           %f = OpFunction %void None %19
          %20 = OpLabel
          %21 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
          %24 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %26 = OpLoad %int %24 None
-         %27 = OpAccessChain %_ptr_Private_int %s %uint_0 %26
-         %29 = OpLoad %int %27 None
-               OpStore %21 %29 None
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_63
+         %31 = OpAccessChain %_ptr_Private_int %s %uint_0 %28
+         %33 = OpLoad %int %31 None
+               OpStore %21 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.dxc.hlsl
index 409f538..a172cfd 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.dxc.hlsl
@@ -8,6 +8,6 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(asint(ssbo.Load((4u * uint(asint(ubo[0].x)))))));
+  result.Store(0u, asuint(asint(ssbo.Load((4u * min(uint(asint(ubo[0].x)), 3u))))));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.fxc.hlsl
index 409f538..a172cfd 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.fxc.hlsl
@@ -8,6 +8,6 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(asint(ssbo.Load((4u * uint(asint(ubo[0].x)))))));
+  result.Store(0u, asuint(asint(ssbo.Load((4u * min(uint(asint(ubo[0].x)), 3u))))));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.glsl
index 9a90581..1518545 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.glsl
@@ -27,6 +27,6 @@
 } v_2;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_3 = v.inner.dynamic_idx;
+  uint v_3 = min(uint(v.inner.dynamic_idx), 3u);
   v_1.inner.tint_symbol = v_2.inner.data[v_3];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.dxc.hlsl
index bb5c58a..1743e0b 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 RWByteAddressBuffer ssbo : register(u1);
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(asint(ssbo.Load((0u + (uint(asint(ubo[0u].x)) * 4u))))));
+  result.Store(0u, asuint(asint(ssbo.Load((0u + (min(uint(asint(ubo[0u].x)), 3u) * 4u))))));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.fxc.hlsl
index bb5c58a..1743e0b 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 RWByteAddressBuffer ssbo : register(u1);
 [numthreads(1, 1, 1)]
 void f() {
-  result.Store(0u, asuint(asint(ssbo.Load((0u + (uint(asint(ubo[0u].x)) * 4u))))));
+  result.Store(0u, asuint(asint(ssbo.Load((0u + (min(uint(asint(ubo[0u].x)), 3u) * 4u))))));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.msl
index 22ad4ff..e7b5866 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.ir.msl
@@ -33,5 +33,5 @@
 
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]], device SSBO* ssbo [[buffer(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result, .ssbo=ssbo};
-  (*tint_module_vars.result).out = (*tint_module_vars.ssbo).data[(*tint_module_vars.ubo).dynamic_idx];
+  (*tint_module_vars.result).out = (*tint_module_vars.ssbo).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 3u)];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.msl
index c802c8f..c336cf0 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.msl
@@ -27,7 +27,7 @@
 };
 
 kernel void f(device Result* tint_symbol [[buffer(1)]], device SSBO* tint_symbol_1 [[buffer(2)]], const constant UBO* tint_symbol_2 [[buffer(0)]]) {
-  (*(tint_symbol)).out = (*(tint_symbol_1)).data[(*(tint_symbol_2)).dynamic_idx];
+  (*(tint_symbol)).out = (*(tint_symbol_1)).data[min(uint((*(tint_symbol_2)).dynamic_idx), 3u)];
   return;
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.spvasm
index e60aec4..16df02e 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/read/storage.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -60,13 +61,16 @@
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
+     %uint_3 = OpConstant %uint 3
           %f = OpFunction %void None %19
          %20 = OpLabel
          %21 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
          %24 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %26 = OpLoad %int %24 None
-         %27 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %26
-         %28 = OpLoad %int %27 None
-               OpStore %21 %28 None
+         %27 = OpBitcast %uint %26
+         %28 = OpExtInst %uint %29 UMin %27 %uint_3
+         %31 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %28
+         %32 = OpLoad %int %31 None
+               OpStore %21 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.dxc.hlsl
index eac7f8c..e267694 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.dxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  const uint scalar_offset = ((16u * uint(asint(ubo[4].x)))) / 4;
+  const uint scalar_offset = ((16u * min(uint(asint(ubo[4].x)), 3u))) / 4;
   result.Store(0u, asuint(asint(ubo[scalar_offset / 4][scalar_offset % 4])));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.fxc.hlsl
index eac7f8c..e267694 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.fxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  const uint scalar_offset = ((16u * uint(asint(ubo[4].x)))) / 4;
+  const uint scalar_offset = ((16u * min(uint(asint(ubo[4].x)), 3u))) / 4;
   result.Store(0u, asuint(asint(ubo[scalar_offset / 4][scalar_offset % 4])));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.glsl
index be3bdf9..e6a7047 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.glsl
@@ -23,6 +23,6 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 3u);
   v_1.inner.tint_symbol = v.inner.data[v_2].x;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.dxc.hlsl
index fb1d6a6..1c20620 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 RWByteAddressBuffer result : register(u2);
 [numthreads(1, 1, 1)]
 void f() {
-  uint v = (16u * uint(asint(ubo[4u].x)));
+  uint v = (16u * uint(min(uint(asint(ubo[4u].x)), 3u)));
   result.Store(0u, asuint(asint(ubo[(v / 16u)][((v % 16u) / 4u)])));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.fxc.hlsl
index fb1d6a6..1c20620 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.fxc.hlsl
@@ -5,7 +5,7 @@
 RWByteAddressBuffer result : register(u2);
 [numthreads(1, 1, 1)]
 void f() {
-  uint v = (16u * uint(asint(ubo[4u].x)));
+  uint v = (16u * uint(min(uint(asint(ubo[4u].x)), 3u)));
   result.Store(0u, asuint(asint(ubo[(v / 16u)][((v % 16u) / 4u)])));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.msl
index d183f35..ec17e1b 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.ir.msl
@@ -30,5 +30,5 @@
 
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result};
-  (*tint_module_vars.result).out = (*tint_module_vars.ubo).data[(*tint_module_vars.ubo).dynamic_idx][0u];
+  (*tint_module_vars.result).out = (*tint_module_vars.ubo).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 3u)][0u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.msl
index c9ab959..521ca26 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.msl
@@ -25,7 +25,7 @@
 };
 
 kernel void f(device Result* tint_symbol [[buffer(1)]], const constant UBO* tint_symbol_1 [[buffer(0)]]) {
-  (*(tint_symbol)).out = (*(tint_symbol_1)).data[(*(tint_symbol_1)).dynamic_idx][0];
+  (*(tint_symbol)).out = (*(tint_symbol_1)).data[min(uint((*(tint_symbol_1)).dynamic_idx), 3u)][0];
   return;
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.spvasm
index 8dde7cc..5283259 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/read/uniform.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,15 +51,18 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_1 = OpConstant %uint 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Uniform_v4int = OpTypePointer Uniform %v4int
           %f = OpFunction %void None %16
          %17 = OpLabel
          %18 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0
          %21 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_1
          %24 = OpLoad %int %21 None
-         %25 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %24
-         %27 = OpAccessChain %_ptr_Uniform_int %25 %uint_0
-         %28 = OpLoad %int %27 None
-               OpStore %18 %28 None
+         %25 = OpBitcast %uint %24
+         %26 = OpExtInst %uint %27 UMin %25 %uint_3
+         %29 = OpAccessChain %_ptr_Uniform_v4int %1 %uint_0 %uint_0 %26
+         %31 = OpAccessChain %_ptr_Uniform_int %29 %uint_0
+         %32 = OpLoad %int %31 None
+               OpStore %18 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.dxc.hlsl
index 38791a5..35ac571 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.dxc.hlsl
@@ -26,7 +26,7 @@
 
 void f_inner(uint local_invocation_index) {
   tint_zero_workgroup_memory(local_invocation_index);
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.fxc.hlsl
index 38791a5..35ac571 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.fxc.hlsl
@@ -26,7 +26,7 @@
 
 void f_inner(uint local_invocation_index) {
   tint_zero_workgroup_memory(local_invocation_index);
-  result.Store(0u, asuint(s.data[asint(ubo[0].x)]));
+  result.Store(0u, asuint(s.data[min(uint(asint(ubo[0].x)), 63u)]));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.glsl
index 5cf9490..1be01ae 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.glsl
@@ -39,7 +39,7 @@
     }
   }
   barrier();
-  int v_4 = v.inner.dynamic_idx;
+  uint v_4 = min(uint(v.inner.dynamic_idx), 63u);
   v_1.inner.tint_symbol = s.data[v_4];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.dxc.hlsl
index 1f32ea6..d4fdbfb 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.dxc.hlsl
@@ -29,7 +29,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  int v_2 = asint(ubo[0u].x);
+  uint v_2 = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v_2]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.fxc.hlsl
index 1f32ea6..d4fdbfb 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.fxc.hlsl
@@ -29,7 +29,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  int v_2 = asint(ubo[0u].x);
+  uint v_2 = min(uint(asint(ubo[0u].x)), 63u);
   result.Store(0u, asuint(s.data[v_2]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.msl
index 955f46a..82d2ab1 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.ir.msl
@@ -31,6 +31,9 @@
   threadgroup S* s;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   S tint_symbol;
 };
@@ -40,6 +43,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 64u)) {
         break;
@@ -52,7 +56,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  (*tint_module_vars.result).out = (*tint_module_vars.s).data[(*tint_module_vars.ubo).dynamic_idx];
+  (*tint_module_vars.result).out = (*tint_module_vars.s).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.msl
index 2a445c2..6919fa8 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   tint_array<int, 64> data;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup S* const tint_symbol) {
   for(uint idx = local_idx; (idx < 64u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol)).data[i] = 0;
   }
@@ -36,7 +40,7 @@
 
 void f_inner(uint local_invocation_index, threadgroup S* const tint_symbol_1, device Result* const tint_symbol_2, const constant UBO* const tint_symbol_3) {
   tint_zero_workgroup_memory(local_invocation_index, tint_symbol_1);
-  (*(tint_symbol_2)).out = (*(tint_symbol_1)).data[(*(tint_symbol_3)).dynamic_idx];
+  (*(tint_symbol_2)).out = (*(tint_symbol_1)).data[min(uint((*(tint_symbol_3)).dynamic_idx), 63u)];
 }
 
 kernel void f(device Result* tint_symbol_5 [[buffer(1)]], const constant UBO* tint_symbol_6 [[buffer(0)]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
diff --git a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.spvasm
index b212159..d1f8de1 100644
--- a/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/read/workgroup.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
+         %49 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f" %f_local_invocation_index_Input
                OpExecutionMode %f LocalSize 1 1 1
@@ -65,7 +66,8 @@
    %uint_264 = OpConstant %uint 264
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_Uniform_int = OpTypePointer Uniform %int
-         %50 = OpTypeFunction %void
+    %uint_63 = OpConstant %uint 63
+         %54 = OpTypeFunction %void
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -94,14 +96,16 @@
          %42 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
          %44 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %46 = OpLoad %int %44 None
-         %47 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %46
-         %48 = OpLoad %int %47 None
-               OpStore %42 %48 None
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %49 UMin %47 %uint_63
+         %51 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %48
+         %52 = OpLoad %int %51 None
+               OpStore %42 %52 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %50
-         %51 = OpLabel
-         %52 = OpLoad %uint %f_local_invocation_index_Input None
-         %53 = OpFunctionCall %void %f_inner %52
+          %f = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpLoad %uint %f_local_invocation_index_Input None
+         %57 = OpFunctionCall %void %f_inner %56
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.dxc.hlsl
index a45e4b5..976dd44 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.dxc.hlsl
@@ -13,7 +13,7 @@
   S s = (S)0;
   {
     int tint_symbol_2[64] = s.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     s.data = tint_symbol_2;
   }
   result.Store(0u, asuint(s.data[3]));
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.fxc.hlsl
index a45e4b5..976dd44 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.fxc.hlsl
@@ -13,7 +13,7 @@
   S s = (S)0;
   {
     int tint_symbol_2[64] = s.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     s.data = tint_symbol_2;
   }
   result.Store(0u, asuint(s.data[3]));
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.glsl
index 1dd7e55..a3e95ca 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.glsl
@@ -24,7 +24,7 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   s.data[v_2] = 1;
-  v_1.inner.tint_symbol = s.data[3];
+  v_1.inner.tint_symbol = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.dxc.hlsl
index 84880c4..a967f29 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   s.data[v] = int(1);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.fxc.hlsl
index eeb55a3..b84965b 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.fxc.hlsl
@@ -11,10 +11,12 @@
 void f() {
   S s = (S)0;
   int v = asint(ubo[0u].x);
+  uint v_1 = min(uint(v), 63u);
   int tint_array_copy[64] = s.data;
-  tint_array_copy[v] = int(1);
-  int v_1[64] = tint_array_copy;
-  s.data = v_1;
-  result.Store(0u, asuint(s.data[int(3)]));
+  uint v_2 = min(uint(v), 63u);
+  tint_array_copy[v_2] = int(1);
+  int v_3[64] = tint_array_copy;
+  s.data = v_3;
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.msl
index ddd9a85..35b884e 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.ir.msl
@@ -33,6 +33,6 @@
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result};
   S s = {};
-  s.data[(*tint_module_vars.ubo).dynamic_idx] = 1;
-  (*tint_module_vars.result).out = s.data[3];
+  s.data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)] = 1;
+  (*tint_module_vars.result).out = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.msl
index 1fe02f1..8ec22c1 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.msl
@@ -28,7 +28,7 @@
 
 kernel void f(const constant UBO* tint_symbol [[buffer(0)]], device Result* tint_symbol_1 [[buffer(1)]]) {
   S s = {};
-  s.data[(*(tint_symbol)).dynamic_idx] = 1;
+  s.data[min(uint((*(tint_symbol)).dynamic_idx), 63u)] = 1;
   (*(tint_symbol_1)).out = s.data[3];
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.spvasm
index 4665807..89f6d78 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -52,20 +53,23 @@
          %20 = OpConstantNull %S
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_0 = OpConstant %uint 0
+    %uint_63 = OpConstant %uint 63
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
           %f = OpFunction %void None %12
          %13 = OpLabel
           %s = OpVariable %_ptr_Function_S Function %20
          %21 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %24 = OpLoad %int %21 None
-         %25 = OpAccessChain %_ptr_Function_int %s %uint_0 %24
-               OpStore %25 %int_1 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %30 = OpAccessChain %_ptr_Function_int %s %uint_0 %int_3
-         %32 = OpLoad %int %30 None
-               OpStore %28 %32 None
+         %25 = OpBitcast %uint %24
+         %26 = OpExtInst %uint %27 UMin %25 %uint_63
+         %29 = OpAccessChain %_ptr_Function_int %s %uint_0 %26
+               OpStore %29 %int_1 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Function_int %s %uint_0 %uint_3
+         %36 = OpLoad %int %34 None
+               OpStore %32 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.dxc.hlsl
index bda090f..321fa94 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.dxc.hlsl
@@ -11,7 +11,7 @@
 void x(inout S p) {
   {
     int tint_symbol_2[64] = p.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     p.data = tint_symbol_2;
   }
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.fxc.hlsl
index bda090f..321fa94 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.fxc.hlsl
@@ -11,7 +11,7 @@
 void x(inout S p) {
   {
     int tint_symbol_2[64] = p.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     p.data = tint_symbol_2;
   }
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.glsl
index fe4b12e..ae705f7 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.glsl
@@ -22,12 +22,12 @@
   Result inner;
 } v_1;
 void x(inout S p) {
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   p.data[v_2] = 1;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
   x(s);
-  v_1.inner.tint_symbol = s.data[3];
+  v_1.inner.tint_symbol = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.dxc.hlsl
index 6b5b381..59f2e16 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.dxc.hlsl
@@ -8,7 +8,7 @@
 };
 RWByteAddressBuffer result : register(u1);
 void x(inout S p) {
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   p.data[v] = int(1);
 }
 
@@ -16,6 +16,6 @@
 void f() {
   S s = (S)0;
   x(s);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.fxc.hlsl
index 5ce4b57..c0db221 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.fxc.hlsl
@@ -9,16 +9,18 @@
 RWByteAddressBuffer result : register(u1);
 void x(inout S p) {
   int v = asint(ubo[0u].x);
+  uint v_1 = min(uint(v), 63u);
   int tint_array_copy[64] = p.data;
-  tint_array_copy[v] = int(1);
-  int v_1[64] = tint_array_copy;
-  p.data = v_1;
+  uint v_2 = min(uint(v), 63u);
+  tint_array_copy[v_2] = int(1);
+  int v_3[64] = tint_array_copy;
+  p.data = v_3;
 }
 
 [numthreads(1, 1, 1)]
 void f() {
   S s = (S)0;
   x(s);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.msl
index a22555e..fa677f2 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.ir.msl
@@ -31,12 +31,12 @@
 };
 
 void x(thread S* const p, tint_module_vars_struct tint_module_vars) {
-  (*p).data[(*tint_module_vars.ubo).dynamic_idx] = 1;
+  (*p).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)] = 1;
 }
 
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result};
   S s = {};
   x((&s), tint_module_vars);
-  (*tint_module_vars.result).out = s.data[3];
+  (*tint_module_vars.result).out = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.msl
index 5aabd3a..31a7f42 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.msl
@@ -27,7 +27,7 @@
 };
 
 void x(thread S* const p, const constant UBO* const tint_symbol) {
-  (*(p)).data[(*(tint_symbol)).dynamic_idx] = 1;
+  (*(p)).data[min(uint((*(tint_symbol)).dynamic_idx), 63u)] = 1;
 }
 
 kernel void f(const constant UBO* tint_symbol_1 [[buffer(0)]], device Result* tint_symbol_2 [[buffer(1)]]) {
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.spvasm
index fc03378..95d0b0a 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/function_via_param.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -53,28 +54,31 @@
          %18 = OpTypeFunction %void %_ptr_Function_S
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_0 = OpConstant %uint 0
+    %uint_63 = OpConstant %uint 63
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
-         %28 = OpTypeFunction %void
-         %31 = OpConstantNull %S
+         %32 = OpTypeFunction %void
+         %35 = OpConstantNull %S
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
           %x = OpFunction %void None %18
      %p_root = OpFunctionParameter %_ptr_Function_S
          %19 = OpLabel
          %20 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %23 = OpLoad %int %20 None
-         %24 = OpAccessChain %_ptr_Function_int %p_root %uint_0 %23
-               OpStore %24 %int_1 None
+         %24 = OpBitcast %uint %23
+         %25 = OpExtInst %uint %26 UMin %24 %uint_63
+         %28 = OpAccessChain %_ptr_Function_int %p_root %uint_0 %25
+               OpStore %28 %int_1 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %28
-         %29 = OpLabel
-          %s = OpVariable %_ptr_Function_S Function %31
-         %32 = OpFunctionCall %void %x %s
-         %33 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %35 = OpAccessChain %_ptr_Function_int %s %uint_0 %int_3
-         %37 = OpLoad %int %35 None
-               OpStore %33 %37 None
+          %f = OpFunction %void None %32
+         %33 = OpLabel
+          %s = OpVariable %_ptr_Function_S Function %35
+         %36 = OpFunctionCall %void %x %s
+         %37 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %39 = OpAccessChain %_ptr_Function_int %s %uint_0 %uint_3
+         %41 = OpLoad %int %39 None
+               OpStore %37 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.dxc.hlsl
index d94c421..02beff5 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.dxc.hlsl
@@ -13,7 +13,7 @@
 void f() {
   {
     int tint_symbol_2[64] = s.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     s.data = tint_symbol_2;
   }
   result.Store(0u, asuint(s.data[3]));
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.fxc.hlsl
index d94c421..02beff5 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.fxc.hlsl
@@ -13,7 +13,7 @@
 void f() {
   {
     int tint_symbol_2[64] = s.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     s.data = tint_symbol_2;
   }
   result.Store(0u, asuint(s.data[3]));
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.glsl
index 7c326ab..5dbc127 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.glsl
@@ -24,7 +24,7 @@
 S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   s.data[v_2] = 1;
-  v_1.inner.tint_symbol = s.data[3];
+  v_1.inner.tint_symbol = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.dxc.hlsl
index dea5353..36f4011 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.dxc.hlsl
@@ -10,8 +10,8 @@
 static S s = (S)0;
 [numthreads(1, 1, 1)]
 void f() {
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   s.data[v] = int(1);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.fxc.hlsl
index b09e0ad..2a931a2 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.fxc.hlsl
@@ -11,10 +11,12 @@
 [numthreads(1, 1, 1)]
 void f() {
   int v = asint(ubo[0u].x);
+  uint v_1 = min(uint(v), 63u);
   int tint_array_copy[64] = s.data;
-  tint_array_copy[v] = int(1);
-  int v_1[64] = tint_array_copy;
-  s.data = v_1;
-  result.Store(0u, asuint(s.data[int(3)]));
+  uint v_2 = min(uint(v), 63u);
+  tint_array_copy[v_2] = int(1);
+  int v_3[64] = tint_array_copy;
+  s.data = v_3;
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.msl
index 2137798..babf7d5 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.ir.msl
@@ -34,6 +34,6 @@
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   thread S s = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result, .s=(&s)};
-  (*tint_module_vars.s).data[(*tint_module_vars.ubo).dynamic_idx] = 1;
-  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3];
+  (*tint_module_vars.s).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)] = 1;
+  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.msl
index a720c5a..fcd6321 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.msl
@@ -32,7 +32,7 @@
 
 kernel void f(const constant UBO* tint_symbol [[buffer(0)]], device Result* tint_symbol_1 [[buffer(1)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.s.data[(*(tint_symbol)).dynamic_idx] = 1;
+  tint_private_vars.s.data[min(uint((*(tint_symbol)).dynamic_idx), 63u)] = 1;
   (*(tint_symbol_1)).out = tint_private_vars.s.data[3];
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.spvasm
index f671578..96a8864 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -53,19 +54,22 @@
          %19 = OpTypeFunction %void
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_0 = OpConstant %uint 0
+    %uint_63 = OpConstant %uint 63
 %_ptr_Private_int = OpTypePointer Private %int
       %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
           %f = OpFunction %void None %19
          %20 = OpLabel
          %21 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %24 = OpLoad %int %21 None
-         %25 = OpAccessChain %_ptr_Private_int %s %uint_0 %24
-               OpStore %25 %int_1 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %30 = OpAccessChain %_ptr_Private_int %s %uint_0 %int_3
-         %32 = OpLoad %int %30 None
-               OpStore %28 %32 None
+         %25 = OpBitcast %uint %24
+         %26 = OpExtInst %uint %27 UMin %25 %uint_63
+         %29 = OpAccessChain %_ptr_Private_int %s %uint_0 %26
+               OpStore %29 %int_1 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %34 = OpAccessChain %_ptr_Private_int %s %uint_0 %uint_3
+         %36 = OpLoad %int %34 None
+               OpStore %32 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.dxc.hlsl
index 67faba9..4f37755 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.dxc.hlsl
@@ -12,7 +12,7 @@
 void x(inout S p) {
   {
     int tint_symbol_2[64] = p.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     p.data = tint_symbol_2;
   }
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.fxc.hlsl
index 67faba9..4f37755 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.fxc.hlsl
@@ -12,7 +12,7 @@
 void x(inout S p) {
   {
     int tint_symbol_2[64] = p.data;
-    tint_symbol_2[asint(ubo[0].x)] = 1;
+    tint_symbol_2[min(uint(asint(ubo[0].x)), 63u)] = 1;
     p.data = tint_symbol_2;
   }
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.glsl
index 701bd7b..b29b216 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.glsl
@@ -23,11 +23,11 @@
 } v_1;
 S s = S(int[64](0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 void x(inout S p) {
-  int v_2 = v.inner.dynamic_idx;
+  uint v_2 = min(uint(v.inner.dynamic_idx), 63u);
   p.data[v_2] = 1;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   x(s);
-  v_1.inner.tint_symbol = s.data[3];
+  v_1.inner.tint_symbol = s.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.dxc.hlsl
index 97ba0a1..5ff500e 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.dxc.hlsl
@@ -9,13 +9,13 @@
 RWByteAddressBuffer result : register(u1);
 static S s = (S)0;
 void x(inout S p) {
-  int v = asint(ubo[0u].x);
+  uint v = min(uint(asint(ubo[0u].x)), 63u);
   p.data[v] = int(1);
 }
 
 [numthreads(1, 1, 1)]
 void f() {
   x(s);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.fxc.hlsl
index 055c202..aa64899 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.fxc.hlsl
@@ -10,15 +10,17 @@
 static S s = (S)0;
 void x(inout S p) {
   int v = asint(ubo[0u].x);
+  uint v_1 = min(uint(v), 63u);
   int tint_array_copy[64] = p.data;
-  tint_array_copy[v] = int(1);
-  int v_1[64] = tint_array_copy;
-  p.data = v_1;
+  uint v_2 = min(uint(v), 63u);
+  tint_array_copy[v_2] = int(1);
+  int v_3[64] = tint_array_copy;
+  p.data = v_3;
 }
 
 [numthreads(1, 1, 1)]
 void f() {
   x(s);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.msl
index a92b547..48ad7b6 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.ir.msl
@@ -32,12 +32,12 @@
 };
 
 void x(thread S* const p, tint_module_vars_struct tint_module_vars) {
-  (*p).data[(*tint_module_vars.ubo).dynamic_idx] = 1;
+  (*p).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)] = 1;
 }
 
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]]) {
   thread S s = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result, .s=(&s)};
   x(tint_module_vars.s, tint_module_vars);
-  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3];
+  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.msl
index baad148..30381fb 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.msl
@@ -31,7 +31,7 @@
 };
 
 void x(thread S* const p, const constant UBO* const tint_symbol) {
-  (*(p)).data[(*(tint_symbol)).dynamic_idx] = 1;
+  (*(p)).data[min(uint((*(tint_symbol)).dynamic_idx), 63u)] = 1;
 }
 
 kernel void f(const constant UBO* tint_symbol_1 [[buffer(0)]], device Result* tint_symbol_2 [[buffer(1)]]) {
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.spvasm
index 47a040e..16c9e10 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/private_via_param.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -54,24 +55,27 @@
          %19 = OpTypeFunction %void
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_0 = OpConstant %uint 0
+    %uint_63 = OpConstant %uint 63
 %_ptr_Private_int = OpTypePointer Private %int
       %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-      %int_3 = OpConstant %int 3
+     %uint_3 = OpConstant %uint 3
           %x = OpFunction %void None %19
          %20 = OpLabel
          %21 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %24 = OpLoad %int %21 None
-         %25 = OpAccessChain %_ptr_Private_int %s %uint_0 %24
-               OpStore %25 %int_1 None
+         %25 = OpBitcast %uint %24
+         %26 = OpExtInst %uint %27 UMin %25 %uint_63
+         %29 = OpAccessChain %_ptr_Private_int %s %uint_0 %26
+               OpStore %29 %int_1 None
                OpReturn
                OpFunctionEnd
           %f = OpFunction %void None %19
-         %29 = OpLabel
-         %30 = OpFunctionCall %void %x
-         %31 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %33 = OpAccessChain %_ptr_Private_int %s %uint_0 %int_3
-         %35 = OpLoad %int %33 None
-               OpStore %31 %35 None
+         %33 = OpLabel
+         %34 = OpFunctionCall %void %x
+         %35 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_Private_int %s %uint_0 %uint_3
+         %39 = OpLoad %int %37 None
+               OpStore %35 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.dxc.hlsl
index aa6f3e6..0cf3613 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.dxc.hlsl
@@ -8,7 +8,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  ssbo.Store((4u * uint(asint(ubo[0].x))), asuint(1));
+  ssbo.Store((4u * min(uint(asint(ubo[0].x)), 3u)), asuint(1));
   result.Store(0u, asuint(asint(ssbo.Load(12u))));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.fxc.hlsl
index aa6f3e6..0cf3613 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.fxc.hlsl
@@ -8,7 +8,7 @@
 
 [numthreads(1, 1, 1)]
 void f() {
-  ssbo.Store((4u * uint(asint(ubo[0].x))), asuint(1));
+  ssbo.Store((4u * min(uint(asint(ubo[0].x)), 3u)), asuint(1));
   result.Store(0u, asuint(asint(ssbo.Load(12u))));
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.glsl
index c7de034..948ac89 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.glsl
@@ -27,7 +27,7 @@
 } v_2;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  int v_3 = v.inner.dynamic_idx;
+  uint v_3 = min(uint(v.inner.dynamic_idx), 3u);
   v_2.inner.data[v_3] = 1;
-  v_1.inner.tint_symbol = v_2.inner.data[3];
+  v_1.inner.tint_symbol = v_2.inner.data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.dxc.hlsl
index ec10569..e3b0857 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer ssbo : register(u1);
 [numthreads(1, 1, 1)]
 void f() {
-  ssbo.Store((0u + (uint(asint(ubo[0u].x)) * 4u)), asuint(int(1)));
+  ssbo.Store((0u + (min(uint(asint(ubo[0u].x)), 3u) * 4u)), asuint(int(1)));
   result.Store(0u, asuint(asint(ssbo.Load(12u))));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.fxc.hlsl
index ec10569..e3b0857 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer ssbo : register(u1);
 [numthreads(1, 1, 1)]
 void f() {
-  ssbo.Store((0u + (uint(asint(ubo[0u].x)) * 4u)), asuint(int(1)));
+  ssbo.Store((0u + (min(uint(asint(ubo[0u].x)), 3u) * 4u)), asuint(int(1)));
   result.Store(0u, asuint(asint(ssbo.Load(12u))));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.msl
index 8f5df4d..27293b7 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.ir.msl
@@ -33,6 +33,6 @@
 
 kernel void f(const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(2)]], device SSBO* ssbo [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.ubo=ubo, .result=result, .ssbo=ssbo};
-  (*tint_module_vars.ssbo).data[(*tint_module_vars.ubo).dynamic_idx] = 1;
-  (*tint_module_vars.result).out = (*tint_module_vars.ssbo).data[3];
+  (*tint_module_vars.ssbo).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 3u)] = 1;
+  (*tint_module_vars.result).out = (*tint_module_vars.ssbo).data[3u];
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.msl
index 747fc40..e3ff051 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.msl
@@ -27,7 +27,7 @@
 };
 
 kernel void f(device SSBO* tint_symbol [[buffer(1)]], const constant UBO* tint_symbol_1 [[buffer(0)]], device Result* tint_symbol_2 [[buffer(2)]]) {
-  (*(tint_symbol)).data[(*(tint_symbol_1)).dynamic_idx] = 1;
+  (*(tint_symbol)).data[min(uint((*(tint_symbol_1)).dynamic_idx), 3u)] = 1;
   (*(tint_symbol_2)).out = (*(tint_symbol)).data[3];
   return;
 }
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.spvasm
index 3093b61..df6554d 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/storage.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -59,18 +60,20 @@
          %19 = OpTypeFunction %void
 %_ptr_Uniform_int = OpTypePointer Uniform %int
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
       %int_1 = OpConstant %int 1
-      %int_3 = OpConstant %int 3
           %f = OpFunction %void None %19
          %20 = OpLabel
          %21 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %24 = OpLoad %int %21 None
-         %25 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %24
-               OpStore %25 %int_1 None
-         %28 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %29 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %int_3
-         %31 = OpLoad %int %29 None
-               OpStore %28 %31 None
+         %25 = OpBitcast %uint %24
+         %26 = OpExtInst %uint %27 UMin %25 %uint_3
+         %29 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %26
+               OpStore %29 %int_1 None
+         %32 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %33 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %uint_3
+         %34 = OpLoad %int %33 None
+               OpStore %32 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.dxc.hlsl
index 76d58cf..5df3076 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.dxc.hlsl
@@ -26,7 +26,7 @@
 
 void f_inner(uint local_invocation_index) {
   tint_zero_workgroup_memory(local_invocation_index);
-  s.data[asint(ubo[0].x)] = 1;
+  s.data[min(uint(asint(ubo[0].x)), 63u)] = 1;
   result.Store(0u, asuint(s.data[3]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.fxc.hlsl
index 76d58cf..5df3076 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.fxc.hlsl
@@ -26,7 +26,7 @@
 
 void f_inner(uint local_invocation_index) {
   tint_zero_workgroup_memory(local_invocation_index);
-  s.data[asint(ubo[0].x)] = 1;
+  s.data[min(uint(asint(ubo[0].x)), 63u)] = 1;
   result.Store(0u, asuint(s.data[3]));
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.glsl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.glsl
index c0d7b64..9d7ac65 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.glsl
@@ -39,9 +39,9 @@
     }
   }
   barrier();
-  int v_4 = v.inner.dynamic_idx;
+  uint v_4 = min(uint(v.inner.dynamic_idx), 63u);
   s.data[v_4] = 1;
-  v_1.inner.tint_symbol = s.data[3];
+  v_1.inner.tint_symbol = s.data[3u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.dxc.hlsl
index bf11112..17ee3be 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.dxc.hlsl
@@ -29,9 +29,9 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  int v_2 = asint(ubo[0u].x);
+  uint v_2 = min(uint(asint(ubo[0u].x)), 63u);
   s.data[v_2] = int(1);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.fxc.hlsl
index bf11112..17ee3be 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.fxc.hlsl
@@ -29,9 +29,9 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  int v_2 = asint(ubo[0u].x);
+  uint v_2 = min(uint(asint(ubo[0u].x)), 63u);
   s.data[v_2] = int(1);
-  result.Store(0u, asuint(s.data[int(3)]));
+  result.Store(0u, asuint(s.data[3u]));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.msl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.msl
index 6808f32..34f69d7 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.ir.msl
@@ -31,6 +31,9 @@
   threadgroup S* s;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   S tint_symbol;
 };
@@ -40,6 +43,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 64u)) {
         break;
@@ -52,8 +56,8 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  (*tint_module_vars.s).data[(*tint_module_vars.ubo).dynamic_idx] = 1;
-  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3];
+  (*tint_module_vars.s).data[min(uint((*tint_module_vars.ubo).dynamic_idx), 63u)] = 1;
+  (*tint_module_vars.result).out = (*tint_module_vars.s).data[3u];
 }
 
 kernel void f(uint tint_local_index [[thread_index_in_threadgroup]], const constant UBO* ubo [[buffer(0)]], device Result* result [[buffer(1)]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.msl b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.msl
index 8ad0b93..c733435 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.msl
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   tint_array<int, 64> data;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup S* const tint_symbol) {
   for(uint idx = local_idx; (idx < 64u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol)).data[i] = 0;
   }
@@ -36,7 +40,7 @@
 
 void f_inner(uint local_invocation_index, threadgroup S* const tint_symbol_1, const constant UBO* const tint_symbol_2, device Result* const tint_symbol_3) {
   tint_zero_workgroup_memory(local_invocation_index, tint_symbol_1);
-  (*(tint_symbol_1)).data[(*(tint_symbol_2)).dynamic_idx] = 1;
+  (*(tint_symbol_1)).data[min(uint((*(tint_symbol_2)).dynamic_idx), 63u)] = 1;
   (*(tint_symbol_3)).out = (*(tint_symbol_1)).data[3];
 }
 
diff --git a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.spvasm b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.spvasm
index 951f86b..9ab1a0c 100644
--- a/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/dyn_array_idx/write/workgroup.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
+         %47 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f" %f_local_invocation_index_Input
                OpExecutionMode %f LocalSize 1 1 1
@@ -64,10 +65,11 @@
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
 %_ptr_Uniform_int = OpTypePointer Uniform %int
+    %uint_63 = OpConstant %uint 63
       %int_1 = OpConstant %int 1
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-      %int_3 = OpConstant %int 3
-         %53 = OpTypeFunction %void
+     %uint_3 = OpConstant %uint 3
+         %57 = OpTypeFunction %void
     %f_inner = OpFunction %void None %21
 %tint_local_index = OpFunctionParameter %uint
          %22 = OpLabel
@@ -95,17 +97,19 @@
                OpControlBarrier %uint_2 %uint_2 %uint_264
          %42 = OpAccessChain %_ptr_Uniform_int %1 %uint_0 %uint_0
          %44 = OpLoad %int %42 None
-         %45 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %44
-               OpStore %45 %int_1 None
-         %47 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
-         %49 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %int_3
-         %51 = OpLoad %int %49 None
-               OpStore %47 %51 None
+         %45 = OpBitcast %uint %44
+         %46 = OpExtInst %uint %47 UMin %45 %uint_63
+         %49 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %46
+               OpStore %49 %int_1 None
+         %51 = OpAccessChain %_ptr_StorageBuffer_int %6 %uint_0 %uint_0
+         %53 = OpAccessChain %_ptr_Workgroup_int %s %uint_0 %uint_3
+         %55 = OpLoad %int %53 None
+               OpStore %51 %55 None
                OpReturn
                OpFunctionEnd
-          %f = OpFunction %void None %53
-         %54 = OpLabel
-         %55 = OpLoad %uint %f_local_invocation_index_Input None
-         %56 = OpFunctionCall %void %f_inner %55
+          %f = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpLoad %uint %f_local_invocation_index_Input None
+         %60 = OpFunctionCall %void %f_inner %59
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.ir.msl b/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.ir.msl
index f8edb82..4868c1c 100644
--- a/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.ir.msl
@@ -7,6 +7,9 @@
   texture2d<float, access::sample> depthTexture;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_outputs {
   float4 tint_symbol_1 [[color(0)]];
 };
@@ -20,6 +23,7 @@
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 1)) {
       } else {
         break;
diff --git a/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.msl b/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.msl
index 00e0497..674321f 100644
--- a/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.msl
+++ b/test/tint/bug/fxc/gradient_in_varying_loop/1112.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_3 {
   float2 vUV [[user(locn0)]];
 };
@@ -14,6 +18,7 @@
   float3 const random = tint_symbol_1.rgb;
   int i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i < 1)) {
     } else {
       break;
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.dxc.hlsl
index f8a5412..c2dd3d6 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.dxc.hlsl
@@ -22,16 +22,19 @@
 }
 
 Particle particles_load(uint offset) {
-  Particle tint_symbol_2 = {particles_load_1((offset + 0u)), asfloat(particles.Load((offset + 128u))), asfloat(particles.Load4((offset + 144u))), asfloat(particles.Load3((offset + 160u)))};
-  return tint_symbol_2;
+  Particle tint_symbol_5 = {particles_load_1((offset + 0u)), asfloat(particles.Load((offset + 128u))), asfloat(particles.Load4((offset + 144u))), asfloat(particles.Load3((offset + 160u)))};
+  return tint_symbol_5;
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  Particle particle = particles_load(0u);
+  uint tint_symbol_3 = 0u;
+  particles.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 176u);
+  Particle particle = particles_load((176u * min(0u, (tint_symbol_4 - 1u))));
   {
     float3 tint_symbol_1[8] = particle.position;
-    tint_symbol_1[sim[0].x] = particle.position[sim[0].x];
+    tint_symbol_1[min(sim[0].x, 7u)] = particle.position[min(sim[0].x, 7u)];
     particle.position = tint_symbol_1;
   }
   return;
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.fxc.hlsl
index f8a5412..c2dd3d6 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.fxc.hlsl
@@ -22,16 +22,19 @@
 }
 
 Particle particles_load(uint offset) {
-  Particle tint_symbol_2 = {particles_load_1((offset + 0u)), asfloat(particles.Load((offset + 128u))), asfloat(particles.Load4((offset + 144u))), asfloat(particles.Load3((offset + 160u)))};
-  return tint_symbol_2;
+  Particle tint_symbol_5 = {particles_load_1((offset + 0u)), asfloat(particles.Load((offset + 128u))), asfloat(particles.Load4((offset + 144u))), asfloat(particles.Load3((offset + 160u)))};
+  return tint_symbol_5;
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  Particle particle = particles_load(0u);
+  uint tint_symbol_3 = 0u;
+  particles.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 176u);
+  Particle particle = particles_load((176u * min(0u, (tint_symbol_4 - 1u))));
   {
     float3 tint_symbol_1[8] = particle.position;
-    tint_symbol_1[sim[0].x] = particle.position[sim[0].x];
+    tint_symbol_1[min(sim[0].x, 7u)] = particle.position[min(sim[0].x, 7u)];
     particle.position = tint_symbol_1;
   }
   return;
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.glsl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.glsl
index 62f77d5..99c41c5 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.glsl
@@ -26,8 +26,10 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  Particle particle = particles.p[0];
-  uint v_1 = v.inner.i;
-  uint v_2 = v.inner.i;
-  particle.position[v_1] = particle.position[v_2];
+  uint v_1 = (uint(particles.p.length()) - 1u);
+  uint v_2 = min(uint(0), v_1);
+  Particle particle = particles.p[v_2];
+  uint v_3 = min(v.inner.i, 7u);
+  uint v_4 = min(v.inner.i, 7u);
+  particle.position[v_3] = particle.position[v_4];
 }
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.dxc.hlsl
index 03a9a03..dbaf744 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.dxc.hlsl
@@ -40,9 +40,12 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  Particle particle = v_4(0u);
-  uint v_7 = sim[0u].x;
-  uint v_8 = sim[0u].x;
-  particle.position[v_7] = particle.position[v_8];
+  uint v_7 = 0u;
+  particles.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 176u) - 1u);
+  Particle particle = v_4((0u + (min(uint(int(0)), v_8) * 176u)));
+  uint v_9 = min(sim[0u].x, 7u);
+  uint v_10 = min(sim[0u].x, 7u);
+  particle.position[v_9] = particle.position[v_10];
 }
 
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.fxc.hlsl
index 6bab655..bd5bf44 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.fxc.hlsl
@@ -40,12 +40,15 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  Particle particle = v_4(0u);
-  uint v_7 = sim[0u].x;
-  uint v_8 = sim[0u].x;
+  uint v_7 = 0u;
+  particles.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 176u) - 1u);
+  Particle particle = v_4((0u + (min(uint(int(0)), v_8) * 176u)));
+  uint v_9 = sim[0u].x;
+  uint v_10 = min(sim[0u].x, 7u);
   float3 tint_array_copy[8] = particle.position;
-  tint_array_copy[v_7] = particle.position[v_8];
-  float3 v_9[8] = tint_array_copy;
-  particle.position = v_9;
+  tint_array_copy[min(v_9, 7u)] = particle.position[v_10];
+  float3 v_11[8] = tint_array_copy;
+  particle.position = v_11;
 }
 
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.msl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.msl
index fbb5d7a..d2fd112 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.ir.msl
@@ -45,6 +45,7 @@
 struct tint_module_vars_struct {
   const device Particles_packed_vec3* particles;
   const constant Simulation* sim;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 tint_array<float3, 8> tint_load_array_packed_vec3(const device tint_array<tint_packed_vec3_f32_array_element, 8>* const from) {
@@ -65,8 +66,9 @@
   return Particle{.position=v_7, .lifetime=v_8, .color=v_9, .velocity=float3((*from).velocity)};
 }
 
-kernel void tint_symbol(const device Particles_packed_vec3* particles [[buffer(1)]], const constant Simulation* sim [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.particles=particles, .sim=sim};
-  Particle particle = tint_load_struct_packed_vec3((&(*tint_module_vars.particles).p[0]));
-  particle.position[(*tint_module_vars.sim).i] = particle.position[(*tint_module_vars.sim).i];
+kernel void tint_symbol(const device Particles_packed_vec3* particles [[buffer(1)]], const constant Simulation* sim [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.particles=particles, .sim=sim, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
+  uint const v_10 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 176u) - 1u);
+  Particle particle = tint_load_struct_packed_vec3((&(*tint_module_vars.particles).p[min(uint(0), v_10)]));
+  particle.position[min((*tint_module_vars.sim).i, 7u)] = particle.position[min((*tint_module_vars.sim).i, 7u)];
 }
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.msl b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.msl
index cccb53c..936a5ae 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.msl
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.msl
@@ -53,6 +53,10 @@
   return result;
 }
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Simulation {
   /* 0x0000 */ uint i;
 };
@@ -61,9 +65,9 @@
   tint_array<Particle, 1> p;
 };
 
-kernel void tint_symbol(const device Particles_tint_packed_vec3* tint_symbol_1 [[buffer(1)]], const constant Simulation* tint_symbol_2 [[buffer(0)]]) {
-  Particle particle = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).p[0]);
-  particle.position[(*(tint_symbol_2)).i] = particle.position[(*(tint_symbol_2)).i];
+kernel void tint_symbol(const device Particles_tint_packed_vec3* tint_symbol_1 [[buffer(1)]], const constant TintArrayLengths* tint_symbol_2 [[buffer(30)]], const constant Simulation* tint_symbol_3 [[buffer(0)]]) {
+  Particle particle = tint_unpack_vec3_in_composite_1((*(tint_symbol_1)).p[min(0u, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 176u) - 1u))]);
+  particle.position[min((*(tint_symbol_3)).i, 7u)] = particle.position[min((*(tint_symbol_3)).i, 7u)];
   return;
 }
 
diff --git a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.spvasm b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.spvasm
index d35027d..77d9c54 100644
--- a/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/indexed_assign_to_array_in_struct/1206.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -55,26 +56,36 @@
          %12 = OpVariable %_ptr_Uniform_sim_block Uniform
        %void = OpTypeVoid
          %18 = OpTypeFunction %void
-%_ptr_StorageBuffer_Particle = OpTypePointer StorageBuffer %Particle
+%_ptr_StorageBuffer__runtimearr_Particle = OpTypePointer StorageBuffer %_runtimearr_Particle
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_Particle = OpTypePointer StorageBuffer %Particle
 %_ptr_Function_Particle = OpTypePointer Function %Particle
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %main = OpFunction %void None %18
          %19 = OpLabel
    %particle = OpVariable %_ptr_Function_Particle Function
-         %20 = OpAccessChain %_ptr_StorageBuffer_Particle %particles %uint_0 %int_0
-         %25 = OpLoad %Particle %20 None
-               OpStore %particle %25
-         %28 = OpAccessChain %_ptr_Uniform_uint %12 %uint_0 %uint_0
-         %30 = OpLoad %uint %28 None
-         %31 = OpAccessChain %_ptr_Function_v3float %particle %uint_0 %30
-         %33 = OpAccessChain %_ptr_Uniform_uint %12 %uint_0 %uint_0
-         %34 = OpLoad %uint %33 None
-         %35 = OpAccessChain %_ptr_Function_v3float %particle %uint_0 %34
-         %36 = OpLoad %v3float %35 None
-               OpStore %31 %36 None
+         %20 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Particle %particles %uint_0
+         %23 = OpArrayLength %uint %particles 0
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_0
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpAccessChain %_ptr_StorageBuffer_Particle %particles %uint_0 %29
+         %33 = OpLoad %Particle %31 None
+               OpStore %particle %33
+         %36 = OpAccessChain %_ptr_Uniform_uint %12 %uint_0 %uint_0
+         %38 = OpLoad %uint %36 None
+         %39 = OpExtInst %uint %30 UMin %38 %uint_7
+         %41 = OpAccessChain %_ptr_Function_v3float %particle %uint_0 %39
+         %43 = OpAccessChain %_ptr_Uniform_uint %12 %uint_0 %uint_0
+         %44 = OpLoad %uint %43 None
+         %45 = OpExtInst %uint %30 UMin %44 %uint_7
+         %46 = OpAccessChain %_ptr_Function_v3float %particle %uint_0 %45
+         %47 = OpLoad %v3float %46 None
+               OpStore %41 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.dxc.hlsl
index ea6cf2e..c53829f 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_scalar(m1, uniforms[0].x, 0, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), 0, 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.fxc.hlsl
index ea6cf2e..c53829f 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_scalar(m1, uniforms[0].x, 0, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), 0, 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.glsl
index 4ef031e..ae7af64 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
-  uint v_1 = v.inner.i;
-  m1[v_1][0] = 1.0f;
+  uint v_1 = min(v.inner.i, 1u);
+  m1[v_1][0u] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
index de1ad7d..712038f 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  uint v = uniforms[0u].x;
+  uint v = min(uniforms[0u].x, 1u);
   m1[v].x = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.msl
index d0393ac..e497322 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.ir.msl
@@ -13,5 +13,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   float2x4 m1 = float2x4(0.0f);
-  m1[(*tint_module_vars.uniforms).i][0] = 1.0f;
+  m1[min((*tint_module_vars.uniforms).i, 1u)][0u] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.msl
index 82056b4..ebdf3a4 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.msl
@@ -8,7 +8,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   float2x4 m1 = float2x4(0.0f);
-  m1[(*(tint_symbol_1)).i][0] = 1.0f;
+  m1[min((*(tint_symbol_1)).i, 1u)][0] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.spvasm
index 585bbb9..4ddd67e 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_x.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,18 +36,18 @@
          %15 = OpConstantNull %mat2v4float
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
 %_ptr_Function_float = OpTypePointer Function %float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %8
           %9 = OpLabel
          %m1 = OpVariable %_ptr_Function_mat2v4float Function %15
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Function_v4float %m1 %19
-         %22 = OpAccessChain %_ptr_Function_float %20 %int_0
-               OpStore %22 %float_1 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Function_v4float %m1 %20
+         %25 = OpAccessChain %_ptr_Function_float %23 %uint_0
+               OpStore %25 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.dxc.hlsl
index 45e9234..153660a 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_scalar(m1, uniforms[0].x, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.fxc.hlsl
index 45e9234..153660a 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_scalar(m1, uniforms[0].x, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.glsl
index 095ea4f..8293dae 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
-  uint v_1 = v.inner.i;
-  m1[v_1][v.inner.j] = 1.0f;
+  uint v_1 = min(v.inner.i, 1u);
+  m1[v_1][min(v.inner.j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
index 72f575a..78b4830 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  uint v = uniforms[0u].x;
-  m1[v][uniforms[0u].y] = 1.0f;
+  uint v = min(uniforms[0u].x, 1u);
+  m1[v][min(uniforms[0u].y, 3u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.msl
index ba672da..717b919 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.ir.msl
@@ -13,5 +13,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   float2x4 m1 = float2x4(0.0f);
-  m1[(*tint_module_vars.uniforms).i][(*tint_module_vars.uniforms).j] = 1.0f;
+  m1[min((*tint_module_vars.uniforms).i, 1u)][min((*tint_module_vars.uniforms).j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.msl
index ea2b9ba..7711b47 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.msl
@@ -8,7 +8,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   float2x4 m1 = float2x4(0.0f);
-  m1[(*(tint_symbol_1)).i][(*(tint_symbol_1)).j] = 1.0f;
+  m1[min((*(tint_symbol_1)).i, 1u)][min((*(tint_symbol_1)).j, 3u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.spvasm
index 1084f3a..6cbb576 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_xy.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,8 +36,9 @@
          %15 = OpConstantNull %mat2v4float
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
-%_ptr_Function_v4float = OpTypePointer Function %v4float
      %uint_1 = OpConstant %uint 1
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %8
@@ -44,10 +46,12 @@
          %m1 = OpVariable %_ptr_Function_mat2v4float Function %15
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Function_v4float %m1 %19
-         %22 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-         %24 = OpLoad %uint %22 None
-         %25 = OpAccessChain %_ptr_Function_float %20 %24
-               OpStore %25 %float_1 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Function_v4float %m1 %20
+         %25 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+         %26 = OpLoad %uint %25 None
+         %27 = OpExtInst %uint %21 UMin %26 %uint_3
+         %29 = OpAccessChain %_ptr_Function_float %23 %27
+               OpStore %29 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.dxc.hlsl
index 03fba5d..23647d7 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, 0, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, 0, min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.fxc.hlsl
index 03fba5d..23647d7 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, 0, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, 0, min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.glsl
index 95b2d02..fad0e94 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.glsl
@@ -13,5 +13,5 @@
 mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  m1[0][v.inner.j] = 1.0f;
+  m1[0u][min(v.inner.j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
index a1e1795..b94aa3d 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
@@ -5,6 +5,6 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  m1[int(0)][uniforms[0u].y] = 1.0f;
+  m1[0u][min(uniforms[0u].y, 3u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
index 6fa43fc..6668acb 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
@@ -5,8 +5,8 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  float4 v = m1[int(0)];
+  float4 v = m1[0u];
   float4 v_1 = uniforms[0u].y.xxxx;
-  m1[int(0)] = (((v_1 == float4(int(0), int(1), int(2), int(3)))) ? (1.0f.xxxx) : (v));
+  m1[0u] = (((v_1 == float4(int(0), int(1), int(2), int(3)))) ? (1.0f.xxxx) : (v));
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.msl
index 51aeb13..1454815 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.ir.msl
@@ -14,5 +14,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   thread float2x4 m1 = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .m1=(&m1)};
-  (*tint_module_vars.m1)[0][(*tint_module_vars.uniforms).j] = 1.0f;
+  (*tint_module_vars.m1)[0u][min((*tint_module_vars.uniforms).j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.msl
index d599ebc..2e69b39 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.msl
@@ -12,7 +12,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.m1[0][(*(tint_symbol_1)).j] = 1.0f;
+  tint_private_vars.m1[0][min((*(tint_symbol_1)).j, 3u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.spvasm
index e4fa7a6..ed51d71 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_scalar_y.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,19 +36,19 @@
        %void = OpTypeVoid
          %14 = OpTypeFunction %void
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-%_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_1 = OpConstant %uint 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Private_v4float %m1 %int_0
-         %20 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-         %24 = OpLoad %uint %20 None
-         %25 = OpAccessChain %_ptr_Private_float %16 %24
-               OpStore %25 %float_1 None
+         %16 = OpAccessChain %_ptr_Private_v4float %m1 %uint_0
+         %19 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+         %22 = OpLoad %uint %19 None
+         %23 = OpExtInst %uint %24 UMin %22 %uint_3
+         %26 = OpAccessChain %_ptr_Private_float %16 %23
+               OpStore %26 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.dxc.hlsl
index b7b3c87..f97795d 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.dxc.hlsl
@@ -12,6 +12,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_column(m1, uniforms[0].x, (1.0f).xxxx);
+  set_matrix_column(m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.fxc.hlsl
index b7b3c87..f97795d 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.fxc.hlsl
@@ -12,6 +12,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-  set_matrix_column(m1, uniforms[0].x, (1.0f).xxxx);
+  set_matrix_column(m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.glsl
index 1c78910..3a8253b 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
-  uint v_1 = v.inner.i;
+  uint v_1 = min(v.inner.i, 1u);
   m1[v_1] = vec4(1.0f);
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.dxc.hlsl
index d70b912..a7f5790 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  uint v = uniforms[0u].x;
+  uint v = min(uniforms[0u].x, 1u);
   m1[v] = (1.0f).xxxx;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.msl
index fb81238..1b923a1 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.ir.msl
@@ -13,5 +13,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   float2x4 m1 = float2x4(0.0f);
-  m1[(*tint_module_vars.uniforms).i] = float4(1.0f);
+  m1[min((*tint_module_vars.uniforms).i, 1u)] = float4(1.0f);
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.msl
index a5aed7f..f3a3712 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.msl
@@ -8,7 +8,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   float2x4 m1 = float2x4(0.0f);
-  m1[(*(tint_symbol_1)).i] = float4(1.0f);
+  m1[min((*(tint_symbol_1)).i, 1u)] = float4(1.0f);
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.spvasm
index 1e77ece..1bd33f7 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/local_assign_vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,15 +36,17 @@
          %15 = OpConstantNull %mat2v4float
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
     %float_1 = OpConstant %float 1
-         %22 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
        %main = OpFunction %void None %8
           %9 = OpLabel
          %m1 = OpVariable %_ptr_Function_mat2v4float Function %15
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Function_v4float %m1 %19
-               OpStore %20 %22 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Function_v4float %m1 %20
+               OpStore %23 %25 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.dxc.hlsl
index f8b97cf..f35ed62 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, uniforms[0].x, 0, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), 0, 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.fxc.hlsl
index f8b97cf..f35ed62 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, uniforms[0].x, 0, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), 0, 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.glsl
index ff920c4..7a5832c 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint v_1 = v.inner.i;
-  m1[v_1][0] = 1.0f;
+  uint v_1 = min(v.inner.i, 1u);
+  m1[v_1][0u] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
index ecf0657..11fd393 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  uint v = uniforms[0u].x;
+  uint v = min(uniforms[0u].x, 1u);
   m1[v].x = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.msl
index e59f055..b98c116 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.ir.msl
@@ -14,5 +14,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   thread float2x4 m1 = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .m1=(&m1)};
-  (*tint_module_vars.m1)[(*tint_module_vars.uniforms).i][0] = 1.0f;
+  (*tint_module_vars.m1)[min((*tint_module_vars.uniforms).i, 1u)][0u] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.msl
index 236ea4b..e6ecea3 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.msl
@@ -12,7 +12,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.m1[(*(tint_symbol_1)).i][0] = 1.0f;
+  tint_private_vars.m1[min((*(tint_symbol_1)).i, 1u)][0] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.spvasm
index 78b504d..60e1210 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_x.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,17 +37,17 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Private_v4float = OpTypePointer Private %v4float
 %_ptr_Private_float = OpTypePointer Private %float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %14
          %15 = OpLabel
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Private_v4float %m1 %19
-         %22 = OpAccessChain %_ptr_Private_float %20 %int_0
-               OpStore %22 %float_1 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Private_v4float %m1 %20
+         %25 = OpAccessChain %_ptr_Private_float %23 %uint_0
+               OpStore %25 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.dxc.hlsl
index 62c740c5..d9510b8 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, uniforms[0].x, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.fxc.hlsl
index 62c740c5..d9510b8 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, uniforms[0].x, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, min(uniforms[0].x, 1u), min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.glsl
index ae8ae48..e6255f0 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint v_1 = v.inner.i;
-  m1[v_1][v.inner.j] = 1.0f;
+  uint v_1 = min(v.inner.i, 1u);
+  m1[v_1][min(v.inner.j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
index dc9d126..2ce6dfd 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  uint v = uniforms[0u].x;
-  m1[v][uniforms[0u].y] = 1.0f;
+  uint v = min(uniforms[0u].x, 1u);
+  m1[v][min(uniforms[0u].y, 3u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.msl
index e08cdbb..9ca7bb3 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.ir.msl
@@ -14,5 +14,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   thread float2x4 m1 = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .m1=(&m1)};
-  (*tint_module_vars.m1)[(*tint_module_vars.uniforms).i][(*tint_module_vars.uniforms).j] = 1.0f;
+  (*tint_module_vars.m1)[min((*tint_module_vars.uniforms).i, 1u)][min((*tint_module_vars.uniforms).j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.msl
index 41f85ae..449e8cb 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.msl
@@ -12,7 +12,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.m1[(*(tint_symbol_1)).i][(*(tint_symbol_1)).j] = 1.0f;
+  tint_private_vars.m1[min((*(tint_symbol_1)).i, 1u)][min((*(tint_symbol_1)).j, 3u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.spvasm
index aa18430..11d4117 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_xy.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,18 +37,21 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
-%_ptr_Private_v4float = OpTypePointer Private %v4float
      %uint_1 = OpConstant %uint 1
+%_ptr_Private_v4float = OpTypePointer Private %v4float
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %14
          %15 = OpLabel
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Private_v4float %m1 %19
-         %22 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-         %24 = OpLoad %uint %22 None
-         %25 = OpAccessChain %_ptr_Private_float %20 %24
-               OpStore %25 %float_1 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Private_v4float %m1 %20
+         %25 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+         %26 = OpLoad %uint %25 None
+         %27 = OpExtInst %uint %21 UMin %26 %uint_3
+         %29 = OpAccessChain %_ptr_Private_float %23 %27
+               OpStore %29 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.dxc.hlsl
index 03fba5d..23647d7 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.dxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, 0, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, 0, min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.fxc.hlsl
index 03fba5d..23647d7 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.fxc.hlsl
@@ -16,6 +16,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_scalar(m1, 0, uniforms[0].y, 1.0f);
+  set_matrix_scalar(m1, 0, min(uniforms[0].y, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.glsl
index 95b2d02..fad0e94 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.glsl
@@ -13,5 +13,5 @@
 mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  m1[0][v.inner.j] = 1.0f;
+  m1[0u][min(v.inner.j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
index a1e1795..b94aa3d 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.dxc.hlsl
@@ -5,6 +5,6 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  m1[int(0)][uniforms[0u].y] = 1.0f;
+  m1[0u][min(uniforms[0u].y, 3u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
index 6fa43fc..6668acb 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.fxc.hlsl
@@ -5,8 +5,8 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  float4 v = m1[int(0)];
+  float4 v = m1[0u];
   float4 v_1 = uniforms[0u].y.xxxx;
-  m1[int(0)] = (((v_1 == float4(int(0), int(1), int(2), int(3)))) ? (1.0f.xxxx) : (v));
+  m1[0u] = (((v_1 == float4(int(0), int(1), int(2), int(3)))) ? (1.0f.xxxx) : (v));
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.msl
index 51aeb13..1454815 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.ir.msl
@@ -14,5 +14,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   thread float2x4 m1 = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .m1=(&m1)};
-  (*tint_module_vars.m1)[0][(*tint_module_vars.uniforms).j] = 1.0f;
+  (*tint_module_vars.m1)[0u][min((*tint_module_vars.uniforms).j, 3u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.msl
index d599ebc..2e69b39 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.msl
@@ -12,7 +12,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.m1[0][(*(tint_symbol_1)).j] = 1.0f;
+  tint_private_vars.m1[0][min((*(tint_symbol_1)).j, 3u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.spvasm
index e4fa7a6..ed51d71 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_scalar_y.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,19 +36,19 @@
        %void = OpTypeVoid
          %14 = OpTypeFunction %void
 %_ptr_Private_v4float = OpTypePointer Private %v4float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-%_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_1 = OpConstant %uint 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Private_v4float %m1 %int_0
-         %20 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-         %24 = OpLoad %uint %20 None
-         %25 = OpAccessChain %_ptr_Private_float %16 %24
-               OpStore %25 %float_1 None
+         %16 = OpAccessChain %_ptr_Private_v4float %m1 %uint_0
+         %19 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+         %22 = OpLoad %uint %19 None
+         %23 = OpExtInst %uint %24 UMin %22 %uint_3
+         %26 = OpAccessChain %_ptr_Private_float %16 %23
+               OpStore %26 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.dxc.hlsl
index e2ba202..a03ac86 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.dxc.hlsl
@@ -12,6 +12,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_column(m1, uniforms[0].x, (1.0f).xxxx);
+  set_matrix_column(m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.fxc.hlsl
index e2ba202..a03ac86 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.fxc.hlsl
@@ -12,6 +12,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_matrix_column(m1, uniforms[0].x, (1.0f).xxxx);
+  set_matrix_column(m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
   return;
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.glsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.glsl
index f6e1892..28b025d 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.glsl
@@ -13,6 +13,6 @@
 mat2x4 m1 = mat2x4(vec4(0.0f), vec4(0.0f));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint v_1 = v.inner.i;
+  uint v_1 = min(v.inner.i, 1u);
   m1[v_1] = vec4(1.0f);
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.dxc.hlsl
index 84f8202..f3b259f 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,7 @@
 static float2x4 m1 = float2x4((0.0f).xxxx, (0.0f).xxxx);
 [numthreads(1, 1, 1)]
 void main() {
-  uint v = uniforms[0u].x;
+  uint v = min(uniforms[0u].x, 1u);
   m1[v] = (1.0f).xxxx;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.msl
index 1fecf66..a4d36e1 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.ir.msl
@@ -14,5 +14,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   thread float2x4 m1 = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .m1=(&m1)};
-  (*tint_module_vars.m1)[(*tint_module_vars.uniforms).i] = float4(1.0f);
+  (*tint_module_vars.m1)[min((*tint_module_vars.uniforms).i, 1u)] = float4(1.0f);
 }
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.msl b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.msl
index fbdeeb9..2f95b5e 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.msl
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.msl
@@ -12,7 +12,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.m1[(*(tint_symbol_1)).i] = float4(1.0f);
+  tint_private_vars.m1[min((*(tint_symbol_1)).i, 1u)] = float4(1.0f);
   return;
 }
 
diff --git a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.spvasm b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.spvasm
index b3a1546..9f72b43 100644
--- a/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/matrix_assignment_dynamic_index/module_assign_vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,14 +37,16 @@
          %14 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Private_v4float = OpTypePointer Private %v4float
     %float_1 = OpConstant %float 1
-         %22 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %25 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
        %main = OpFunction %void None %14
          %15 = OpLabel
          %16 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %19 = OpLoad %uint %16 None
-         %20 = OpAccessChain %_ptr_Private_v4float %m1 %19
-               OpStore %20 %22 None
+         %20 = OpExtInst %uint %21 UMin %19 %uint_1
+         %23 = OpAccessChain %_ptr_Private_v4float %m1 %20
+               OpStore %23 %25 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.dxc.hlsl
index bd0c260..2f28b96 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.dxc.hlsl
@@ -9,6 +9,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3 v1 = float3(0.0f, 0.0f, 0.0f);
-  set_vector_element(v1, i[0].x, 1.0f);
+  set_vector_element(v1, min(i[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.fxc.hlsl
index bd0c260..2f28b96 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.fxc.hlsl
@@ -9,6 +9,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3 v1 = float3(0.0f, 0.0f, 0.0f);
-  set_vector_element(v1, i[0].x, 1.0f);
+  set_vector_element(v1, min(i[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.glsl
index 4b564cd..47d4cfa 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.glsl
@@ -7,5 +7,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   vec3 v1 = vec3(0.0f);
-  v1[v.inner] = 1.0f;
+  v1[min(v.inner, 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.dxc.hlsl
index 24851e9..4f2d982 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.dxc.hlsl
@@ -5,6 +5,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3 v1 = (0.0f).xxx;
-  v1[i[0u].x] = 1.0f;
+  v1[min(i[0u].x, 2u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.msl
index 164ff26..29fa740 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 kernel void tint_symbol(const constant uint* i [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.i=i};
   float3 v1 = 0.0f;
-  v1[(*tint_module_vars.i)] = 1.0f;
+  v1[min((*tint_module_vars.i), 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.msl
index c4924dc..672d75f 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 kernel void tint_symbol(const constant uint* tint_symbol_1 [[buffer(0)]]) {
   float3 v1 = 0.0f;
-  v1[*(tint_symbol_1)] = 1.0f;
+  v1[min(*(tint_symbol_1), 2u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.spvasm
index 4139edf..9887e89 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/function_var.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -28,6 +29,7 @@
          %13 = OpConstantNull %v3float
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %7
@@ -35,7 +37,8 @@
          %v1 = OpVariable %_ptr_Function_v3float Function %13
          %14 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0
          %17 = OpLoad %uint %14 None
-         %18 = OpAccessChain %_ptr_Function_float %v1 %17
-               OpStore %18 %float_1 None
+         %18 = OpExtInst %uint %19 UMin %17 %uint_2
+         %21 = OpAccessChain %_ptr_Function_float %v1 %18
+               OpStore %21 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.dxc.hlsl
index ff5cf5b..e77ba7e 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.dxc.hlsl
@@ -9,6 +9,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_vector_element(v1, i[0].x, 1.0f);
+  set_vector_element(v1, min(i[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.fxc.hlsl
index ff5cf5b..e77ba7e 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.fxc.hlsl
@@ -9,6 +9,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  set_vector_element(v1, i[0].x, 1.0f);
+  set_vector_element(v1, min(i[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.glsl
index 6a225c6..9f9d6aa 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.glsl
@@ -7,5 +7,5 @@
 vec3 v1 = vec3(0.0f);
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  v1[v.inner] = 1.0f;
+  v1[min(v.inner, 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.dxc.hlsl
index bb0d174..9d46797 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.dxc.hlsl
@@ -5,6 +5,6 @@
 static float3 v1 = (0.0f).xxx;
 [numthreads(1, 1, 1)]
 void main() {
-  v1[i[0u].x] = 1.0f;
+  v1[min(i[0u].x, 2u)] = 1.0f;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.msl
index 16c0883..e02426a 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.ir.msl
@@ -9,5 +9,5 @@
 kernel void tint_symbol(const constant uint* i [[buffer(0)]]) {
   thread float3 v1 = 0.0f;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.i=i, .v1=(&v1)};
-  (*tint_module_vars.v1)[(*tint_module_vars.i)] = 1.0f;
+  (*tint_module_vars.v1)[min((*tint_module_vars.i), 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.msl
index 2165cfa..e2c85ca 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.msl
@@ -7,7 +7,7 @@
 
 kernel void tint_symbol(const constant uint* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.v1[*(tint_symbol_1)] = 1.0f;
+  tint_private_vars.v1[min(*(tint_symbol_1), 2u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.spvasm
index 2511260..3beabce 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/private_var.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -29,13 +30,15 @@
          %12 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %12
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0
          %17 = OpLoad %uint %14 None
-         %18 = OpAccessChain %_ptr_Private_float %v1 %17
-               OpStore %18 %float_1 None
+         %18 = OpExtInst %uint %19 UMin %17 %uint_2
+         %21 = OpAccessChain %_ptr_Private_float %v1 %18
+               OpStore %21 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.dxc.hlsl
index 4cd1c3f..bb2ba60 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.dxc.hlsl
@@ -5,6 +5,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  v1.Store((4u * i[0].x), asuint(1.0f));
+  v1.Store((4u * min(i[0].x, 2u)), asuint(1.0f));
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.fxc.hlsl
index 4cd1c3f..bb2ba60 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.fxc.hlsl
@@ -5,6 +5,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  v1.Store((4u * i[0].x), asuint(1.0f));
+  v1.Store((4u * min(i[0].x, 2u)), asuint(1.0f));
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.glsl
index 55a101d..36687ce 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 } v_1;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  v_1.inner[v.inner] = 1.0f;
+  v_1.inner[min(v.inner, 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.dxc.hlsl
index ad136e3..2dbe6c3 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.dxc.hlsl
@@ -5,6 +5,6 @@
 RWByteAddressBuffer v1 : register(u1);
 [numthreads(1, 1, 1)]
 void main() {
-  v1.Store((0u + (i[0u].x * 4u)), asuint(1.0f));
+  v1.Store((0u + (min(i[0u].x, 2u) * 4u)), asuint(1.0f));
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.fxc.hlsl
index ad136e3..2dbe6c3 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.fxc.hlsl
@@ -5,6 +5,6 @@
 RWByteAddressBuffer v1 : register(u1);
 [numthreads(1, 1, 1)]
 void main() {
-  v1.Store((0u + (i[0u].x * 4u)), asuint(1.0f));
+  v1.Store((0u + (min(i[0u].x, 2u) * 4u)), asuint(1.0f));
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.msl
index 771c8d1..9bf51aa 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 
 kernel void tint_symbol(const constant uint* i [[buffer(0)]], device packed_float3* v1 [[buffer(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.i=i, .v1=v1};
-  (*tint_module_vars.v1)[(*tint_module_vars.i)] = 1.0f;
+  (*tint_module_vars.v1)[min((*tint_module_vars.i), 2u)] = 1.0f;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.msl
index a6f8f48..8ba2d21 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 kernel void tint_symbol(device packed_float3* tint_symbol_1 [[buffer(1)]], const constant uint* tint_symbol_2 [[buffer(0)]]) {
-  (*(tint_symbol_1))[*(tint_symbol_2)] = 1.0f;
+  (*(tint_symbol_1))[min(*(tint_symbol_2), 2u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.spvasm
index 2092fe2..533c53b 100644
--- a/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_dynamic_index/storage_var.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 23
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,6 +36,7 @@
          %12 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
     %float_1 = OpConstant %float 1
@@ -42,8 +44,9 @@
          %13 = OpLabel
          %14 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0
          %17 = OpLoad %uint %14 None
-         %18 = OpAccessChain %_ptr_StorageBuffer_v3float %5 %uint_0
-         %20 = OpAccessChain %_ptr_StorageBuffer_float %18 %17
-               OpStore %20 %float_1 None
+         %18 = OpExtInst %uint %19 UMin %17 %uint_2
+         %21 = OpAccessChain %_ptr_StorageBuffer_v3float %5 %uint_0
+         %23 = OpAccessChain %_ptr_StorageBuffer_float %21 %18
+               OpStore %23 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.dxc.hlsl
index 1bc07f3..032aab6 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.dxc.hlsl
@@ -22,10 +22,10 @@
 void foo() {
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3i, i, 1);
-      set_vector_element_2(v4u, i, 1u);
-      set_vector_element_3(v2b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
     }
   }
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.fxc.hlsl
index 1bc07f3..032aab6 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.fxc.hlsl
@@ -22,10 +22,10 @@
 void foo() {
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3i, i, 1);
-      set_vector_element_2(v4u, i, 1u);
-      set_vector_element_3(v2b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
     }
   }
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.glsl
index b7cc5a4..06e4548 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.glsl
@@ -12,10 +12,10 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3i[i] = 1;
-      v4u[i] = 1u;
-      v2b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3i[min(uint(i), 2u)] = 1;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
       {
         i = (i + 1);
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.dxc.hlsl
index cc983da..979faf1 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.dxc.hlsl
@@ -11,10 +11,10 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3i[i] = int(1);
-      v4u[i] = 1u;
-      v2b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3i[min(uint(i), 2u)] = int(1);
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
       {
         i = (i + int(1));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.msl
index 81d543b..a1d07e8 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.ir.msl
@@ -16,10 +16,10 @@
       } else {
         break;
       }
-      (*tint_module_vars.v2f)[i] = 1.0f;
-      (*tint_module_vars.v3i)[i] = 1;
-      (*tint_module_vars.v4u)[i] = 1u;
-      (*tint_module_vars.v2b)[i] = true;
+      (*tint_module_vars.v2f)[min(uint(i), 1u)] = 1.0f;
+      (*tint_module_vars.v3i)[min(uint(i), 2u)] = 1;
+      (*tint_module_vars.v4u)[min(uint(i), 3u)] = 1u;
+      (*tint_module_vars.v2b)[min(uint(i), 1u)] = true;
       {
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.msl
index 91fd58a..25881ae 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   float2 v2f;
   int3 v3i;
@@ -10,16 +14,18 @@
 
 void foo(thread tint_private_vars_struct* const tint_private_vars) {
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    (*(tint_private_vars)).v2f[i] = 1.0f;
-    (*(tint_private_vars)).v3i[i] = 1;
-    (*(tint_private_vars)).v4u[i] = 1u;
-    (*(tint_private_vars)).v2b[i] = true;
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(tint_private_vars)).v2f[min(uint(i), 1u)] = 1.0f;
+    (*(tint_private_vars)).v3i[min(uint(i), 2u)] = 1;
+    (*(tint_private_vars)).v4u[min(uint(i), 3u)] = 1u;
+    (*(tint_private_vars)).v2b[min(uint(i), 1u)] = true;
   }
 }
 
 kernel void tint_symbol() {
   thread tint_private_vars_struct tint_private_vars = {};
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     foo(&(tint_private_vars));
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.spvasm
index e934fa6..4c33b38 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_loop.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -40,12 +41,14 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
       %int_2 = OpConstant %int 2
+     %uint_1 = OpConstant %uint 1
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_int = OpTypePointer Private %int
       %int_1 = OpConstant %int 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_uint = OpTypePointer Private %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Private_bool = OpTypePointer Private %bool
        %true = OpConstantTrue %bool
         %foo = OpFunction %void None %23
@@ -67,51 +70,59 @@
                OpBranch %29
          %36 = OpLabel
          %38 = OpLoad %int %i None
-         %39 = OpAccessChain %_ptr_Private_float %v2f %38
-               OpStore %39 %float_1 None
-         %42 = OpLoad %int %i None
-         %43 = OpAccessChain %_ptr_Private_int %v3i %42
-               OpStore %43 %int_1 None
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %41 UMin %39 %uint_1
+         %43 = OpAccessChain %_ptr_Private_float %v2f %40
+               OpStore %43 %float_1 None
          %46 = OpLoad %int %i None
-         %47 = OpAccessChain %_ptr_Private_uint %v4u %46
-               OpStore %47 %uint_1 None
-         %50 = OpLoad %int %i None
-         %51 = OpAccessChain %_ptr_Private_bool %v2b %50
-               OpStore %51 %true None
+         %47 = OpBitcast %uint %46
+         %48 = OpExtInst %uint %41 UMin %47 %uint_2
+         %50 = OpAccessChain %_ptr_Private_int %v3i %48
+               OpStore %50 %int_1 None
+         %53 = OpLoad %int %i None
+         %54 = OpBitcast %uint %53
+         %55 = OpExtInst %uint %41 UMin %54 %uint_3
+         %57 = OpAccessChain %_ptr_Private_uint %v4u %55
+               OpStore %57 %uint_1 None
+         %59 = OpLoad %int %i None
+         %60 = OpBitcast %uint %59
+         %61 = OpExtInst %uint %41 UMin %60 %uint_1
+         %62 = OpAccessChain %_ptr_Private_bool %v2b %61
+               OpStore %62 %true None
                OpBranch %27
          %27 = OpLabel
-         %54 = OpLoad %int %i None
-         %55 = OpIAdd %int %54 %int_1
-               OpStore %i %55 None
+         %65 = OpLoad %int %i None
+         %66 = OpIAdd %int %65 %int_1
+               OpStore %i %66 None
                OpBranch %28
          %29 = OpLabel
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %23
-         %57 = OpLabel
+         %68 = OpLabel
         %i_0 = OpVariable %_ptr_Function_int Function
-               OpBranch %58
-         %58 = OpLabel
+               OpBranch %69
+         %69 = OpLabel
                OpStore %i_0 %int_0
-               OpBranch %61
-         %61 = OpLabel
-               OpLoopMerge %62 %60 None
-               OpBranch %59
-         %59 = OpLabel
-         %64 = OpLoad %int %i_0 None
-         %65 = OpSLessThan %bool %64 %int_2
-               OpSelectionMerge %66 None
-               OpBranchConditional %65 %66 %67
-         %67 = OpLabel
-               OpBranch %62
-         %66 = OpLabel
-         %68 = OpFunctionCall %void %foo
-               OpBranch %60
-         %60 = OpLabel
-         %69 = OpLoad %int %i_0 None
-         %70 = OpIAdd %int %69 %int_1
-               OpStore %i_0 %70 None
-               OpBranch %61
-         %62 = OpLabel
+               OpBranch %72
+         %72 = OpLabel
+               OpLoopMerge %73 %71 None
+               OpBranch %70
+         %70 = OpLabel
+         %75 = OpLoad %int %i_0 None
+         %76 = OpSLessThan %bool %75 %int_2
+               OpSelectionMerge %77 None
+               OpBranchConditional %76 %77 %78
+         %78 = OpLabel
+               OpBranch %73
+         %77 = OpLabel
+         %79 = OpFunctionCall %void %foo
+               OpBranch %71
+         %71 = OpLabel
+         %80 = OpLoad %int %i_0 None
+         %81 = OpIAdd %int %80 %int_1
+               OpStore %i_0 %81 None
+               OpBranch %72
+         %73 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.dxc.hlsl
index bb49c65..64713c7 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.dxc.hlsl
@@ -21,10 +21,10 @@
 
 void foo() {
   int i = 0;
-  set_vector_element(v2f, i, 1.0f);
-  set_vector_element_1(v3i, i, 1);
-  set_vector_element_2(v4u, i, 1u);
-  set_vector_element_3(v2b, i, true);
+  set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+  set_vector_element_1(v3i, min(uint(i), 2u), 1);
+  set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_3(v2b, min(uint(i), 1u), true);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.fxc.hlsl
index bb49c65..64713c7 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.fxc.hlsl
@@ -21,10 +21,10 @@
 
 void foo() {
   int i = 0;
-  set_vector_element(v2f, i, 1.0f);
-  set_vector_element_1(v3i, i, 1);
-  set_vector_element_2(v4u, i, 1u);
-  set_vector_element_3(v2b, i, true);
+  set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+  set_vector_element_1(v3i, min(uint(i), 2u), 1);
+  set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_3(v2b, min(uint(i), 1u), true);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.glsl
index 6068cba..9cd1b74 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.glsl
@@ -6,10 +6,10 @@
 bvec2 v2b = bvec2(false);
 void foo() {
   int i = 0;
-  v2f[i] = 1.0f;
-  v3i[i] = 1;
-  v4u[i] = 1u;
-  v2b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = 1;
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.dxc.hlsl
index efcfa31..4ff6924 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.dxc.hlsl
@@ -5,10 +5,10 @@
 static bool2 v2b = (false).xx;
 void foo() {
   int i = int(0);
-  v2f[i] = 1.0f;
-  v3i[i] = int(1);
-  v4u[i] = 1u;
-  v2b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = int(1);
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.msl
index b0e5153..9899e92 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.ir.msl
@@ -10,10 +10,10 @@
 
 void foo(tint_module_vars_struct tint_module_vars) {
   int i = 0;
-  (*tint_module_vars.v2f)[i] = 1.0f;
-  (*tint_module_vars.v3i)[i] = 1;
-  (*tint_module_vars.v4u)[i] = 1u;
-  (*tint_module_vars.v2b)[i] = true;
+  (*tint_module_vars.v2f)[min(uint(i), 1u)] = 1.0f;
+  (*tint_module_vars.v3i)[min(uint(i), 2u)] = 1;
+  (*tint_module_vars.v4u)[min(uint(i), 3u)] = 1u;
+  (*tint_module_vars.v2b)[min(uint(i), 1u)] = true;
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.msl
index 1c06a5e..8da5f96 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   float2 v2f;
   int3 v3i;
@@ -10,15 +14,16 @@
 
 void foo(thread tint_private_vars_struct* const tint_private_vars) {
   int i = 0;
-  (*(tint_private_vars)).v2f[i] = 1.0f;
-  (*(tint_private_vars)).v3i[i] = 1;
-  (*(tint_private_vars)).v4u[i] = 1u;
-  (*(tint_private_vars)).v2b[i] = true;
+  (*(tint_private_vars)).v2f[min(uint(i), 1u)] = 1.0f;
+  (*(tint_private_vars)).v3i[min(uint(i), 2u)] = 1;
+  (*(tint_private_vars)).v4u[min(uint(i), 3u)] = 1u;
+  (*(tint_private_vars)).v2b[min(uint(i), 1u)] = true;
 }
 
 kernel void tint_symbol() {
   thread tint_private_vars_struct tint_private_vars = {};
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     foo(&(tint_private_vars));
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.spvasm
index a507d24..a0bad64 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_call_with_no_loop.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -39,12 +40,14 @@
          %23 = OpTypeFunction %void
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Private_float = OpTypePointer Private %float
     %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_int = OpTypePointer Private %int
       %int_1 = OpConstant %int 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_uint = OpTypePointer Private %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Private_bool = OpTypePointer Private %bool
        %true = OpConstantTrue %bool
       %int_2 = OpConstant %int 2
@@ -53,44 +56,52 @@
           %i = OpVariable %_ptr_Function_int Function
                OpStore %i %int_0
          %28 = OpLoad %int %i None
-         %29 = OpAccessChain %_ptr_Private_float %v2f %28
-               OpStore %29 %float_1 None
-         %32 = OpLoad %int %i None
-         %33 = OpAccessChain %_ptr_Private_int %v3i %32
-               OpStore %33 %int_1 None
+         %29 = OpBitcast %uint %28
+         %30 = OpExtInst %uint %31 UMin %29 %uint_1
+         %33 = OpAccessChain %_ptr_Private_float %v2f %30
+               OpStore %33 %float_1 None
          %36 = OpLoad %int %i None
-         %37 = OpAccessChain %_ptr_Private_uint %v4u %36
-               OpStore %37 %uint_1 None
-         %40 = OpLoad %int %i None
-         %41 = OpAccessChain %_ptr_Private_bool %v2b %40
-               OpStore %41 %true None
+         %37 = OpBitcast %uint %36
+         %38 = OpExtInst %uint %31 UMin %37 %uint_2
+         %40 = OpAccessChain %_ptr_Private_int %v3i %38
+               OpStore %40 %int_1 None
+         %43 = OpLoad %int %i None
+         %44 = OpBitcast %uint %43
+         %45 = OpExtInst %uint %31 UMin %44 %uint_3
+         %47 = OpAccessChain %_ptr_Private_uint %v4u %45
+               OpStore %47 %uint_1 None
+         %49 = OpLoad %int %i None
+         %50 = OpBitcast %uint %49
+         %51 = OpExtInst %uint %31 UMin %50 %uint_1
+         %52 = OpAccessChain %_ptr_Private_bool %v2b %51
+               OpStore %52 %true None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %23
-         %45 = OpLabel
-        %i_0 = OpVariable %_ptr_Function_int Function
-               OpBranch %46
-         %46 = OpLabel
-               OpStore %i_0 %int_0
-               OpBranch %49
-         %49 = OpLabel
-               OpLoopMerge %50 %48 None
-               OpBranch %47
-         %47 = OpLabel
-         %52 = OpLoad %int %i_0 None
-         %53 = OpSLessThan %bool %52 %int_2
-               OpSelectionMerge %55 None
-               OpBranchConditional %53 %55 %56
          %56 = OpLabel
-               OpBranch %50
-         %55 = OpLabel
-         %57 = OpFunctionCall %void %foo
-               OpBranch %48
-         %48 = OpLabel
-         %58 = OpLoad %int %i_0 None
-         %59 = OpIAdd %int %58 %int_1
-               OpStore %i_0 %59 None
-               OpBranch %49
-         %50 = OpLabel
+        %i_0 = OpVariable %_ptr_Function_int Function
+               OpBranch %57
+         %57 = OpLabel
+               OpStore %i_0 %int_0
+               OpBranch %60
+         %60 = OpLabel
+               OpLoopMerge %61 %59 None
+               OpBranch %58
+         %58 = OpLabel
+         %63 = OpLoad %int %i_0 None
+         %64 = OpSLessThan %bool %63 %int_2
+               OpSelectionMerge %66 None
+               OpBranchConditional %64 %66 %67
+         %67 = OpLabel
+               OpBranch %61
+         %66 = OpLabel
+         %68 = OpFunctionCall %void %foo
+               OpBranch %59
+         %59 = OpLabel
+         %69 = OpLoad %int %i_0 None
+         %70 = OpIAdd %int %69 %int_1
+               OpStore %i_0 %70 None
+               OpBranch %60
+         %61 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.dxc.hlsl
index 2b40cd2..470f9f8 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.dxc.hlsl
@@ -62,18 +62,18 @@
   bool4 v4b = bool4(false, false, false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3f, i, 1.0f);
-      set_vector_element_2(v4f, i, 1.0f);
-      set_vector_element_3(v2i, i, 1);
-      set_vector_element_4(v3i, i, 1);
-      set_vector_element_5(v4i, i, 1);
-      set_vector_element_6(v2u, i, 1u);
-      set_vector_element_7(v3u, i, 1u);
-      set_vector_element_8(v4u, i, 1u);
-      set_vector_element_9(v2b, i, true);
-      set_vector_element_10(v3b, i, true);
-      set_vector_element_11(v4b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3f, min(uint(i), 2u), 1.0f);
+      set_vector_element_2(v4f, min(uint(i), 3u), 1.0f);
+      set_vector_element_3(v2i, min(uint(i), 1u), 1);
+      set_vector_element_4(v3i, min(uint(i), 2u), 1);
+      set_vector_element_5(v4i, min(uint(i), 3u), 1);
+      set_vector_element_6(v2u, min(uint(i), 1u), 1u);
+      set_vector_element_7(v3u, min(uint(i), 2u), 1u);
+      set_vector_element_8(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_9(v2b, min(uint(i), 1u), true);
+      set_vector_element_10(v3b, min(uint(i), 2u), true);
+      set_vector_element_11(v4b, min(uint(i), 3u), true);
     }
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.fxc.hlsl
index 2b40cd2..470f9f8 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.fxc.hlsl
@@ -62,18 +62,18 @@
   bool4 v4b = bool4(false, false, false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3f, i, 1.0f);
-      set_vector_element_2(v4f, i, 1.0f);
-      set_vector_element_3(v2i, i, 1);
-      set_vector_element_4(v3i, i, 1);
-      set_vector_element_5(v4i, i, 1);
-      set_vector_element_6(v2u, i, 1u);
-      set_vector_element_7(v3u, i, 1u);
-      set_vector_element_8(v4u, i, 1u);
-      set_vector_element_9(v2b, i, true);
-      set_vector_element_10(v3b, i, true);
-      set_vector_element_11(v4b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3f, min(uint(i), 2u), 1.0f);
+      set_vector_element_2(v4f, min(uint(i), 3u), 1.0f);
+      set_vector_element_3(v2i, min(uint(i), 1u), 1);
+      set_vector_element_4(v3i, min(uint(i), 2u), 1);
+      set_vector_element_5(v4i, min(uint(i), 3u), 1);
+      set_vector_element_6(v2u, min(uint(i), 1u), 1u);
+      set_vector_element_7(v3u, min(uint(i), 2u), 1u);
+      set_vector_element_8(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_9(v2b, min(uint(i), 1u), true);
+      set_vector_element_10(v3b, min(uint(i), 2u), true);
+      set_vector_element_11(v4b, min(uint(i), 3u), true);
     }
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.glsl
index 1a7a52b..d9c9d31 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.glsl
@@ -21,18 +21,18 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3f[i] = 1.0f;
-      v4f[i] = 1.0f;
-      v2i[i] = 1;
-      v3i[i] = 1;
-      v4i[i] = 1;
-      v2u[i] = 1u;
-      v3u[i] = 1u;
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v3b[i] = true;
-      v4b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3f[min(uint(i), 2u)] = 1.0f;
+      v4f[min(uint(i), 3u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = 1;
+      v3i[min(uint(i), 2u)] = 1;
+      v4i[min(uint(i), 3u)] = 1;
+      v2u[min(uint(i), 1u)] = 1u;
+      v3u[min(uint(i), 2u)] = 1u;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v3b[min(uint(i), 2u)] = true;
+      v4b[min(uint(i), 3u)] = true;
       {
         i = (i + 1);
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.dxc.hlsl
index a2633f2..33c1772 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.dxc.hlsl
@@ -20,18 +20,18 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3f[i] = 1.0f;
-      v4f[i] = 1.0f;
-      v2i[i] = int(1);
-      v3i[i] = int(1);
-      v4i[i] = int(1);
-      v2u[i] = 1u;
-      v3u[i] = 1u;
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v3b[i] = true;
-      v4b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3f[min(uint(i), 2u)] = 1.0f;
+      v4f[min(uint(i), 3u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = int(1);
+      v3i[min(uint(i), 2u)] = int(1);
+      v4i[min(uint(i), 3u)] = int(1);
+      v2u[min(uint(i), 1u)] = 1u;
+      v3u[min(uint(i), 2u)] = 1u;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v3b[min(uint(i), 2u)] = true;
+      v4b[min(uint(i), 3u)] = true;
       {
         i = (i + int(1));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.msl
index b64511b..65d3c70 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.ir.msl
@@ -21,18 +21,18 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3f[i] = 1.0f;
-      v4f[i] = 1.0f;
-      v2i[i] = 1;
-      v3i[i] = 1;
-      v4i[i] = 1;
-      v2u[i] = 1u;
-      v3u[i] = 1u;
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v3b[i] = true;
-      v4b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3f[min(uint(i), 2u)] = 1.0f;
+      v4f[min(uint(i), 3u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = 1;
+      v3i[min(uint(i), 2u)] = 1;
+      v4i[min(uint(i), 3u)] = 1;
+      v2u[min(uint(i), 1u)] = 1u;
+      v3u[min(uint(i), 2u)] = 1u;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v3b[min(uint(i), 2u)] = true;
+      v4b[min(uint(i), 3u)] = true;
       {
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.msl
index eb3e7d2..aeda4b1 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   float2 v2f = 0.0f;
   float3 v3f = 0.0f;
@@ -15,18 +19,19 @@
   bool3 v3b = false;
   bool4 v4b = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    v2f[i] = 1.0f;
-    v3f[i] = 1.0f;
-    v4f[i] = 1.0f;
-    v2i[i] = 1;
-    v3i[i] = 1;
-    v4i[i] = 1;
-    v2u[i] = 1u;
-    v3u[i] = 1u;
-    v4u[i] = 1u;
-    v2b[i] = true;
-    v3b[i] = true;
-    v4b[i] = true;
+    TINT_ISOLATE_UB(tint_volatile_false);
+    v2f[min(uint(i), 1u)] = 1.0f;
+    v3f[min(uint(i), 2u)] = 1.0f;
+    v4f[min(uint(i), 3u)] = 1.0f;
+    v2i[min(uint(i), 1u)] = 1;
+    v3i[min(uint(i), 2u)] = 1;
+    v4i[min(uint(i), 3u)] = 1;
+    v2u[min(uint(i), 1u)] = 1u;
+    v3u[min(uint(i), 2u)] = 1u;
+    v4u[min(uint(i), 3u)] = 1u;
+    v2b[min(uint(i), 1u)] = true;
+    v3b[min(uint(i), 2u)] = true;
+    v4b[min(uint(i), 3u)] = true;
   }
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.spvasm
index 4b4ef6c..8ce5745 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_all.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 103
+; Bound: 130
 ; Schema: 0
                OpCapability Shader
+         %73 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -66,11 +67,13 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
       %int_2 = OpConstant %int 2
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
+     %uint_3 = OpConstant %uint 3
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_bool = OpTypePointer Function %bool
        %true = OpConstantTrue %bool
        %main = OpFunction %void None %3
@@ -104,46 +107,70 @@
                OpBranch %61
          %68 = OpLabel
          %70 = OpLoad %int %i None
-         %71 = OpAccessChain %_ptr_Function_float %v2f %70
-               OpStore %71 %float_1 None
-         %74 = OpLoad %int %i None
-         %75 = OpAccessChain %_ptr_Function_float %v3f %74
+         %71 = OpBitcast %uint %70
+         %72 = OpExtInst %uint %73 UMin %71 %uint_1
+         %75 = OpAccessChain %_ptr_Function_float %v2f %72
                OpStore %75 %float_1 None
-         %76 = OpLoad %int %i None
-         %77 = OpAccessChain %_ptr_Function_float %v4f %76
-               OpStore %77 %float_1 None
          %78 = OpLoad %int %i None
-         %79 = OpAccessChain %_ptr_Function_int %v2i %78
-               OpStore %79 %int_1 None
-         %81 = OpLoad %int %i None
-         %82 = OpAccessChain %_ptr_Function_int %v3i %81
-               OpStore %82 %int_1 None
+         %79 = OpBitcast %uint %78
+         %80 = OpExtInst %uint %73 UMin %79 %uint_2
+         %82 = OpAccessChain %_ptr_Function_float %v3f %80
+               OpStore %82 %float_1 None
          %83 = OpLoad %int %i None
-         %84 = OpAccessChain %_ptr_Function_int %v4i %83
-               OpStore %84 %int_1 None
-         %85 = OpLoad %int %i None
-         %86 = OpAccessChain %_ptr_Function_uint %v2u %85
-               OpStore %86 %uint_1 None
-         %89 = OpLoad %int %i None
-         %90 = OpAccessChain %_ptr_Function_uint %v3u %89
-               OpStore %90 %uint_1 None
-         %91 = OpLoad %int %i None
-         %92 = OpAccessChain %_ptr_Function_uint %v4u %91
-               OpStore %92 %uint_1 None
+         %84 = OpBitcast %uint %83
+         %85 = OpExtInst %uint %73 UMin %84 %uint_3
+         %87 = OpAccessChain %_ptr_Function_float %v4f %85
+               OpStore %87 %float_1 None
+         %88 = OpLoad %int %i None
+         %89 = OpBitcast %uint %88
+         %90 = OpExtInst %uint %73 UMin %89 %uint_1
+         %91 = OpAccessChain %_ptr_Function_int %v2i %90
+               OpStore %91 %int_1 None
          %93 = OpLoad %int %i None
-         %94 = OpAccessChain %_ptr_Function_bool %v2b %93
-               OpStore %94 %true None
+         %94 = OpBitcast %uint %93
+         %95 = OpExtInst %uint %73 UMin %94 %uint_2
+         %96 = OpAccessChain %_ptr_Function_int %v3i %95
+               OpStore %96 %int_1 None
          %97 = OpLoad %int %i None
-         %98 = OpAccessChain %_ptr_Function_bool %v3b %97
-               OpStore %98 %true None
-         %99 = OpLoad %int %i None
-        %100 = OpAccessChain %_ptr_Function_bool %v4b %99
-               OpStore %100 %true None
+         %98 = OpBitcast %uint %97
+         %99 = OpExtInst %uint %73 UMin %98 %uint_3
+        %100 = OpAccessChain %_ptr_Function_int %v4i %99
+               OpStore %100 %int_1 None
+        %101 = OpLoad %int %i None
+        %102 = OpBitcast %uint %101
+        %103 = OpExtInst %uint %73 UMin %102 %uint_1
+        %104 = OpAccessChain %_ptr_Function_uint %v2u %103
+               OpStore %104 %uint_1 None
+        %106 = OpLoad %int %i None
+        %107 = OpBitcast %uint %106
+        %108 = OpExtInst %uint %73 UMin %107 %uint_2
+        %109 = OpAccessChain %_ptr_Function_uint %v3u %108
+               OpStore %109 %uint_1 None
+        %110 = OpLoad %int %i None
+        %111 = OpBitcast %uint %110
+        %112 = OpExtInst %uint %73 UMin %111 %uint_3
+        %113 = OpAccessChain %_ptr_Function_uint %v4u %112
+               OpStore %113 %uint_1 None
+        %114 = OpLoad %int %i None
+        %115 = OpBitcast %uint %114
+        %116 = OpExtInst %uint %73 UMin %115 %uint_1
+        %117 = OpAccessChain %_ptr_Function_bool %v2b %116
+               OpStore %117 %true None
+        %120 = OpLoad %int %i None
+        %121 = OpBitcast %uint %120
+        %122 = OpExtInst %uint %73 UMin %121 %uint_2
+        %123 = OpAccessChain %_ptr_Function_bool %v3b %122
+               OpStore %123 %true None
+        %124 = OpLoad %int %i None
+        %125 = OpBitcast %uint %124
+        %126 = OpExtInst %uint %73 UMin %125 %uint_3
+        %127 = OpAccessChain %_ptr_Function_bool %v4b %126
+               OpStore %127 %true None
                OpBranch %59
          %59 = OpLabel
-        %101 = OpLoad %int %i None
-        %102 = OpIAdd %int %101 %int_1
-               OpStore %i %102 None
+        %128 = OpLoad %int %i None
+        %129 = OpIAdd %int %128 %int_1
+               OpStore %i %129 None
                OpBranch %60
          %61 = OpLabel
                OpReturn
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.dxc.hlsl
index 27051ff..71701d3 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.dxc.hlsl
@@ -26,14 +26,14 @@
   bool2 v2b_2 = bool2(false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3i, i, 1);
-      set_vector_element_2(v4u, i, 1u);
-      set_vector_element_3(v2b, i, true);
-      set_vector_element(v2f_2, i, 1.0f);
-      set_vector_element_1(v3i_2, i, 1);
-      set_vector_element_2(v4u_2, i, 1u);
-      set_vector_element_3(v2b_2, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
+      set_vector_element(v2f_2, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i_2, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u_2, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b_2, min(uint(i), 1u), true);
     }
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.fxc.hlsl
index 27051ff..71701d3 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.fxc.hlsl
@@ -26,14 +26,14 @@
   bool2 v2b_2 = bool2(false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v3i, i, 1);
-      set_vector_element_2(v4u, i, 1u);
-      set_vector_element_3(v2b, i, true);
-      set_vector_element(v2f_2, i, 1.0f);
-      set_vector_element_1(v3i_2, i, 1);
-      set_vector_element_2(v4u_2, i, 1u);
-      set_vector_element_3(v2b_2, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
+      set_vector_element(v2f_2, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v3i_2, min(uint(i), 2u), 1);
+      set_vector_element_2(v4u_2, min(uint(i), 3u), 1u);
+      set_vector_element_3(v2b_2, min(uint(i), 1u), true);
     }
   }
   return;
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.glsl
index 35cd935..1215bd2 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.glsl
@@ -17,14 +17,14 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3i[i] = 1;
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v2f_2[i] = 1.0f;
-      v3i_2[i] = 1;
-      v4u_2[i] = 1u;
-      v2b_2[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3i[min(uint(i), 2u)] = 1;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v2f_2[min(uint(i), 1u)] = 1.0f;
+      v3i_2[min(uint(i), 2u)] = 1;
+      v4u_2[min(uint(i), 3u)] = 1u;
+      v2b_2[min(uint(i), 1u)] = true;
       {
         i = (i + 1);
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.dxc.hlsl
index 3d27cfa..de6c28d 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.dxc.hlsl
@@ -16,14 +16,14 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3i[i] = int(1);
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v2f_2[i] = 1.0f;
-      v3i_2[i] = int(1);
-      v4u_2[i] = 1u;
-      v2b_2[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3i[min(uint(i), 2u)] = int(1);
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v2f_2[min(uint(i), 1u)] = 1.0f;
+      v3i_2[min(uint(i), 2u)] = int(1);
+      v4u_2[min(uint(i), 3u)] = 1u;
+      v2b_2[min(uint(i), 1u)] = true;
       {
         i = (i + int(1));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.msl
index 9c6d617..a36baa2 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.ir.msl
@@ -17,14 +17,14 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v3i[i] = 1;
-      v4u[i] = 1u;
-      v2b[i] = true;
-      v2f_2[i] = 1.0f;
-      v3i_2[i] = 1;
-      v4u_2[i] = 1u;
-      v2b_2[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v3i[min(uint(i), 2u)] = 1;
+      v4u[min(uint(i), 3u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
+      v2f_2[min(uint(i), 1u)] = 1.0f;
+      v3i_2[min(uint(i), 2u)] = 1;
+      v4u_2[min(uint(i), 3u)] = 1u;
+      v2b_2[min(uint(i), 1u)] = true;
       {
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.msl
index 9b58f40..4369b3a 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   float2 v2f = 0.0f;
   float2 v2f_2 = 0.0f;
@@ -11,14 +15,15 @@
   bool2 v2b = false;
   bool2 v2b_2 = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    v2f[i] = 1.0f;
-    v3i[i] = 1;
-    v4u[i] = 1u;
-    v2b[i] = true;
-    v2f_2[i] = 1.0f;
-    v3i_2[i] = 1;
-    v4u_2[i] = 1u;
-    v2b_2[i] = true;
+    TINT_ISOLATE_UB(tint_volatile_false);
+    v2f[min(uint(i), 1u)] = 1.0f;
+    v3i[min(uint(i), 2u)] = 1;
+    v4u[min(uint(i), 3u)] = 1u;
+    v2b[min(uint(i), 1u)] = true;
+    v2f_2[min(uint(i), 1u)] = 1.0f;
+    v3i_2[min(uint(i), 2u)] = 1;
+    v4u_2[min(uint(i), 3u)] = 1u;
+    v2b_2[min(uint(i), 1u)] = true;
   }
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.spvasm
index d821baf..30ec0c6 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_repeated.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 86
 ; Schema: 0
                OpCapability Shader
+         %45 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -38,11 +39,13 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
       %int_2 = OpConstant %int 2
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
       %int_1 = OpConstant %int 1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_uint = OpTypePointer Function %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_bool = OpTypePointer Function %bool
        %true = OpConstantTrue %bool
        %main = OpFunction %void None %3
@@ -72,34 +75,50 @@
                OpBranch %33
          %40 = OpLabel
          %42 = OpLoad %int %i None
-         %43 = OpAccessChain %_ptr_Function_float %v2f %42
-               OpStore %43 %float_1 None
-         %46 = OpLoad %int %i None
-         %47 = OpAccessChain %_ptr_Function_int %v3i %46
-               OpStore %47 %int_1 None
-         %49 = OpLoad %int %i None
-         %50 = OpAccessChain %_ptr_Function_uint %v4u %49
-               OpStore %50 %uint_1 None
-         %53 = OpLoad %int %i None
-         %54 = OpAccessChain %_ptr_Function_bool %v2b %53
-               OpStore %54 %true None
-         %57 = OpLoad %int %i None
-         %58 = OpAccessChain %_ptr_Function_float %v2f_2 %57
-               OpStore %58 %float_1 None
-         %59 = OpLoad %int %i None
-         %60 = OpAccessChain %_ptr_Function_int %v3i_2 %59
-               OpStore %60 %int_1 None
-         %61 = OpLoad %int %i None
-         %62 = OpAccessChain %_ptr_Function_uint %v4u_2 %61
-               OpStore %62 %uint_1 None
-         %63 = OpLoad %int %i None
-         %64 = OpAccessChain %_ptr_Function_bool %v2b_2 %63
-               OpStore %64 %true None
+         %43 = OpBitcast %uint %42
+         %44 = OpExtInst %uint %45 UMin %43 %uint_1
+         %47 = OpAccessChain %_ptr_Function_float %v2f %44
+               OpStore %47 %float_1 None
+         %50 = OpLoad %int %i None
+         %51 = OpBitcast %uint %50
+         %52 = OpExtInst %uint %45 UMin %51 %uint_2
+         %54 = OpAccessChain %_ptr_Function_int %v3i %52
+               OpStore %54 %int_1 None
+         %56 = OpLoad %int %i None
+         %57 = OpBitcast %uint %56
+         %58 = OpExtInst %uint %45 UMin %57 %uint_3
+         %60 = OpAccessChain %_ptr_Function_uint %v4u %58
+               OpStore %60 %uint_1 None
+         %62 = OpLoad %int %i None
+         %63 = OpBitcast %uint %62
+         %64 = OpExtInst %uint %45 UMin %63 %uint_1
+         %65 = OpAccessChain %_ptr_Function_bool %v2b %64
+               OpStore %65 %true None
+         %68 = OpLoad %int %i None
+         %69 = OpBitcast %uint %68
+         %70 = OpExtInst %uint %45 UMin %69 %uint_1
+         %71 = OpAccessChain %_ptr_Function_float %v2f_2 %70
+               OpStore %71 %float_1 None
+         %72 = OpLoad %int %i None
+         %73 = OpBitcast %uint %72
+         %74 = OpExtInst %uint %45 UMin %73 %uint_2
+         %75 = OpAccessChain %_ptr_Function_int %v3i_2 %74
+               OpStore %75 %int_1 None
+         %76 = OpLoad %int %i None
+         %77 = OpBitcast %uint %76
+         %78 = OpExtInst %uint %45 UMin %77 %uint_3
+         %79 = OpAccessChain %_ptr_Function_uint %v4u_2 %78
+               OpStore %79 %uint_1 None
+         %80 = OpLoad %int %i None
+         %81 = OpBitcast %uint %80
+         %82 = OpExtInst %uint %45 UMin %81 %uint_1
+         %83 = OpAccessChain %_ptr_Function_bool %v2b_2 %82
+               OpStore %83 %true None
                OpBranch %31
          %31 = OpLabel
-         %65 = OpLoad %int %i None
-         %66 = OpIAdd %int %65 %int_1
-               OpStore %i %66 None
+         %84 = OpLoad %int %i None
+         %85 = OpIAdd %int %84 %int_1
+               OpStore %i %85 None
                OpBranch %32
          %33 = OpLabel
                OpReturn
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.dxc.hlsl
index 499bc18..0a2eac8 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.dxc.hlsl
@@ -62,20 +62,20 @@
   bool4 v4b = bool4(false, false, false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v2i, i, 1);
-      set_vector_element_2(v2u, i, 1u);
-      set_vector_element_3(v2b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v2i, min(uint(i), 1u), 1);
+      set_vector_element_2(v2u, min(uint(i), 1u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
     }
   }
   int i = 0;
-  set_vector_element_4(v3f, i, 1.0f);
-  set_vector_element_5(v4f, i, 1.0f);
-  set_vector_element_6(v3i, i, 1);
-  set_vector_element_7(v4i, i, 1);
-  set_vector_element_8(v3u, i, 1u);
-  set_vector_element_9(v4u, i, 1u);
-  set_vector_element_10(v3b, i, true);
-  set_vector_element_11(v4b, i, true);
+  set_vector_element_4(v3f, min(uint(i), 2u), 1.0f);
+  set_vector_element_5(v4f, min(uint(i), 3u), 1.0f);
+  set_vector_element_6(v3i, min(uint(i), 2u), 1);
+  set_vector_element_7(v4i, min(uint(i), 3u), 1);
+  set_vector_element_8(v3u, min(uint(i), 2u), 1u);
+  set_vector_element_9(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_10(v3b, min(uint(i), 2u), true);
+  set_vector_element_11(v4b, min(uint(i), 3u), true);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.fxc.hlsl
index 499bc18..0a2eac8 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.fxc.hlsl
@@ -62,20 +62,20 @@
   bool4 v4b = bool4(false, false, false, false);
   {
     for(int i = 0; (i < 2); i = (i + 1)) {
-      set_vector_element(v2f, i, 1.0f);
-      set_vector_element_1(v2i, i, 1);
-      set_vector_element_2(v2u, i, 1u);
-      set_vector_element_3(v2b, i, true);
+      set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+      set_vector_element_1(v2i, min(uint(i), 1u), 1);
+      set_vector_element_2(v2u, min(uint(i), 1u), 1u);
+      set_vector_element_3(v2b, min(uint(i), 1u), true);
     }
   }
   int i = 0;
-  set_vector_element_4(v3f, i, 1.0f);
-  set_vector_element_5(v4f, i, 1.0f);
-  set_vector_element_6(v3i, i, 1);
-  set_vector_element_7(v4i, i, 1);
-  set_vector_element_8(v3u, i, 1u);
-  set_vector_element_9(v4u, i, 1u);
-  set_vector_element_10(v3b, i, true);
-  set_vector_element_11(v4b, i, true);
+  set_vector_element_4(v3f, min(uint(i), 2u), 1.0f);
+  set_vector_element_5(v4f, min(uint(i), 3u), 1.0f);
+  set_vector_element_6(v3i, min(uint(i), 2u), 1);
+  set_vector_element_7(v4i, min(uint(i), 3u), 1);
+  set_vector_element_8(v3u, min(uint(i), 2u), 1u);
+  set_vector_element_9(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_10(v3b, min(uint(i), 2u), true);
+  set_vector_element_11(v4b, min(uint(i), 3u), true);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.glsl
index c24ea24..42d897f 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.glsl
@@ -21,10 +21,10 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v2i[i] = 1;
-      v2u[i] = 1u;
-      v2b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = 1;
+      v2u[min(uint(i), 1u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
       {
         i = (i + 1);
       }
@@ -32,12 +32,12 @@
     }
   }
   int i = 0;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v3b[i] = true;
-  v4b[i] = true;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.dxc.hlsl
index 69fe60a..70fb360 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.dxc.hlsl
@@ -20,10 +20,10 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v2i[i] = int(1);
-      v2u[i] = 1u;
-      v2b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = int(1);
+      v2u[min(uint(i), 1u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
       {
         i = (i + int(1));
       }
@@ -31,13 +31,13 @@
     }
   }
   int i = int(0);
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v3i[i] = int(1);
-  v4i[i] = int(1);
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v3b[i] = true;
-  v4b[i] = true;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = int(1);
+  v4i[min(uint(i), 3u)] = int(1);
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.msl
index dfa8ac1..9f7dc9a 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.ir.msl
@@ -21,10 +21,10 @@
       } else {
         break;
       }
-      v2f[i] = 1.0f;
-      v2i[i] = 1;
-      v2u[i] = 1u;
-      v2b[i] = true;
+      v2f[min(uint(i), 1u)] = 1.0f;
+      v2i[min(uint(i), 1u)] = 1;
+      v2u[min(uint(i), 1u)] = 1u;
+      v2b[min(uint(i), 1u)] = true;
       {
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       }
@@ -32,12 +32,12 @@
     }
   }
   int i = 0;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v3b[i] = true;
-  v4b[i] = true;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.msl
index fa9d188..acf0cb5 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   float2 v2f = 0.0f;
   float3 v3f = 0.0f;
@@ -15,20 +19,21 @@
   bool3 v3b = false;
   bool4 v4b = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    v2f[i] = 1.0f;
-    v2i[i] = 1;
-    v2u[i] = 1u;
-    v2b[i] = true;
+    TINT_ISOLATE_UB(tint_volatile_false);
+    v2f[min(uint(i), 1u)] = 1.0f;
+    v2i[min(uint(i), 1u)] = 1;
+    v2u[min(uint(i), 1u)] = 1u;
+    v2b[min(uint(i), 1u)] = true;
   }
   int i = 0;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v3b[i] = true;
-  v4b[i] = true;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
   return;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.spvasm
index 2ff52b8..12aff07 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/loop_types_some.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 131
 ; Schema: 0
                OpCapability Shader
+         %73 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -67,13 +68,15 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
       %int_2 = OpConstant %int 2
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_bool = OpTypePointer Function %bool
        %true = OpConstantTrue %bool
+     %uint_2 = OpConstant %uint 2
+     %uint_3 = OpConstant %uint 3
        %main = OpFunction %void None %3
           %4 = OpLabel
         %v2f = OpVariable %_ptr_Function_v2float Function %9
@@ -106,48 +109,72 @@
                OpBranch %61
          %68 = OpLabel
          %70 = OpLoad %int %i None
-         %71 = OpAccessChain %_ptr_Function_float %v2f %70
-               OpStore %71 %float_1 None
-         %74 = OpLoad %int %i None
-         %75 = OpAccessChain %_ptr_Function_int %v2i %74
-               OpStore %75 %int_1 None
-         %77 = OpLoad %int %i None
-         %78 = OpAccessChain %_ptr_Function_uint %v2u %77
-               OpStore %78 %uint_1 None
-         %81 = OpLoad %int %i None
-         %82 = OpAccessChain %_ptr_Function_bool %v2b %81
-               OpStore %82 %true None
+         %71 = OpBitcast %uint %70
+         %72 = OpExtInst %uint %73 UMin %71 %uint_1
+         %75 = OpAccessChain %_ptr_Function_float %v2f %72
+               OpStore %75 %float_1 None
+         %78 = OpLoad %int %i None
+         %79 = OpBitcast %uint %78
+         %80 = OpExtInst %uint %73 UMin %79 %uint_1
+         %81 = OpAccessChain %_ptr_Function_int %v2i %80
+               OpStore %81 %int_1 None
+         %83 = OpLoad %int %i None
+         %84 = OpBitcast %uint %83
+         %85 = OpExtInst %uint %73 UMin %84 %uint_1
+         %86 = OpAccessChain %_ptr_Function_uint %v2u %85
+               OpStore %86 %uint_1 None
+         %88 = OpLoad %int %i None
+         %89 = OpBitcast %uint %88
+         %90 = OpExtInst %uint %73 UMin %89 %uint_1
+         %91 = OpAccessChain %_ptr_Function_bool %v2b %90
+               OpStore %91 %true None
                OpBranch %59
          %59 = OpLabel
-         %85 = OpLoad %int %i None
-         %86 = OpIAdd %int %85 %int_1
-               OpStore %i %86 None
+         %94 = OpLoad %int %i None
+         %95 = OpIAdd %int %94 %int_1
+               OpStore %i %95 None
                OpBranch %60
          %61 = OpLabel
                OpStore %i_0 %int_0
-         %88 = OpLoad %int %i_0 None
-         %89 = OpAccessChain %_ptr_Function_float %v3f %88
-               OpStore %89 %float_1 None
-         %90 = OpLoad %int %i_0 None
-         %91 = OpAccessChain %_ptr_Function_float %v4f %90
-               OpStore %91 %float_1 None
-         %92 = OpLoad %int %i_0 None
-         %93 = OpAccessChain %_ptr_Function_int %v3i %92
-               OpStore %93 %int_1 None
-         %94 = OpLoad %int %i_0 None
-         %95 = OpAccessChain %_ptr_Function_int %v4i %94
-               OpStore %95 %int_1 None
-         %96 = OpLoad %int %i_0 None
-         %97 = OpAccessChain %_ptr_Function_uint %v3u %96
-               OpStore %97 %uint_1 None
-         %98 = OpLoad %int %i_0 None
-         %99 = OpAccessChain %_ptr_Function_uint %v4u %98
-               OpStore %99 %uint_1 None
-        %100 = OpLoad %int %i_0 None
-        %101 = OpAccessChain %_ptr_Function_bool %v3b %100
-               OpStore %101 %true None
+         %97 = OpLoad %int %i_0 None
+         %98 = OpBitcast %uint %97
+         %99 = OpExtInst %uint %73 UMin %98 %uint_2
+        %101 = OpAccessChain %_ptr_Function_float %v3f %99
+               OpStore %101 %float_1 None
         %102 = OpLoad %int %i_0 None
-        %103 = OpAccessChain %_ptr_Function_bool %v4b %102
-               OpStore %103 %true None
+        %103 = OpBitcast %uint %102
+        %104 = OpExtInst %uint %73 UMin %103 %uint_3
+        %106 = OpAccessChain %_ptr_Function_float %v4f %104
+               OpStore %106 %float_1 None
+        %107 = OpLoad %int %i_0 None
+        %108 = OpBitcast %uint %107
+        %109 = OpExtInst %uint %73 UMin %108 %uint_2
+        %110 = OpAccessChain %_ptr_Function_int %v3i %109
+               OpStore %110 %int_1 None
+        %111 = OpLoad %int %i_0 None
+        %112 = OpBitcast %uint %111
+        %113 = OpExtInst %uint %73 UMin %112 %uint_3
+        %114 = OpAccessChain %_ptr_Function_int %v4i %113
+               OpStore %114 %int_1 None
+        %115 = OpLoad %int %i_0 None
+        %116 = OpBitcast %uint %115
+        %117 = OpExtInst %uint %73 UMin %116 %uint_2
+        %118 = OpAccessChain %_ptr_Function_uint %v3u %117
+               OpStore %118 %uint_1 None
+        %119 = OpLoad %int %i_0 None
+        %120 = OpBitcast %uint %119
+        %121 = OpExtInst %uint %73 UMin %120 %uint_3
+        %122 = OpAccessChain %_ptr_Function_uint %v4u %121
+               OpStore %122 %uint_1 None
+        %123 = OpLoad %int %i_0 None
+        %124 = OpBitcast %uint %123
+        %125 = OpExtInst %uint %73 UMin %124 %uint_2
+        %126 = OpAccessChain %_ptr_Function_bool %v3b %125
+               OpStore %126 %true None
+        %127 = OpLoad %int %i_0 None
+        %128 = OpBitcast %uint %127
+        %129 = OpExtInst %uint %73 UMin %128 %uint_3
+        %130 = OpAccessChain %_ptr_Function_bool %v4b %129
+               OpStore %130 %true None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.dxc.hlsl
index 7e32f5c..1649ed3 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.dxc.hlsl
@@ -61,17 +61,17 @@
   bool3 v3b = bool3(false, false, false);
   bool4 v4b = bool4(false, false, false, false);
   int i = 0;
-  set_vector_element(v2f, i, 1.0f);
-  set_vector_element_1(v3f, i, 1.0f);
-  set_vector_element_2(v4f, i, 1.0f);
-  set_vector_element_3(v2i, i, 1);
-  set_vector_element_4(v3i, i, 1);
-  set_vector_element_5(v4i, i, 1);
-  set_vector_element_6(v2u, i, 1u);
-  set_vector_element_7(v3u, i, 1u);
-  set_vector_element_8(v4u, i, 1u);
-  set_vector_element_9(v2b, i, true);
-  set_vector_element_10(v3b, i, true);
-  set_vector_element_11(v4b, i, true);
+  set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+  set_vector_element_1(v3f, min(uint(i), 2u), 1.0f);
+  set_vector_element_2(v4f, min(uint(i), 3u), 1.0f);
+  set_vector_element_3(v2i, min(uint(i), 1u), 1);
+  set_vector_element_4(v3i, min(uint(i), 2u), 1);
+  set_vector_element_5(v4i, min(uint(i), 3u), 1);
+  set_vector_element_6(v2u, min(uint(i), 1u), 1u);
+  set_vector_element_7(v3u, min(uint(i), 2u), 1u);
+  set_vector_element_8(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_9(v2b, min(uint(i), 1u), true);
+  set_vector_element_10(v3b, min(uint(i), 2u), true);
+  set_vector_element_11(v4b, min(uint(i), 3u), true);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.fxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.fxc.hlsl
index 7e32f5c..1649ed3 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.fxc.hlsl
@@ -61,17 +61,17 @@
   bool3 v3b = bool3(false, false, false);
   bool4 v4b = bool4(false, false, false, false);
   int i = 0;
-  set_vector_element(v2f, i, 1.0f);
-  set_vector_element_1(v3f, i, 1.0f);
-  set_vector_element_2(v4f, i, 1.0f);
-  set_vector_element_3(v2i, i, 1);
-  set_vector_element_4(v3i, i, 1);
-  set_vector_element_5(v4i, i, 1);
-  set_vector_element_6(v2u, i, 1u);
-  set_vector_element_7(v3u, i, 1u);
-  set_vector_element_8(v4u, i, 1u);
-  set_vector_element_9(v2b, i, true);
-  set_vector_element_10(v3b, i, true);
-  set_vector_element_11(v4b, i, true);
+  set_vector_element(v2f, min(uint(i), 1u), 1.0f);
+  set_vector_element_1(v3f, min(uint(i), 2u), 1.0f);
+  set_vector_element_2(v4f, min(uint(i), 3u), 1.0f);
+  set_vector_element_3(v2i, min(uint(i), 1u), 1);
+  set_vector_element_4(v3i, min(uint(i), 2u), 1);
+  set_vector_element_5(v4i, min(uint(i), 3u), 1);
+  set_vector_element_6(v2u, min(uint(i), 1u), 1u);
+  set_vector_element_7(v3u, min(uint(i), 2u), 1u);
+  set_vector_element_8(v4u, min(uint(i), 3u), 1u);
+  set_vector_element_9(v2b, min(uint(i), 1u), true);
+  set_vector_element_10(v3b, min(uint(i), 2u), true);
+  set_vector_element_11(v4b, min(uint(i), 3u), true);
   return;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.glsl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.glsl
index 7b6e49a..95693b2 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.glsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.glsl
@@ -15,16 +15,16 @@
   bvec3 v3b = bvec3(false);
   bvec4 v4b = bvec4(false);
   int i = 0;
-  v2f[i] = 1.0f;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v2i[i] = 1;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v2u[i] = 1u;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v2b[i] = true;
-  v3b[i] = true;
-  v4b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v2i[min(uint(i), 1u)] = 1;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v2u[min(uint(i), 1u)] = 1u;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.dxc.hlsl
index 7d6c6e4..a5cf6e1 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.dxc.hlsl
@@ -14,17 +14,17 @@
   bool3 v3b = (false).xxx;
   bool4 v4b = (false).xxxx;
   int i = int(0);
-  v2f[i] = 1.0f;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v2i[i] = int(1);
-  v3i[i] = int(1);
-  v4i[i] = int(1);
-  v2u[i] = 1u;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v2b[i] = true;
-  v3b[i] = true;
-  v4b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v2i[min(uint(i), 1u)] = int(1);
+  v3i[min(uint(i), 2u)] = int(1);
+  v4i[min(uint(i), 3u)] = int(1);
+  v2u[min(uint(i), 1u)] = 1u;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.msl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.msl
index 03abd5c..989a7dc 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.ir.msl
@@ -15,16 +15,16 @@
   bool3 v3b = false;
   bool4 v4b = false;
   int i = 0;
-  v2f[i] = 1.0f;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v2i[i] = 1;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v2u[i] = 1u;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v2b[i] = true;
-  v3b[i] = true;
-  v4b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v2i[min(uint(i), 1u)] = 1;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v2u[min(uint(i), 1u)] = 1u;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
 }
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.msl b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.msl
index cb0748e..d1663a2 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.msl
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.msl
@@ -15,18 +15,18 @@
   bool3 v3b = false;
   bool4 v4b = false;
   int i = 0;
-  v2f[i] = 1.0f;
-  v3f[i] = 1.0f;
-  v4f[i] = 1.0f;
-  v2i[i] = 1;
-  v3i[i] = 1;
-  v4i[i] = 1;
-  v2u[i] = 1u;
-  v3u[i] = 1u;
-  v4u[i] = 1u;
-  v2b[i] = true;
-  v3b[i] = true;
-  v4b[i] = true;
+  v2f[min(uint(i), 1u)] = 1.0f;
+  v3f[min(uint(i), 2u)] = 1.0f;
+  v4f[min(uint(i), 3u)] = 1.0f;
+  v2i[min(uint(i), 1u)] = 1;
+  v3i[min(uint(i), 2u)] = 1;
+  v4i[min(uint(i), 3u)] = 1;
+  v2u[min(uint(i), 1u)] = 1u;
+  v3u[min(uint(i), 2u)] = 1u;
+  v4u[min(uint(i), 3u)] = 1u;
+  v2b[min(uint(i), 1u)] = true;
+  v3b[min(uint(i), 2u)] = true;
+  v4b[min(uint(i), 3u)] = true;
   return;
 }
 
diff --git a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.spvasm b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.spvasm
index cac9a3b..cdb708d 100644
--- a/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.spvasm
+++ b/test/tint/bug/fxc/vector_assignment_in_loop/no_loop.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 91
+; Bound: 118
 ; Schema: 0
                OpCapability Shader
+         %63 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -65,11 +66,13 @@
          %56 = OpConstantNull %v4bool
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
+     %uint_3 = OpConstant %uint 3
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_bool = OpTypePointer Function %bool
        %true = OpConstantTrue %bool
        %main = OpFunction %void None %3
@@ -89,40 +92,64 @@
           %i = OpVariable %_ptr_Function_int Function
                OpStore %i %int_0
          %60 = OpLoad %int %i None
-         %61 = OpAccessChain %_ptr_Function_float %v2f %60
-               OpStore %61 %float_1 None
-         %64 = OpLoad %int %i None
-         %65 = OpAccessChain %_ptr_Function_float %v3f %64
+         %61 = OpBitcast %uint %60
+         %62 = OpExtInst %uint %63 UMin %61 %uint_1
+         %65 = OpAccessChain %_ptr_Function_float %v2f %62
                OpStore %65 %float_1 None
-         %66 = OpLoad %int %i None
-         %67 = OpAccessChain %_ptr_Function_float %v4f %66
-               OpStore %67 %float_1 None
          %68 = OpLoad %int %i None
-         %69 = OpAccessChain %_ptr_Function_int %v2i %68
-               OpStore %69 %int_1 None
-         %71 = OpLoad %int %i None
-         %72 = OpAccessChain %_ptr_Function_int %v3i %71
-               OpStore %72 %int_1 None
+         %69 = OpBitcast %uint %68
+         %70 = OpExtInst %uint %63 UMin %69 %uint_2
+         %72 = OpAccessChain %_ptr_Function_float %v3f %70
+               OpStore %72 %float_1 None
          %73 = OpLoad %int %i None
-         %74 = OpAccessChain %_ptr_Function_int %v4i %73
-               OpStore %74 %int_1 None
-         %75 = OpLoad %int %i None
-         %76 = OpAccessChain %_ptr_Function_uint %v2u %75
-               OpStore %76 %uint_1 None
-         %79 = OpLoad %int %i None
-         %80 = OpAccessChain %_ptr_Function_uint %v3u %79
-               OpStore %80 %uint_1 None
-         %81 = OpLoad %int %i None
-         %82 = OpAccessChain %_ptr_Function_uint %v4u %81
-               OpStore %82 %uint_1 None
+         %74 = OpBitcast %uint %73
+         %75 = OpExtInst %uint %63 UMin %74 %uint_3
+         %77 = OpAccessChain %_ptr_Function_float %v4f %75
+               OpStore %77 %float_1 None
+         %78 = OpLoad %int %i None
+         %79 = OpBitcast %uint %78
+         %80 = OpExtInst %uint %63 UMin %79 %uint_1
+         %81 = OpAccessChain %_ptr_Function_int %v2i %80
+               OpStore %81 %int_1 None
          %83 = OpLoad %int %i None
-         %84 = OpAccessChain %_ptr_Function_bool %v2b %83
-               OpStore %84 %true None
+         %84 = OpBitcast %uint %83
+         %85 = OpExtInst %uint %63 UMin %84 %uint_2
+         %86 = OpAccessChain %_ptr_Function_int %v3i %85
+               OpStore %86 %int_1 None
          %87 = OpLoad %int %i None
-         %88 = OpAccessChain %_ptr_Function_bool %v3b %87
-               OpStore %88 %true None
-         %89 = OpLoad %int %i None
-         %90 = OpAccessChain %_ptr_Function_bool %v4b %89
-               OpStore %90 %true None
+         %88 = OpBitcast %uint %87
+         %89 = OpExtInst %uint %63 UMin %88 %uint_3
+         %90 = OpAccessChain %_ptr_Function_int %v4i %89
+               OpStore %90 %int_1 None
+         %91 = OpLoad %int %i None
+         %92 = OpBitcast %uint %91
+         %93 = OpExtInst %uint %63 UMin %92 %uint_1
+         %94 = OpAccessChain %_ptr_Function_uint %v2u %93
+               OpStore %94 %uint_1 None
+         %96 = OpLoad %int %i None
+         %97 = OpBitcast %uint %96
+         %98 = OpExtInst %uint %63 UMin %97 %uint_2
+         %99 = OpAccessChain %_ptr_Function_uint %v3u %98
+               OpStore %99 %uint_1 None
+        %100 = OpLoad %int %i None
+        %101 = OpBitcast %uint %100
+        %102 = OpExtInst %uint %63 UMin %101 %uint_3
+        %103 = OpAccessChain %_ptr_Function_uint %v4u %102
+               OpStore %103 %uint_1 None
+        %104 = OpLoad %int %i None
+        %105 = OpBitcast %uint %104
+        %106 = OpExtInst %uint %63 UMin %105 %uint_1
+        %107 = OpAccessChain %_ptr_Function_bool %v2b %106
+               OpStore %107 %true None
+        %110 = OpLoad %int %i None
+        %111 = OpBitcast %uint %110
+        %112 = OpExtInst %uint %63 UMin %111 %uint_2
+        %113 = OpAccessChain %_ptr_Function_bool %v3b %112
+               OpStore %113 %true None
+        %114 = OpLoad %int %i None
+        %115 = OpBitcast %uint %114
+        %116 = OpExtInst %uint %63 UMin %115 %uint_3
+        %117 = OpAccessChain %_ptr_Function_bool %v4b %116
+               OpStore %117 %true None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1064.wgsl.expected.ir.msl b/test/tint/bug/tint/1064.wgsl.expected.ir.msl
index cb79529..d7f982f 100644
--- a/test/tint/bug/tint/1064.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1064.wgsl.expected.ir.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 fragment void tint_symbol() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/bug/tint/1064.wgsl.expected.msl b/test/tint/bug/tint/1064.wgsl.expected.msl
index 4b572f1..b0bf1a3 100644
--- a/test/tint/bug/tint/1064.wgsl.expected.msl
+++ b/test/tint/bug/tint/1064.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 fragment void tint_symbol() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if (false) {
     } else {
       break;
diff --git a/test/tint/bug/tint/1081.wgsl.expected.ir.msl b/test/tint/bug/tint/1081.wgsl.expected.ir.msl
index 8522a0e..f562caa 100644
--- a/test/tint/bug/tint/1081.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1081.wgsl.expected.ir.msl
@@ -5,6 +5,9 @@
   thread bool* continue_execution;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_outputs {
   int tint_symbol_1 [[color(2)]];
 };
@@ -24,6 +27,7 @@
   int y = x[0u];
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       int const r = f(y, tint_module_vars);
       if ((r == 0)) {
         break;
diff --git a/test/tint/bug/tint/1081.wgsl.expected.msl b/test/tint/bug/tint/1081.wgsl.expected.msl
index 9eb8e5f..d955e00 100644
--- a/test/tint/bug/tint/1081.wgsl.expected.msl
+++ b/test/tint/bug/tint/1081.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   bool tint_discarded;
 };
@@ -23,6 +27,7 @@
 int tint_symbol_inner(int3 x, thread tint_private_vars_struct* const tint_private_vars) {
   int y = x[0];
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     int const r = f(y, tint_private_vars);
     if ((r == 0)) {
       break;
diff --git a/test/tint/bug/tint/1088.spvasm.expected.glsl b/test/tint/bug/tint/1088.spvasm.expected.glsl
index 3f4f3c5..3ffcaaa 100644
--- a/test/tint/bug/tint/1088.spvasm.expected.glsl
+++ b/test/tint/bug/tint/1088.spvasm.expected.glsl
@@ -41,7 +41,7 @@
   vec3 p = vec3(0.0f);
   q = vec4(position_1.x, position_1.y, position_1.z, 1.0f);
   p = q.xyz;
-  p[0u] = (p.x + sin(((v.inner.test[0].el * position_1.y) + v.inner.time)));
+  p[0u] = (p.x + sin(((v.inner.test[0u].el * position_1.y) + v.inner.time)));
   p[1u] = (p.y + sin((v.inner.time + 4.0f)));
   mat4 v_1 = v.inner.worldViewProjection;
   tint_symbol = (v_1 * vec4(p.x, p.y, p.z, 1.0f));
diff --git a/test/tint/bug/tint/1088.spvasm.expected.ir.msl b/test/tint/bug/tint/1088.spvasm.expected.ir.msl
index 6cfa262..669fce9 100644
--- a/test/tint/bug/tint/1088.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/1088.spvasm.expected.ir.msl
@@ -56,7 +56,7 @@
   float3 p = 0.0f;
   q = float4((*tint_module_vars.position_1)[0u], (*tint_module_vars.position_1)[1u], (*tint_module_vars.position_1)[2u], 1.0f);
   p = q.xyz;
-  p[0u] = (p[0u] + sin((((*tint_module_vars.x_14).test[0].el * (*tint_module_vars.position_1)[1u]) + (*tint_module_vars.x_14).time)));
+  p[0u] = (p[0u] + sin((((*tint_module_vars.x_14).test[0u].el * (*tint_module_vars.position_1)[1u]) + (*tint_module_vars.x_14).time)));
   p[1u] = (p[1u] + sin(((*tint_module_vars.x_14).time + 4.0f)));
   float4x4 const v = (*tint_module_vars.x_14).worldViewProjection;
   (*tint_module_vars.gl_Position) = (v * float4(p[0u], p[1u], p[2u], 1.0f));
diff --git a/test/tint/bug/tint/1088.spvasm.expected.spvasm b/test/tint/bug/tint/1088.spvasm.expected.spvasm
index dd2363c..55910aa 100644
--- a/test/tint/bug/tint/1088.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/1088.spvasm.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 123
+; Bound: 121
 ; Schema: 0
                OpCapability Shader
-         %75 = OpExtInstImport "GLSL.std.450"
+         %73 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %main "main" %main_loc0_Input %main_loc2_Input %main_loc1_Input %main_position_Output %main_loc0_Output %main___point_size_Output
                OpName %position_1 "position_1"
@@ -110,13 +110,11 @@
 %_ptr_Function_float = OpTypePointer Function %float
 %_ptr_Uniform_float = OpTypePointer Uniform %float
      %uint_3 = OpConstant %uint 3
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
     %float_4 = OpConstant %float 4
 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
    %float_n1 = OpConstant %float -1
    %main_out = OpTypeStruct %v4float %v2float
-        %109 = OpTypeFunction %main_out %v3float %v2float %v3float
+        %107 = OpTypeFunction %main_out %v3float %v2float %v3float
      %main_1 = OpFunction %void None %40
          %41 = OpLabel
           %q = OpVariable %_ptr_Function_v4float Function %26
@@ -134,71 +132,71 @@
                OpStore %p %58 None
          %59 = OpAccessChain %_ptr_Function_float %p %uint_0
          %61 = OpLoad %float %59 None
-         %62 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_3 %int_0 %uint_0
-         %67 = OpLoad %float %62 None
-         %68 = OpAccessChain %_ptr_Private_float %position_1 %uint_1
-         %69 = OpLoad %float %68 None
-         %70 = OpFMul %float %67 %69
-         %71 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_1
-         %72 = OpLoad %float %71 None
-         %73 = OpFAdd %float %70 %72
-         %74 = OpExtInst %float %75 Sin %73
-         %76 = OpFAdd %float %61 %74
-         %77 = OpAccessChain %_ptr_Function_float %p %uint_0
-               OpStore %77 %76 None
-         %78 = OpAccessChain %_ptr_Function_float %p %uint_1
+         %62 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_3 %uint_0 %uint_0
+         %65 = OpLoad %float %62 None
+         %66 = OpAccessChain %_ptr_Private_float %position_1 %uint_1
+         %67 = OpLoad %float %66 None
+         %68 = OpFMul %float %65 %67
+         %69 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_1
+         %70 = OpLoad %float %69 None
+         %71 = OpFAdd %float %68 %70
+         %72 = OpExtInst %float %73 Sin %71
+         %74 = OpFAdd %float %61 %72
+         %75 = OpAccessChain %_ptr_Function_float %p %uint_0
+               OpStore %75 %74 None
+         %76 = OpAccessChain %_ptr_Function_float %p %uint_1
+         %77 = OpLoad %float %76 None
+         %78 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_1
          %79 = OpLoad %float %78 None
-         %80 = OpAccessChain %_ptr_Uniform_float %6 %uint_0 %uint_1
-         %81 = OpLoad %float %80 None
-         %82 = OpFAdd %float %81 %float_4
-         %84 = OpExtInst %float %75 Sin %82
-         %85 = OpFAdd %float %79 %84
-         %86 = OpAccessChain %_ptr_Function_float %p %uint_1
-               OpStore %86 %85 None
-         %87 = OpAccessChain %_ptr_Uniform_mat4v4float %6 %uint_0 %uint_0
-         %89 = OpLoad %mat4v4float %87 None
-         %90 = OpAccessChain %_ptr_Function_float %p %uint_0
+         %80 = OpFAdd %float %79 %float_4
+         %82 = OpExtInst %float %73 Sin %80
+         %83 = OpFAdd %float %77 %82
+         %84 = OpAccessChain %_ptr_Function_float %p %uint_1
+               OpStore %84 %83 None
+         %85 = OpAccessChain %_ptr_Uniform_mat4v4float %6 %uint_0 %uint_0
+         %87 = OpLoad %mat4v4float %85 None
+         %88 = OpAccessChain %_ptr_Function_float %p %uint_0
+         %89 = OpLoad %float %88 None
+         %90 = OpAccessChain %_ptr_Function_float %p %uint_1
          %91 = OpLoad %float %90 None
-         %92 = OpAccessChain %_ptr_Function_float %p %uint_1
+         %92 = OpAccessChain %_ptr_Function_float %p %uint_2
          %93 = OpLoad %float %92 None
-         %94 = OpAccessChain %_ptr_Function_float %p %uint_2
-         %95 = OpLoad %float %94 None
-         %96 = OpCompositeConstruct %v4float %91 %93 %95 %float_1
-         %97 = OpMatrixTimesVector %v4float %89 %96
-               OpStore %gl_Position %97 None
-         %98 = OpLoad %v2float %uv None
-               OpStore %vUV %98 None
-         %99 = OpAccessChain %_ptr_Private_float %gl_Position %uint_1
-        %100 = OpLoad %float %99 None
-        %101 = OpFMul %float %100 %float_n1
-        %103 = OpAccessChain %_ptr_Private_float %gl_Position %uint_1
-               OpStore %103 %101 None
+         %94 = OpCompositeConstruct %v4float %89 %91 %93 %float_1
+         %95 = OpMatrixTimesVector %v4float %87 %94
+               OpStore %gl_Position %95 None
+         %96 = OpLoad %v2float %uv None
+               OpStore %vUV %96 None
+         %97 = OpAccessChain %_ptr_Private_float %gl_Position %uint_1
+         %98 = OpLoad %float %97 None
+         %99 = OpFMul %float %98 %float_n1
+        %101 = OpAccessChain %_ptr_Private_float %gl_Position %uint_1
+               OpStore %101 %99 None
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %main_out None %109
+ %main_inner = OpFunction %main_out None %107
 %position_1_param = OpFunctionParameter %v3float
    %uv_param = OpFunctionParameter %v2float
 %normal_param = OpFunctionParameter %v3float
-        %110 = OpLabel
+        %108 = OpLabel
                OpStore %position_1 %position_1_param None
                OpStore %uv %uv_param None
                OpStore %normal %normal_param None
-        %111 = OpFunctionCall %void %main_1
-        %112 = OpLoad %v4float %gl_Position None
-        %113 = OpLoad %v2float %vUV None
-        %114 = OpCompositeConstruct %main_out %112 %113
-               OpReturnValue %114
+        %109 = OpFunctionCall %void %main_1
+        %110 = OpLoad %v4float %gl_Position None
+        %111 = OpLoad %v2float %vUV None
+        %112 = OpCompositeConstruct %main_out %110 %111
+               OpReturnValue %112
                OpFunctionEnd
        %main = OpFunction %void None %40
-        %116 = OpLabel
-        %117 = OpLoad %v3float %main_loc0_Input None
-        %118 = OpLoad %v2float %main_loc2_Input None
-        %119 = OpLoad %v3float %main_loc1_Input None
-        %120 = OpFunctionCall %main_out %main_inner %117 %118 %119
-        %121 = OpCompositeExtract %v4float %120 0
-               OpStore %main_position_Output %121 None
-        %122 = OpCompositeExtract %v2float %120 1
-               OpStore %main_loc0_Output %122 None
+        %114 = OpLabel
+        %115 = OpLoad %v3float %main_loc0_Input None
+        %116 = OpLoad %v2float %main_loc2_Input None
+        %117 = OpLoad %v3float %main_loc1_Input None
+        %118 = OpFunctionCall %main_out %main_inner %115 %116 %117
+        %119 = OpCompositeExtract %v4float %118 0
+               OpStore %main_position_Output %119 None
+        %120 = OpCompositeExtract %v2float %118 1
+               OpStore %main_loc0_Output %120 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl
index 4c0b1de..cf14016 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.dxc.hlsl
@@ -44,7 +44,10 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((4u * ((3u * vertexIndex) + 0u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 1u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 2u)))));
+  uint tint_symbol_8 = 0u;
+  positions.GetDimensions(tint_symbol_8);
+  uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 4u);
+  float3 position = float3(asfloat(positions.Load((4u * min(((3u * vertexIndex) + 0u), (tint_symbol_9 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 1u), (tint_symbol_9 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 2u), (tint_symbol_9 - 1u))))));
   return position;
 }
 
@@ -63,12 +66,24 @@
 
 
 void doIgnore() {
+  uint tint_symbol_11 = 0u;
+  counters.GetDimensions(tint_symbol_11);
+  uint tint_symbol_12 = ((tint_symbol_11 - 0u) / 4u);
+  uint tint_symbol_14 = 0u;
+  indices.GetDimensions(tint_symbol_14);
+  uint tint_symbol_15 = ((tint_symbol_14 - 0u) / 4u);
+  uint tint_symbol_16 = 0u;
+  positions.GetDimensions(tint_symbol_16);
+  uint tint_symbol_17 = ((tint_symbol_16 - 0u) / 4u);
+  uint tint_symbol_19 = 0u;
+  LUT.GetDimensions(tint_symbol_19);
+  uint tint_symbol_20 = ((tint_symbol_19 - 0u) / 4u);
   uint g42 = uniforms[0].x;
   uint kj6 = dbg.Load(20u);
-  uint b53 = countersatomicLoad(0u);
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int g55 = LUTatomicLoad(0u);
+  uint b53 = countersatomicLoad((4u * min(0u, (tint_symbol_12 - 1u))));
+  uint rwg = indices.Load((4u * min(0u, (tint_symbol_15 - 1u))));
+  float rb5 = asfloat(positions.Load((4u * min(0u, (tint_symbol_17 - 1u)))));
+  int g55 = LUTatomicLoad((4u * min(0u, (tint_symbol_20 - 1u))));
 }
 
 struct tint_symbol_2 {
@@ -83,21 +98,27 @@
 
 
 void main_count_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_21 = 0u;
+  indices.GetDimensions(tint_symbol_21);
+  uint tint_symbol_22 = ((tint_symbol_21 - 0u) / 4u);
+  uint tint_symbol_23 = 0u;
+  counters.GetDimensions(tint_symbol_23);
+  uint tint_symbol_24 = ((tint_symbol_23 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * triangleIndex) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * triangleIndex) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_22 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * triangleIndex) + 1u), (tint_symbol_22 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * triangleIndex) + 2u), (tint_symbol_22 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0].y, voxelPos);
-  uint acefg = countersatomicAdd((4u * voxelIndex), 1u);
+  uint acefg = countersatomicAdd((4u * min(voxelIndex, (tint_symbol_24 - 1u))), 1u);
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, asuint(uniforms[0].y));
     dbg.Store(32u, asuint(center.x));
@@ -130,19 +151,25 @@
 
 
 void main_create_lut_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_25 = 0u;
+  counters.GetDimensions(tint_symbol_25);
+  uint tint_symbol_26 = ((tint_symbol_25 - 0u) / 4u);
+  uint tint_symbol_27 = 0u;
+  LUT.GetDimensions(tint_symbol_27);
+  uint tint_symbol_28 = ((tint_symbol_27 - 0u) / 4u);
   uint voxelIndex = GlobalInvocationID.x;
   doIgnore();
   uint maxVoxels = ((uniforms[0].y * uniforms[0].y) * uniforms[0].y);
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint numTriangles = countersatomicLoad((4u * voxelIndex));
+  uint numTriangles = countersatomicLoad((4u * min(voxelIndex, (tint_symbol_26 - 1u))));
   int offset = -1;
   if ((numTriangles > 0u)) {
     uint tint_symbol = dbgatomicAdd(0u, numTriangles);
     offset = int(tint_symbol);
   }
-  LUTatomicStore((4u * voxelIndex), offset);
+  LUTatomicStore((4u * min(voxelIndex, (tint_symbol_28 - 1u))), offset);
 }
 
 [numthreads(128, 1, 1)]
@@ -163,21 +190,27 @@
 
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_29 = 0u;
+  indices.GetDimensions(tint_symbol_29);
+  uint tint_symbol_30 = ((tint_symbol_29 - 0u) / 4u);
+  uint tint_symbol_31 = 0u;
+  LUT.GetDimensions(tint_symbol_31);
+  uint tint_symbol_32 = ((tint_symbol_31 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   doIgnore();
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * triangleIndex) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * triangleIndex) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_30 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * triangleIndex) + 1u), (tint_symbol_30 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * triangleIndex) + 2u), (tint_symbol_30 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0].y, voxelPos);
-  int triangleOffset = LUTatomicAdd((4u * voxelIndex), 1);
+  int triangleOffset = LUTatomicAdd((4u * min(voxelIndex, (tint_symbol_32 - 1u))), 1);
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl
index 4c0b1de..cf14016 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.fxc.hlsl
@@ -44,7 +44,10 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((4u * ((3u * vertexIndex) + 0u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 1u)))), asfloat(positions.Load((4u * ((3u * vertexIndex) + 2u)))));
+  uint tint_symbol_8 = 0u;
+  positions.GetDimensions(tint_symbol_8);
+  uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 4u);
+  float3 position = float3(asfloat(positions.Load((4u * min(((3u * vertexIndex) + 0u), (tint_symbol_9 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 1u), (tint_symbol_9 - 1u))))), asfloat(positions.Load((4u * min(((3u * vertexIndex) + 2u), (tint_symbol_9 - 1u))))));
   return position;
 }
 
@@ -63,12 +66,24 @@
 
 
 void doIgnore() {
+  uint tint_symbol_11 = 0u;
+  counters.GetDimensions(tint_symbol_11);
+  uint tint_symbol_12 = ((tint_symbol_11 - 0u) / 4u);
+  uint tint_symbol_14 = 0u;
+  indices.GetDimensions(tint_symbol_14);
+  uint tint_symbol_15 = ((tint_symbol_14 - 0u) / 4u);
+  uint tint_symbol_16 = 0u;
+  positions.GetDimensions(tint_symbol_16);
+  uint tint_symbol_17 = ((tint_symbol_16 - 0u) / 4u);
+  uint tint_symbol_19 = 0u;
+  LUT.GetDimensions(tint_symbol_19);
+  uint tint_symbol_20 = ((tint_symbol_19 - 0u) / 4u);
   uint g42 = uniforms[0].x;
   uint kj6 = dbg.Load(20u);
-  uint b53 = countersatomicLoad(0u);
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int g55 = LUTatomicLoad(0u);
+  uint b53 = countersatomicLoad((4u * min(0u, (tint_symbol_12 - 1u))));
+  uint rwg = indices.Load((4u * min(0u, (tint_symbol_15 - 1u))));
+  float rb5 = asfloat(positions.Load((4u * min(0u, (tint_symbol_17 - 1u)))));
+  int g55 = LUTatomicLoad((4u * min(0u, (tint_symbol_20 - 1u))));
 }
 
 struct tint_symbol_2 {
@@ -83,21 +98,27 @@
 
 
 void main_count_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_21 = 0u;
+  indices.GetDimensions(tint_symbol_21);
+  uint tint_symbol_22 = ((tint_symbol_21 - 0u) / 4u);
+  uint tint_symbol_23 = 0u;
+  counters.GetDimensions(tint_symbol_23);
+  uint tint_symbol_24 = ((tint_symbol_23 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * triangleIndex) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * triangleIndex) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_22 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * triangleIndex) + 1u), (tint_symbol_22 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * triangleIndex) + 2u), (tint_symbol_22 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0].y, voxelPos);
-  uint acefg = countersatomicAdd((4u * voxelIndex), 1u);
+  uint acefg = countersatomicAdd((4u * min(voxelIndex, (tint_symbol_24 - 1u))), 1u);
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, asuint(uniforms[0].y));
     dbg.Store(32u, asuint(center.x));
@@ -130,19 +151,25 @@
 
 
 void main_create_lut_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_25 = 0u;
+  counters.GetDimensions(tint_symbol_25);
+  uint tint_symbol_26 = ((tint_symbol_25 - 0u) / 4u);
+  uint tint_symbol_27 = 0u;
+  LUT.GetDimensions(tint_symbol_27);
+  uint tint_symbol_28 = ((tint_symbol_27 - 0u) / 4u);
   uint voxelIndex = GlobalInvocationID.x;
   doIgnore();
   uint maxVoxels = ((uniforms[0].y * uniforms[0].y) * uniforms[0].y);
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint numTriangles = countersatomicLoad((4u * voxelIndex));
+  uint numTriangles = countersatomicLoad((4u * min(voxelIndex, (tint_symbol_26 - 1u))));
   int offset = -1;
   if ((numTriangles > 0u)) {
     uint tint_symbol = dbgatomicAdd(0u, numTriangles);
     offset = int(tint_symbol);
   }
-  LUTatomicStore((4u * voxelIndex), offset);
+  LUTatomicStore((4u * min(voxelIndex, (tint_symbol_28 - 1u))), offset);
 }
 
 [numthreads(128, 1, 1)]
@@ -163,21 +190,27 @@
 
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_29 = 0u;
+  indices.GetDimensions(tint_symbol_29);
+  uint tint_symbol_30 = ((tint_symbol_29 - 0u) / 4u);
+  uint tint_symbol_31 = 0u;
+  LUT.GetDimensions(tint_symbol_31);
+  uint tint_symbol_32 = ((tint_symbol_31 - 0u) / 4u);
   uint triangleIndex = GlobalInvocationID.x;
   doIgnore();
   if ((triangleIndex >= uniforms[0].x)) {
     return;
   }
-  uint i0 = indices.Load((4u * ((3u * triangleIndex) + 0u)));
-  uint i1 = indices.Load((4u * ((3u * triangleIndex) + 1u)));
-  uint i2 = indices.Load((4u * ((3u * triangleIndex) + 2u)));
+  uint i0 = indices.Load((4u * min(((3u * triangleIndex) + 0u), (tint_symbol_30 - 1u))));
+  uint i1 = indices.Load((4u * min(((3u * triangleIndex) + 1u), (tint_symbol_30 - 1u))));
+  uint i2 = indices.Load((4u * min(((3u * triangleIndex) + 2u), (tint_symbol_30 - 1u))));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0].y, voxelPos);
-  int triangleOffset = LUTatomicAdd((4u * voxelIndex), 1);
+  int triangleOffset = LUTatomicAdd((4u * min(voxelIndex, (tint_symbol_32 - 1u))), 1);
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1113.wgsl.expected.glsl b/test/tint/bug/tint/1113.wgsl.expected.glsl
index c57d440..7a93aea 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.glsl
@@ -70,16 +70,29 @@
   return ((icoord.x + (gridSize * icoord.y)) + ((gridSize * gridSize) * icoord.z));
 }
 vec3 loadPosition(uint vertexIndex) {
-  vec3 position = vec3(positions.values[((3u * vertexIndex) + 0u)], positions.values[((3u * vertexIndex) + 1u)], positions.values[((3u * vertexIndex) + 2u)]);
+  uint v_2 = min(((3u * vertexIndex) + 0u), (uint(positions.values.length()) - 1u));
+  float v_3 = positions.values[v_2];
+  uint v_4 = min(((3u * vertexIndex) + 1u), (uint(positions.values.length()) - 1u));
+  float v_5 = positions.values[v_4];
+  uint v_6 = min(((3u * vertexIndex) + 2u), (uint(positions.values.length()) - 1u));
+  vec3 position = vec3(v_3, v_5, positions.values[v_6]);
   return position;
 }
 void doIgnore() {
   uint g42 = v.inner.numTriangles;
   uint kj6 = v_1.inner.value1;
-  uint b53 = atomicOr(counters.values[0], 0u);
-  uint rwg = indices.values[0];
-  float rb5 = positions.values[0];
-  int g55 = atomicOr(LUT.values[0], 0);
+  uint v_7 = (uint(counters.values.length()) - 1u);
+  uint v_8 = min(uint(0), v_7);
+  uint b53 = atomicOr(counters.values[v_8], 0u);
+  uint v_9 = (uint(indices.values.length()) - 1u);
+  uint v_10 = min(uint(0), v_9);
+  uint rwg = indices.values[v_10];
+  uint v_11 = (uint(positions.values.length()) - 1u);
+  uint v_12 = min(uint(0), v_11);
+  float rb5 = positions.values[v_12];
+  uint v_13 = (uint(LUT.values.length()) - 1u);
+  uint v_14 = min(uint(0), v_13);
+  int g55 = atomicOr(LUT.values[v_14], 0);
 }
 void main_count_inner(uvec3 GlobalInvocationID) {
   uint triangleIndex = GlobalInvocationID[0u];
@@ -87,20 +100,24 @@
     return;
   }
   doIgnore();
-  uint v_2 = ((3u * triangleIndex) + 0u);
-  uint i0 = indices.values[v_2];
-  uint v_3 = ((3u * triangleIndex) + 1u);
-  uint i1 = indices.values[v_3];
-  uint v_4 = ((3u * triangleIndex) + 2u);
-  uint i2 = indices.values[v_4];
+  uint v_15 = ((3u * triangleIndex) + 0u);
+  uint v_16 = min(v_15, (uint(indices.values.length()) - 1u));
+  uint i0 = indices.values[v_16];
+  uint v_17 = ((3u * triangleIndex) + 1u);
+  uint v_18 = min(v_17, (uint(indices.values.length()) - 1u));
+  uint i1 = indices.values[v_18];
+  uint v_19 = ((3u * triangleIndex) + 2u);
+  uint v_20 = min(v_19, (uint(indices.values.length()) - 1u));
+  uint i2 = indices.values[v_20];
   vec3 p0 = loadPosition(i0);
   vec3 p1 = loadPosition(i1);
   vec3 p2 = loadPosition(i2);
   vec3 center = (((p0 + p1) + p2) / 3.0f);
   vec3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(v.inner.gridSize, voxelPos);
-  uint v_5 = voxelIndex;
-  uint acefg = atomicAdd(counters.values[v_5], 1u);
+  uint v_21 = voxelIndex;
+  uint v_22 = min(v_21, (uint(counters.values.length()) - 1u));
+  uint acefg = atomicAdd(counters.values[v_22], 1u);
   if ((triangleIndex == 0u)) {
     v_1.inner.value0 = v.inner.gridSize;
     v_1.inner.value_f32_0 = center.x;
@@ -168,10 +185,18 @@
 void doIgnore() {
   uint g42 = v.inner.numTriangles;
   uint kj6 = v_1.inner.value1;
-  uint b53 = atomicOr(counters.values[0], 0u);
-  uint rwg = indices.values[0];
-  float rb5 = positions.values[0];
-  int g55 = atomicOr(LUT.values[0], 0);
+  uint v_2 = (uint(counters.values.length()) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  uint b53 = atomicOr(counters.values[v_3], 0u);
+  uint v_4 = (uint(indices.values.length()) - 1u);
+  uint v_5 = min(uint(0), v_4);
+  uint rwg = indices.values[v_5];
+  uint v_6 = (uint(positions.values.length()) - 1u);
+  uint v_7 = min(uint(0), v_6);
+  float rb5 = positions.values[v_7];
+  uint v_8 = (uint(LUT.values.length()) - 1u);
+  uint v_9 = min(uint(0), v_8);
+  int g55 = atomicOr(LUT.values[v_9], 0);
 }
 void main_create_lut_inner(uvec3 GlobalInvocationID) {
   uint voxelIndex = GlobalInvocationID[0u];
@@ -180,14 +205,16 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint v_2 = voxelIndex;
-  uint numTriangles = atomicOr(counters.values[v_2], 0u);
+  uint v_10 = voxelIndex;
+  uint v_11 = min(v_10, (uint(counters.values.length()) - 1u));
+  uint numTriangles = atomicOr(counters.values[v_11], 0u);
   int offset = -1;
   if ((numTriangles > 0u)) {
     offset = int(atomicAdd(v_1.inner.offsetCounter, numTriangles));
   }
-  uint v_3 = voxelIndex;
-  atomicExchange(LUT.values[v_3], offset);
+  uint v_12 = voxelIndex;
+  uint v_13 = min(v_12, (uint(LUT.values.length()) - 1u));
+  atomicExchange(LUT.values[v_13], offset);
 }
 layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -265,16 +292,29 @@
   return ((icoord.x + (gridSize * icoord.y)) + ((gridSize * gridSize) * icoord.z));
 }
 vec3 loadPosition(uint vertexIndex) {
-  vec3 position = vec3(positions.values[((3u * vertexIndex) + 0u)], positions.values[((3u * vertexIndex) + 1u)], positions.values[((3u * vertexIndex) + 2u)]);
+  uint v_2 = min(((3u * vertexIndex) + 0u), (uint(positions.values.length()) - 1u));
+  float v_3 = positions.values[v_2];
+  uint v_4 = min(((3u * vertexIndex) + 1u), (uint(positions.values.length()) - 1u));
+  float v_5 = positions.values[v_4];
+  uint v_6 = min(((3u * vertexIndex) + 2u), (uint(positions.values.length()) - 1u));
+  vec3 position = vec3(v_3, v_5, positions.values[v_6]);
   return position;
 }
 void doIgnore() {
   uint g42 = v.inner.numTriangles;
   uint kj6 = v_1.inner.value1;
-  uint b53 = atomicOr(counters.values[0], 0u);
-  uint rwg = indices.values[0];
-  float rb5 = positions.values[0];
-  int g55 = atomicOr(LUT.values[0], 0);
+  uint v_7 = (uint(counters.values.length()) - 1u);
+  uint v_8 = min(uint(0), v_7);
+  uint b53 = atomicOr(counters.values[v_8], 0u);
+  uint v_9 = (uint(indices.values.length()) - 1u);
+  uint v_10 = min(uint(0), v_9);
+  uint rwg = indices.values[v_10];
+  uint v_11 = (uint(positions.values.length()) - 1u);
+  uint v_12 = min(uint(0), v_11);
+  float rb5 = positions.values[v_12];
+  uint v_13 = (uint(LUT.values.length()) - 1u);
+  uint v_14 = min(uint(0), v_13);
+  int g55 = atomicOr(LUT.values[v_14], 0);
 }
 void main_sort_triangles_inner(uvec3 GlobalInvocationID) {
   uint triangleIndex = GlobalInvocationID[0u];
@@ -282,20 +322,24 @@
   if ((triangleIndex >= v.inner.numTriangles)) {
     return;
   }
-  uint v_2 = ((3u * triangleIndex) + 0u);
-  uint i0 = indices.values[v_2];
-  uint v_3 = ((3u * triangleIndex) + 1u);
-  uint i1 = indices.values[v_3];
-  uint v_4 = ((3u * triangleIndex) + 2u);
-  uint i2 = indices.values[v_4];
+  uint v_15 = ((3u * triangleIndex) + 0u);
+  uint v_16 = min(v_15, (uint(indices.values.length()) - 1u));
+  uint i0 = indices.values[v_16];
+  uint v_17 = ((3u * triangleIndex) + 1u);
+  uint v_18 = min(v_17, (uint(indices.values.length()) - 1u));
+  uint i1 = indices.values[v_18];
+  uint v_19 = ((3u * triangleIndex) + 2u);
+  uint v_20 = min(v_19, (uint(indices.values.length()) - 1u));
+  uint i2 = indices.values[v_20];
   vec3 p0 = loadPosition(i0);
   vec3 p1 = loadPosition(i1);
   vec3 p2 = loadPosition(i2);
   vec3 center = (((p0 + p1) + p2) / 3.0f);
   vec3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(v.inner.gridSize, voxelPos);
-  uint v_5 = voxelIndex;
-  int triangleOffset = atomicAdd(LUT.values[v_5], 1);
+  uint v_21 = voxelIndex;
+  uint v_22 = min(v_21, (uint(LUT.values.length()) - 1u));
+  int triangleOffset = atomicAdd(LUT.values[v_22], 1);
 }
 layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
index 1b8a4e2..a21ea39 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.ir.dxc.hlsl
@@ -57,21 +57,39 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((0u + (((3u * vertexIndex) + 0u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 1u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 2u) * 4u)))));
+  uint v_1 = 0u;
+  positions.GetDimensions(v_1);
+  uint v_2 = 0u;
+  positions.GetDimensions(v_2);
+  uint v_3 = 0u;
+  positions.GetDimensions(v_3);
+  float3 position = float3(asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 0u), ((v_1 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 1u), ((v_2 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 2u), ((v_3 / 4u) - 1u)) * 4u)))));
   return position;
 }
 
 void doIgnore() {
   uint g42 = uniforms[0u].x;
   uint kj6 = dbg.Load(20u);
-  uint v_1 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_1);
-  uint b53 = v_1;
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int v_2 = int(0);
-  LUT.InterlockedOr(int(0u), int(0), v_2);
-  int g55 = v_2;
+  uint v_4 = 0u;
+  counters.GetDimensions(v_4);
+  uint v_5 = ((v_4 / 4u) - 1u);
+  uint v_6 = 0u;
+  counters.InterlockedOr(uint((0u + (min(uint(int(0)), v_5) * 4u))), 0u, v_6);
+  uint b53 = v_6;
+  uint v_7 = 0u;
+  indices.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 4u) - 1u);
+  uint rwg = indices.Load((0u + (min(uint(int(0)), v_8) * 4u)));
+  uint v_9 = 0u;
+  positions.GetDimensions(v_9);
+  uint v_10 = ((v_9 / 4u) - 1u);
+  float rb5 = asfloat(positions.Load((0u + (min(uint(int(0)), v_10) * 4u))));
+  uint v_11 = 0u;
+  LUT.GetDimensions(v_11);
+  uint v_12 = ((v_11 / 4u) - 1u);
+  int v_13 = int(0);
+  LUT.InterlockedOr(int((0u + (min(uint(int(0)), v_12) * 4u))), int(0), v_13);
+  int g55 = v_13;
 }
 
 void main_count_inner(uint3 GlobalInvocationID) {
@@ -80,18 +98,26 @@
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * triangleIndex) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * triangleIndex) + 2u) * 4u)));
+  uint v_14 = 0u;
+  indices.GetDimensions(v_14);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_14 / 4u) - 1u)) * 4u)));
+  uint v_15 = 0u;
+  indices.GetDimensions(v_15);
+  uint i1 = indices.Load((0u + (min(((3u * triangleIndex) + 1u), ((v_15 / 4u) - 1u)) * 4u)));
+  uint v_16 = 0u;
+  indices.GetDimensions(v_16);
+  uint i2 = indices.Load((0u + (min(((3u * triangleIndex) + 2u), ((v_16 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  uint v_3 = 0u;
-  counters.InterlockedAdd(uint((0u + (voxelIndex * 4u))), 1u, v_3);
-  uint acefg = v_3;
+  uint v_17 = 0u;
+  counters.GetDimensions(v_17);
+  uint v_18 = 0u;
+  counters.InterlockedAdd(uint((0u + (min(voxelIndex, ((v_17 / 4u) - 1u)) * 4u))), 1u, v_18);
+  uint acefg = v_18;
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, uniforms[0u].y);
     dbg.Store(32u, asuint(center.x));
@@ -107,19 +133,23 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint v_4 = 0u;
-  counters.InterlockedOr(uint((0u + (voxelIndex * 4u))), 0u, v_4);
-  uint numTriangles = v_4;
+  uint v_19 = 0u;
+  counters.GetDimensions(v_19);
+  uint v_20 = 0u;
+  counters.InterlockedOr(uint((0u + (min(voxelIndex, ((v_19 / 4u) - 1u)) * 4u))), 0u, v_20);
+  uint numTriangles = v_20;
   int offset = int(-1);
   if ((numTriangles > 0u)) {
-    uint v_5 = numTriangles;
-    uint v_6 = 0u;
-    dbg.InterlockedAdd(uint(0u), v_5, v_6);
-    offset = int(v_6);
+    uint v_21 = numTriangles;
+    uint v_22 = 0u;
+    dbg.InterlockedAdd(uint(0u), v_21, v_22);
+    offset = int(v_22);
   }
-  int v_7 = offset;
-  int v_8 = int(0);
-  LUT.InterlockedExchange(int((0u + (voxelIndex * 4u))), v_7, v_8);
+  uint v_23 = 0u;
+  LUT.GetDimensions(v_23);
+  int v_24 = offset;
+  int v_25 = int(0);
+  LUT.InterlockedExchange(int((0u + (min(voxelIndex, ((v_23 / 4u) - 1u)) * 4u))), v_24, v_25);
 }
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
@@ -128,18 +158,26 @@
   if ((triangleIndex >= uniforms[0u].x)) {
     return;
   }
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * triangleIndex) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * triangleIndex) + 2u) * 4u)));
+  uint v_26 = 0u;
+  indices.GetDimensions(v_26);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_26 / 4u) - 1u)) * 4u)));
+  uint v_27 = 0u;
+  indices.GetDimensions(v_27);
+  uint i1 = indices.Load((0u + (min(((3u * triangleIndex) + 1u), ((v_27 / 4u) - 1u)) * 4u)));
+  uint v_28 = 0u;
+  indices.GetDimensions(v_28);
+  uint i2 = indices.Load((0u + (min(((3u * triangleIndex) + 2u), ((v_28 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  int v_9 = int(0);
-  LUT.InterlockedAdd(int((0u + (voxelIndex * 4u))), int(1), v_9);
-  int triangleOffset = v_9;
+  uint v_29 = 0u;
+  LUT.GetDimensions(v_29);
+  int v_30 = int(0);
+  LUT.InterlockedAdd(int((0u + (min(voxelIndex, ((v_29 / 4u) - 1u)) * 4u))), int(1), v_30);
+  int triangleOffset = v_30;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
index 1b8a4e2..a21ea39 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1113.wgsl.expected.ir.fxc.hlsl
@@ -57,21 +57,39 @@
 }
 
 float3 loadPosition(uint vertexIndex) {
-  float3 position = float3(asfloat(positions.Load((0u + (((3u * vertexIndex) + 0u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 1u) * 4u)))), asfloat(positions.Load((0u + (((3u * vertexIndex) + 2u) * 4u)))));
+  uint v_1 = 0u;
+  positions.GetDimensions(v_1);
+  uint v_2 = 0u;
+  positions.GetDimensions(v_2);
+  uint v_3 = 0u;
+  positions.GetDimensions(v_3);
+  float3 position = float3(asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 0u), ((v_1 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 1u), ((v_2 / 4u) - 1u)) * 4u)))), asfloat(positions.Load((0u + (min(((3u * vertexIndex) + 2u), ((v_3 / 4u) - 1u)) * 4u)))));
   return position;
 }
 
 void doIgnore() {
   uint g42 = uniforms[0u].x;
   uint kj6 = dbg.Load(20u);
-  uint v_1 = 0u;
-  counters.InterlockedOr(uint(0u), 0u, v_1);
-  uint b53 = v_1;
-  uint rwg = indices.Load(0u);
-  float rb5 = asfloat(positions.Load(0u));
-  int v_2 = int(0);
-  LUT.InterlockedOr(int(0u), int(0), v_2);
-  int g55 = v_2;
+  uint v_4 = 0u;
+  counters.GetDimensions(v_4);
+  uint v_5 = ((v_4 / 4u) - 1u);
+  uint v_6 = 0u;
+  counters.InterlockedOr(uint((0u + (min(uint(int(0)), v_5) * 4u))), 0u, v_6);
+  uint b53 = v_6;
+  uint v_7 = 0u;
+  indices.GetDimensions(v_7);
+  uint v_8 = ((v_7 / 4u) - 1u);
+  uint rwg = indices.Load((0u + (min(uint(int(0)), v_8) * 4u)));
+  uint v_9 = 0u;
+  positions.GetDimensions(v_9);
+  uint v_10 = ((v_9 / 4u) - 1u);
+  float rb5 = asfloat(positions.Load((0u + (min(uint(int(0)), v_10) * 4u))));
+  uint v_11 = 0u;
+  LUT.GetDimensions(v_11);
+  uint v_12 = ((v_11 / 4u) - 1u);
+  int v_13 = int(0);
+  LUT.InterlockedOr(int((0u + (min(uint(int(0)), v_12) * 4u))), int(0), v_13);
+  int g55 = v_13;
 }
 
 void main_count_inner(uint3 GlobalInvocationID) {
@@ -80,18 +98,26 @@
     return;
   }
   doIgnore();
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * triangleIndex) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * triangleIndex) + 2u) * 4u)));
+  uint v_14 = 0u;
+  indices.GetDimensions(v_14);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_14 / 4u) - 1u)) * 4u)));
+  uint v_15 = 0u;
+  indices.GetDimensions(v_15);
+  uint i1 = indices.Load((0u + (min(((3u * triangleIndex) + 1u), ((v_15 / 4u) - 1u)) * 4u)));
+  uint v_16 = 0u;
+  indices.GetDimensions(v_16);
+  uint i2 = indices.Load((0u + (min(((3u * triangleIndex) + 2u), ((v_16 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  uint v_3 = 0u;
-  counters.InterlockedAdd(uint((0u + (voxelIndex * 4u))), 1u, v_3);
-  uint acefg = v_3;
+  uint v_17 = 0u;
+  counters.GetDimensions(v_17);
+  uint v_18 = 0u;
+  counters.InterlockedAdd(uint((0u + (min(voxelIndex, ((v_17 / 4u) - 1u)) * 4u))), 1u, v_18);
+  uint acefg = v_18;
   if ((triangleIndex == 0u)) {
     dbg.Store(16u, uniforms[0u].y);
     dbg.Store(32u, asuint(center.x));
@@ -107,19 +133,23 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint v_4 = 0u;
-  counters.InterlockedOr(uint((0u + (voxelIndex * 4u))), 0u, v_4);
-  uint numTriangles = v_4;
+  uint v_19 = 0u;
+  counters.GetDimensions(v_19);
+  uint v_20 = 0u;
+  counters.InterlockedOr(uint((0u + (min(voxelIndex, ((v_19 / 4u) - 1u)) * 4u))), 0u, v_20);
+  uint numTriangles = v_20;
   int offset = int(-1);
   if ((numTriangles > 0u)) {
-    uint v_5 = numTriangles;
-    uint v_6 = 0u;
-    dbg.InterlockedAdd(uint(0u), v_5, v_6);
-    offset = int(v_6);
+    uint v_21 = numTriangles;
+    uint v_22 = 0u;
+    dbg.InterlockedAdd(uint(0u), v_21, v_22);
+    offset = int(v_22);
   }
-  int v_7 = offset;
-  int v_8 = int(0);
-  LUT.InterlockedExchange(int((0u + (voxelIndex * 4u))), v_7, v_8);
+  uint v_23 = 0u;
+  LUT.GetDimensions(v_23);
+  int v_24 = offset;
+  int v_25 = int(0);
+  LUT.InterlockedExchange(int((0u + (min(voxelIndex, ((v_23 / 4u) - 1u)) * 4u))), v_24, v_25);
 }
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID) {
@@ -128,18 +158,26 @@
   if ((triangleIndex >= uniforms[0u].x)) {
     return;
   }
-  uint i0 = indices.Load((0u + (((3u * triangleIndex) + 0u) * 4u)));
-  uint i1 = indices.Load((0u + (((3u * triangleIndex) + 1u) * 4u)));
-  uint i2 = indices.Load((0u + (((3u * triangleIndex) + 2u) * 4u)));
+  uint v_26 = 0u;
+  indices.GetDimensions(v_26);
+  uint i0 = indices.Load((0u + (min(((3u * triangleIndex) + 0u), ((v_26 / 4u) - 1u)) * 4u)));
+  uint v_27 = 0u;
+  indices.GetDimensions(v_27);
+  uint i1 = indices.Load((0u + (min(((3u * triangleIndex) + 1u), ((v_27 / 4u) - 1u)) * 4u)));
+  uint v_28 = 0u;
+  indices.GetDimensions(v_28);
+  uint i2 = indices.Load((0u + (min(((3u * triangleIndex) + 2u), ((v_28 / 4u) - 1u)) * 4u)));
   float3 p0 = loadPosition(i0);
   float3 p1 = loadPosition(i1);
   float3 p2 = loadPosition(i2);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center);
   uint voxelIndex = toIndex1D(uniforms[0u].y, voxelPos);
-  int v_9 = int(0);
-  LUT.InterlockedAdd(int((0u + (voxelIndex * 4u))), int(1), v_9);
-  int triangleOffset = v_9;
+  uint v_29 = 0u;
+  LUT.GetDimensions(v_29);
+  int v_30 = int(0);
+  LUT.InterlockedAdd(int((0u + (min(voxelIndex, ((v_29 / 4u) - 1u)) * 4u))), int(1), v_30);
+  int triangleOffset = v_30;
 }
 
 [numthreads(128, 1, 1)]
diff --git a/test/tint/bug/tint/1113.wgsl.expected.ir.msl b/test/tint/bug/tint/1113.wgsl.expected.ir.msl
index 2190f3c..8538ca0 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1113.wgsl.expected.ir.msl
@@ -62,6 +62,7 @@
   device AU32s* counters;
   device AI32s* LUT;
   device Dbg* dbg;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 float3 toVoxelPos(float3 position, tint_module_vars_struct tint_module_vars) {
@@ -101,17 +102,21 @@
 }
 
 float3 loadPosition(uint vertexIndex, tint_module_vars_struct tint_module_vars) {
-  float3 position = float3((*tint_module_vars.positions).values[((3u * vertexIndex) + 0u)], (*tint_module_vars.positions).values[((3u * vertexIndex) + 1u)], (*tint_module_vars.positions).values[((3u * vertexIndex) + 2u)]);
+  float3 position = float3((*tint_module_vars.positions).values[min(((3u * vertexIndex) + 0u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))], (*tint_module_vars.positions).values[min(((3u * vertexIndex) + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))], (*tint_module_vars.positions).values[min(((3u * vertexIndex) + 2u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))]);
   return position;
 }
 
 void doIgnore(tint_module_vars_struct tint_module_vars) {
   uint g42 = (*tint_module_vars.uniforms).numTriangles;
   uint kj6 = (*tint_module_vars.dbg).value1;
-  uint b53 = atomic_load_explicit((&(*tint_module_vars.counters).values[0]), memory_order_relaxed);
-  uint rwg = (*tint_module_vars.indices).values[0];
-  float rb5 = (*tint_module_vars.positions).values[0];
-  int g55 = atomic_load_explicit((&(*tint_module_vars.LUT).values[0]), memory_order_relaxed);
+  uint const v = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u);
+  uint b53 = atomic_load_explicit((&(*tint_module_vars.counters).values[min(uint(0), v)]), memory_order_relaxed);
+  uint const v_1 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u);
+  uint rwg = (*tint_module_vars.indices).values[min(uint(0), v_1)];
+  uint const v_2 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u);
+  float rb5 = (*tint_module_vars.positions).values[min(uint(0), v_2)];
+  uint const v_3 = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][3u] - 0u) / 4u) - 1u);
+  int g55 = atomic_load_explicit((&(*tint_module_vars.LUT).values[min(uint(0), v_3)]), memory_order_relaxed);
 }
 
 void main_count_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
@@ -120,16 +125,16 @@
     return;
   }
   doIgnore(tint_module_vars);
-  uint i0 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 1u)];
-  uint i2 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 2u)];
+  uint i0 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 0u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 2u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
   float3 p0 = loadPosition(i0, tint_module_vars);
   float3 p1 = loadPosition(i1, tint_module_vars);
   float3 p2 = loadPosition(i2, tint_module_vars);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center, tint_module_vars);
   uint voxelIndex = toIndex1D((*tint_module_vars.uniforms).gridSize, voxelPos);
-  uint acefg = atomic_fetch_add_explicit((&(*tint_module_vars.counters).values[voxelIndex]), 1u, memory_order_relaxed);
+  uint acefg = atomic_fetch_add_explicit((&(*tint_module_vars.counters).values[min(voxelIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u))]), 1u, memory_order_relaxed);
   if ((triangleIndex == 0u)) {
     (*tint_module_vars.dbg).value0 = (*tint_module_vars.uniforms).gridSize;
     (*tint_module_vars.dbg).value_f32_0 = center[0u];
@@ -145,12 +150,12 @@
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint numTriangles = atomic_load_explicit((&(*tint_module_vars.counters).values[voxelIndex]), memory_order_relaxed);
+  uint numTriangles = atomic_load_explicit((&(*tint_module_vars.counters).values[min(voxelIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
   int offset = -1;
   if ((numTriangles > 0u)) {
     offset = int(atomic_fetch_add_explicit((&(*tint_module_vars.dbg).offsetCounter), numTriangles, memory_order_relaxed));
   }
-  atomic_store_explicit((&(*tint_module_vars.LUT).values[voxelIndex]), offset, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.LUT).values[min(voxelIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][3u] - 0u) / 4u) - 1u))]), offset, memory_order_relaxed);
 }
 
 void main_sort_triangles_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
@@ -159,29 +164,29 @@
   if ((triangleIndex >= (*tint_module_vars.uniforms).numTriangles)) {
     return;
   }
-  uint i0 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 1u)];
-  uint i2 = (*tint_module_vars.indices).values[((3u * triangleIndex) + 2u)];
+  uint i0 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 0u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 1u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*tint_module_vars.indices).values[min(((3u * triangleIndex) + 2u), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
   float3 p0 = loadPosition(i0, tint_module_vars);
   float3 p1 = loadPosition(i1, tint_module_vars);
   float3 p2 = loadPosition(i2, tint_module_vars);
   float3 center = (((p0 + p1) + p2) / 3.0f);
   float3 voxelPos = toVoxelPos(center, tint_module_vars);
   uint voxelIndex = toIndex1D((*tint_module_vars.uniforms).gridSize, voxelPos);
-  int triangleOffset = atomic_fetch_add_explicit((&(*tint_module_vars.LUT).values[voxelIndex]), 1, memory_order_relaxed);
+  int triangleOffset = atomic_fetch_add_explicit((&(*tint_module_vars.LUT).values[min(voxelIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][3u] - 0u) / 4u) - 1u))]), 1, memory_order_relaxed);
 }
 
-kernel void main_count(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg};
+kernel void main_count(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   main_count_inner(GlobalInvocationID, tint_module_vars);
 }
 
-kernel void main_create_lut(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg};
+kernel void main_create_lut(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   main_create_lut_inner(GlobalInvocationID, tint_module_vars);
 }
 
-kernel void main_sort_triangles(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg};
+kernel void main_sort_triangles(uint3 GlobalInvocationID [[thread_position_in_grid]], const constant Uniforms_packed_vec3* uniforms [[buffer(0)]], device U32s* indices [[buffer(3)]], device F32s* positions [[buffer(4)]], device AU32s* counters [[buffer(2)]], device AI32s* LUT [[buffer(5)]], device Dbg* dbg [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .indices=indices, .positions=positions, .counters=counters, .LUT=LUT, .dbg=dbg, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   main_sort_triangles_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/1113.wgsl.expected.msl b/test/tint/bug/tint/1113.wgsl.expected.msl
index c5f5df1..35a4d66 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.msl
+++ b/test/tint/bug/tint/1113.wgsl.expected.msl
@@ -25,6 +25,10 @@
   /* 0x002c */ tint_array<int8_t, 4> tint_pad_1;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 uint3 tint_ftou(float3 v) {
   return select(uint3(4294967295u), select(uint3(v), uint3(0u), (v < float3(0.0f))), (v <= float3(4294967040.0f)));
 }
@@ -105,90 +109,90 @@
   return uint3(x, y, z);
 }
 
-float3 loadPosition(uint vertexIndex, device F32s* const tint_symbol_2) {
-  float3 position = float3((*(tint_symbol_2)).values[((3u * vertexIndex) + 0u)], (*(tint_symbol_2)).values[((3u * vertexIndex) + 1u)], (*(tint_symbol_2)).values[((3u * vertexIndex) + 2u)]);
+float3 loadPosition(uint vertexIndex, device F32s* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
+  float3 position = float3((*(tint_symbol_2)).values[min(((3u * vertexIndex) + 0u), ((((*(tint_symbol_3)).array_lengths[0u][1u] - 0u) / 4u) - 1u))], (*(tint_symbol_2)).values[min(((3u * vertexIndex) + 1u), ((((*(tint_symbol_3)).array_lengths[0u][1u] - 0u) / 4u) - 1u))], (*(tint_symbol_2)).values[min(((3u * vertexIndex) + 2u), ((((*(tint_symbol_3)).array_lengths[0u][1u] - 0u) / 4u) - 1u))]);
   return position;
 }
 
-void doIgnore(const constant Uniforms_tint_packed_vec3* const tint_symbol_3, device Dbg* const tint_symbol_4, device AU32s* const tint_symbol_5, device U32s* const tint_symbol_6, device F32s* const tint_symbol_7, device AI32s* const tint_symbol_8) {
-  uint g42 = (*(tint_symbol_3)).numTriangles;
-  uint kj6 = (*(tint_symbol_4)).value1;
-  uint b53 = atomic_load_explicit(&((*(tint_symbol_5)).values[0]), memory_order_relaxed);
-  uint rwg = (*(tint_symbol_6)).values[0];
-  float rb5 = (*(tint_symbol_7)).values[0];
-  int g55 = atomic_load_explicit(&((*(tint_symbol_8)).values[0]), memory_order_relaxed);
+void doIgnore(const constant Uniforms_tint_packed_vec3* const tint_symbol_4, device Dbg* const tint_symbol_5, device AU32s* const tint_symbol_6, const constant TintArrayLengths* const tint_symbol_7, device U32s* const tint_symbol_8, device F32s* const tint_symbol_9, device AI32s* const tint_symbol_10) {
+  uint g42 = (*(tint_symbol_4)).numTriangles;
+  uint kj6 = (*(tint_symbol_5)).value1;
+  uint b53 = atomic_load_explicit(&((*(tint_symbol_6)).values[min(0u, ((((*(tint_symbol_7)).array_lengths[0u][2u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
+  uint rwg = (*(tint_symbol_8)).values[min(0u, ((((*(tint_symbol_7)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  float rb5 = (*(tint_symbol_9)).values[min(0u, ((((*(tint_symbol_7)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
+  int g55 = atomic_load_explicit(&((*(tint_symbol_10)).values[min(0u, ((((*(tint_symbol_7)).array_lengths[0u][3u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
 }
 
-void main_count_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_9, device Dbg* const tint_symbol_10, device AU32s* const tint_symbol_11, device U32s* const tint_symbol_12, device F32s* const tint_symbol_13, device AI32s* const tint_symbol_14) {
+void main_count_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_11, device Dbg* const tint_symbol_12, device AU32s* const tint_symbol_13, const constant TintArrayLengths* const tint_symbol_14, device U32s* const tint_symbol_15, device F32s* const tint_symbol_16, device AI32s* const tint_symbol_17) {
   uint triangleIndex = GlobalInvocationID[0];
-  if ((triangleIndex >= (*(tint_symbol_9)).numTriangles)) {
+  if ((triangleIndex >= (*(tint_symbol_11)).numTriangles)) {
     return;
   }
-  doIgnore(tint_symbol_9, tint_symbol_10, tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14);
-  uint i0 = (*(tint_symbol_12)).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*(tint_symbol_12)).values[((3u * triangleIndex) + 1u)];
-  uint i2 = (*(tint_symbol_12)).values[((3u * triangleIndex) + 2u)];
-  float3 p0 = loadPosition(i0, tint_symbol_13);
-  float3 p1 = loadPosition(i1, tint_symbol_13);
-  float3 p2 = loadPosition(i2, tint_symbol_13);
+  doIgnore(tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16, tint_symbol_17);
+  uint i0 = (*(tint_symbol_15)).values[min(((3u * triangleIndex) + 0u), ((((*(tint_symbol_14)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*(tint_symbol_15)).values[min(((3u * triangleIndex) + 1u), ((((*(tint_symbol_14)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*(tint_symbol_15)).values[min(((3u * triangleIndex) + 2u), ((((*(tint_symbol_14)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  float3 p0 = loadPosition(i0, tint_symbol_16, tint_symbol_14);
+  float3 p1 = loadPosition(i1, tint_symbol_16, tint_symbol_14);
+  float3 p2 = loadPosition(i2, tint_symbol_16, tint_symbol_14);
   float3 center = (((p0 + p1) + p2) / 3.0f);
-  float3 voxelPos = toVoxelPos(center, tint_symbol_9);
-  uint voxelIndex = toIndex1D((*(tint_symbol_9)).gridSize, voxelPos);
-  uint acefg = atomic_fetch_add_explicit(&((*(tint_symbol_11)).values[voxelIndex]), 1u, memory_order_relaxed);
+  float3 voxelPos = toVoxelPos(center, tint_symbol_11);
+  uint voxelIndex = toIndex1D((*(tint_symbol_11)).gridSize, voxelPos);
+  uint acefg = atomic_fetch_add_explicit(&((*(tint_symbol_13)).values[min(voxelIndex, ((((*(tint_symbol_14)).array_lengths[0u][2u] - 0u) / 4u) - 1u))]), 1u, memory_order_relaxed);
   if ((triangleIndex == 0u)) {
-    (*(tint_symbol_10)).value0 = (*(tint_symbol_9)).gridSize;
-    (*(tint_symbol_10)).value_f32_0 = center[0];
-    (*(tint_symbol_10)).value_f32_1 = center[1];
-    (*(tint_symbol_10)).value_f32_2 = center[2];
+    (*(tint_symbol_12)).value0 = (*(tint_symbol_11)).gridSize;
+    (*(tint_symbol_12)).value_f32_0 = center[0];
+    (*(tint_symbol_12)).value_f32_1 = center[1];
+    (*(tint_symbol_12)).value_f32_2 = center[2];
   }
 }
 
-kernel void main_count(const constant Uniforms_tint_packed_vec3* tint_symbol_15 [[buffer(0)]], device Dbg* tint_symbol_16 [[buffer(1)]], device AU32s* tint_symbol_17 [[buffer(2)]], device U32s* tint_symbol_18 [[buffer(3)]], device F32s* tint_symbol_19 [[buffer(4)]], device AI32s* tint_symbol_20 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  main_count_inner(GlobalInvocationID, tint_symbol_15, tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
+kernel void main_count(const constant Uniforms_tint_packed_vec3* tint_symbol_18 [[buffer(0)]], device Dbg* tint_symbol_19 [[buffer(1)]], device AU32s* tint_symbol_20 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_21 [[buffer(30)]], device U32s* tint_symbol_22 [[buffer(3)]], device F32s* tint_symbol_23 [[buffer(4)]], device AI32s* tint_symbol_24 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  main_count_inner(GlobalInvocationID, tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23, tint_symbol_24);
   return;
 }
 
-void main_create_lut_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_21, device Dbg* const tint_symbol_22, device AU32s* const tint_symbol_23, device U32s* const tint_symbol_24, device F32s* const tint_symbol_25, device AI32s* const tint_symbol_26) {
+void main_create_lut_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_25, device Dbg* const tint_symbol_26, device AU32s* const tint_symbol_27, const constant TintArrayLengths* const tint_symbol_28, device U32s* const tint_symbol_29, device F32s* const tint_symbol_30, device AI32s* const tint_symbol_31) {
   uint voxelIndex = GlobalInvocationID[0];
-  doIgnore(tint_symbol_21, tint_symbol_22, tint_symbol_23, tint_symbol_24, tint_symbol_25, tint_symbol_26);
-  uint maxVoxels = (((*(tint_symbol_21)).gridSize * (*(tint_symbol_21)).gridSize) * (*(tint_symbol_21)).gridSize);
+  doIgnore(tint_symbol_25, tint_symbol_26, tint_symbol_27, tint_symbol_28, tint_symbol_29, tint_symbol_30, tint_symbol_31);
+  uint maxVoxels = (((*(tint_symbol_25)).gridSize * (*(tint_symbol_25)).gridSize) * (*(tint_symbol_25)).gridSize);
   if ((voxelIndex >= maxVoxels)) {
     return;
   }
-  uint numTriangles = atomic_load_explicit(&((*(tint_symbol_23)).values[voxelIndex]), memory_order_relaxed);
+  uint numTriangles = atomic_load_explicit(&((*(tint_symbol_27)).values[min(voxelIndex, ((((*(tint_symbol_28)).array_lengths[0u][2u] - 0u) / 4u) - 1u))]), memory_order_relaxed);
   int offset = -1;
   if ((numTriangles > 0u)) {
-    uint const tint_symbol = atomic_fetch_add_explicit(&((*(tint_symbol_22)).offsetCounter), numTriangles, memory_order_relaxed);
+    uint const tint_symbol = atomic_fetch_add_explicit(&((*(tint_symbol_26)).offsetCounter), numTriangles, memory_order_relaxed);
     offset = int(tint_symbol);
   }
-  atomic_store_explicit(&((*(tint_symbol_26)).values[voxelIndex]), offset, memory_order_relaxed);
+  atomic_store_explicit(&((*(tint_symbol_31)).values[min(voxelIndex, ((((*(tint_symbol_28)).array_lengths[0u][3u] - 0u) / 4u) - 1u))]), offset, memory_order_relaxed);
 }
 
-kernel void main_create_lut(const constant Uniforms_tint_packed_vec3* tint_symbol_27 [[buffer(0)]], device Dbg* tint_symbol_28 [[buffer(1)]], device AU32s* tint_symbol_29 [[buffer(2)]], device U32s* tint_symbol_30 [[buffer(3)]], device F32s* tint_symbol_31 [[buffer(4)]], device AI32s* tint_symbol_32 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  main_create_lut_inner(GlobalInvocationID, tint_symbol_27, tint_symbol_28, tint_symbol_29, tint_symbol_30, tint_symbol_31, tint_symbol_32);
+kernel void main_create_lut(const constant Uniforms_tint_packed_vec3* tint_symbol_32 [[buffer(0)]], device Dbg* tint_symbol_33 [[buffer(1)]], device AU32s* tint_symbol_34 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_35 [[buffer(30)]], device U32s* tint_symbol_36 [[buffer(3)]], device F32s* tint_symbol_37 [[buffer(4)]], device AI32s* tint_symbol_38 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  main_create_lut_inner(GlobalInvocationID, tint_symbol_32, tint_symbol_33, tint_symbol_34, tint_symbol_35, tint_symbol_36, tint_symbol_37, tint_symbol_38);
   return;
 }
 
-void main_sort_triangles_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_33, device Dbg* const tint_symbol_34, device AU32s* const tint_symbol_35, device U32s* const tint_symbol_36, device F32s* const tint_symbol_37, device AI32s* const tint_symbol_38) {
+void main_sort_triangles_inner(uint3 GlobalInvocationID, const constant Uniforms_tint_packed_vec3* const tint_symbol_39, device Dbg* const tint_symbol_40, device AU32s* const tint_symbol_41, const constant TintArrayLengths* const tint_symbol_42, device U32s* const tint_symbol_43, device F32s* const tint_symbol_44, device AI32s* const tint_symbol_45) {
   uint triangleIndex = GlobalInvocationID[0];
-  doIgnore(tint_symbol_33, tint_symbol_34, tint_symbol_35, tint_symbol_36, tint_symbol_37, tint_symbol_38);
-  if ((triangleIndex >= (*(tint_symbol_33)).numTriangles)) {
+  doIgnore(tint_symbol_39, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44, tint_symbol_45);
+  if ((triangleIndex >= (*(tint_symbol_39)).numTriangles)) {
     return;
   }
-  uint i0 = (*(tint_symbol_36)).values[((3u * triangleIndex) + 0u)];
-  uint i1 = (*(tint_symbol_36)).values[((3u * triangleIndex) + 1u)];
-  uint i2 = (*(tint_symbol_36)).values[((3u * triangleIndex) + 2u)];
-  float3 p0 = loadPosition(i0, tint_symbol_37);
-  float3 p1 = loadPosition(i1, tint_symbol_37);
-  float3 p2 = loadPosition(i2, tint_symbol_37);
+  uint i0 = (*(tint_symbol_43)).values[min(((3u * triangleIndex) + 0u), ((((*(tint_symbol_42)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i1 = (*(tint_symbol_43)).values[min(((3u * triangleIndex) + 1u), ((((*(tint_symbol_42)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  uint i2 = (*(tint_symbol_43)).values[min(((3u * triangleIndex) + 2u), ((((*(tint_symbol_42)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
+  float3 p0 = loadPosition(i0, tint_symbol_44, tint_symbol_42);
+  float3 p1 = loadPosition(i1, tint_symbol_44, tint_symbol_42);
+  float3 p2 = loadPosition(i2, tint_symbol_44, tint_symbol_42);
   float3 center = (((p0 + p1) + p2) / 3.0f);
-  float3 voxelPos = toVoxelPos(center, tint_symbol_33);
-  uint voxelIndex = toIndex1D((*(tint_symbol_33)).gridSize, voxelPos);
-  int triangleOffset = atomic_fetch_add_explicit(&((*(tint_symbol_38)).values[voxelIndex]), 1, memory_order_relaxed);
+  float3 voxelPos = toVoxelPos(center, tint_symbol_39);
+  uint voxelIndex = toIndex1D((*(tint_symbol_39)).gridSize, voxelPos);
+  int triangleOffset = atomic_fetch_add_explicit(&((*(tint_symbol_45)).values[min(voxelIndex, ((((*(tint_symbol_42)).array_lengths[0u][3u] - 0u) / 4u) - 1u))]), 1, memory_order_relaxed);
 }
 
-kernel void main_sort_triangles(const constant Uniforms_tint_packed_vec3* tint_symbol_39 [[buffer(0)]], device Dbg* tint_symbol_40 [[buffer(1)]], device AU32s* tint_symbol_41 [[buffer(2)]], device U32s* tint_symbol_42 [[buffer(3)]], device F32s* tint_symbol_43 [[buffer(4)]], device AI32s* tint_symbol_44 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  main_sort_triangles_inner(GlobalInvocationID, tint_symbol_39, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44);
+kernel void main_sort_triangles(const constant Uniforms_tint_packed_vec3* tint_symbol_46 [[buffer(0)]], device Dbg* tint_symbol_47 [[buffer(1)]], device AU32s* tint_symbol_48 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_49 [[buffer(30)]], device U32s* tint_symbol_50 [[buffer(3)]], device F32s* tint_symbol_51 [[buffer(4)]], device AI32s* tint_symbol_52 [[buffer(5)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  main_sort_triangles_inner(GlobalInvocationID, tint_symbol_46, tint_symbol_47, tint_symbol_48, tint_symbol_49, tint_symbol_50, tint_symbol_51, tint_symbol_52);
   return;
 }
 
diff --git a/test/tint/bug/tint/1113.wgsl.expected.spvasm b/test/tint/bug/tint/1113.wgsl.expected.spvasm
index 32f8945..e441f1e 100644
--- a/test/tint/bug/tint/1113.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1113.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 434
+; Bound: 510
 ; Schema: 0
                OpCapability Shader
          %78 = OpExtInstImport "GLSL.std.450"
@@ -229,15 +229,19 @@
         %146 = OpTypeFunction %v3uint %uint %uint
         %167 = OpTypeFunction %v3float %uint
      %uint_3 = OpConstant %uint 3
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
        %void = OpTypeVoid
-        %188 = OpTypeFunction %void
+        %201 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint_0 = OpTypePointer StorageBuffer %_runtimearr_uint_0
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
+%_ptr_StorageBuffer__runtimearr_int = OpTypePointer StorageBuffer %_runtimearr_int
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
 %_ptr_Function_int = OpTypePointer Function %int
-        %215 = OpTypeFunction %void %v3uint
+        %251 = OpTypeFunction %void %v3uint
        %bool = OpTypeBool
     %float_3 = OpConstant %float 3
      %uint_8 = OpConstant %uint 8
@@ -245,15 +249,15 @@
     %uint_10 = OpConstant %uint 10
      %int_n1 = OpConstant %int -1
       %int_1 = OpConstant %int 1
-        %394 = OpTypeFunction %uint %uint %uint
-        %408 = OpTypeFunction %v3uint %v3float
-        %412 = OpConstantNull %v3float
+        %470 = OpTypeFunction %uint %uint %uint
+        %484 = OpTypeFunction %v3uint %v3float
+        %488 = OpConstantNull %v3float
      %v3bool = OpTypeVector %bool 3
-        %415 = OpConstantNull %v3uint
+        %491 = OpConstantNull %v3uint
 %float_4_29496704e_09 = OpConstant %float 4.29496704e+09
-        %417 = OpConstantComposite %v3float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
+        %493 = OpConstantComposite %v3float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
 %uint_4294967295 = OpConstant %uint 4294967295
-        %420 = OpConstantComposite %v3uint %uint_4294967295 %uint_4294967295 %uint_4294967295
+        %496 = OpConstantComposite %v3uint %uint_4294967295 %uint_4294967295 %uint_4294967295
  %toVoxelPos = OpFunction %v3float None %36
    %position = OpFunctionParameter %v3float
          %37 = OpLabel
@@ -390,52 +394,84 @@
  %position_0 = OpVariable %_ptr_Function_v3float Function
         %169 = OpIMul %uint %uint_3 %vertexIndex
         %171 = OpIAdd %uint %169 %uint_0
-        %172 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %171
-        %174 = OpLoad %float %172 None
-        %175 = OpIMul %uint %uint_3 %vertexIndex
-        %176 = OpIAdd %uint %175 %uint_1
+        %172 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %174 = OpArrayLength %uint %positions 0
+        %175 = OpISub %uint %174 %uint_1
+        %176 = OpExtInst %uint %78 UMin %171 %175
         %177 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %176
-        %178 = OpLoad %float %177 None
-        %179 = OpIMul %uint %uint_3 %vertexIndex
-        %180 = OpIAdd %uint %179 %uint_2
-        %181 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %180
-        %182 = OpLoad %float %181 None
-        %183 = OpCompositeConstruct %v3float %174 %178 %182
-               OpStore %position_0 %183
-        %185 = OpLoad %v3float %position_0 None
-               OpReturnValue %185
+        %179 = OpLoad %float %177 None
+        %180 = OpIMul %uint %uint_3 %vertexIndex
+        %181 = OpIAdd %uint %180 %uint_1
+        %182 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %183 = OpArrayLength %uint %positions 0
+        %184 = OpISub %uint %183 %uint_1
+        %185 = OpExtInst %uint %78 UMin %181 %184
+        %186 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %185
+        %187 = OpLoad %float %186 None
+        %188 = OpIMul %uint %uint_3 %vertexIndex
+        %189 = OpIAdd %uint %188 %uint_2
+        %190 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %191 = OpArrayLength %uint %positions 0
+        %192 = OpISub %uint %191 %uint_1
+        %193 = OpExtInst %uint %78 UMin %189 %192
+        %194 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %193
+        %195 = OpLoad %float %194 None
+        %196 = OpCompositeConstruct %v3float %179 %187 %195
+               OpStore %position_0 %196
+        %198 = OpLoad %v3float %position_0 None
+               OpReturnValue %198
                OpFunctionEnd
-   %doIgnore = OpFunction %void None %188
-        %189 = OpLabel
+   %doIgnore = OpFunction %void None %201
+        %202 = OpLabel
         %g42 = OpVariable %_ptr_Function_uint Function
         %kj6 = OpVariable %_ptr_Function_uint Function
         %b53 = OpVariable %_ptr_Function_uint Function
         %rwg = OpVariable %_ptr_Function_uint Function
         %rb5 = OpVariable %_ptr_Function_float Function
         %g55 = OpVariable %_ptr_Function_int Function
-        %190 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-        %191 = OpLoad %uint %190 None
-               OpStore %g42 %191
-        %193 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_5
-        %195 = OpLoad %uint %193 None
-               OpStore %kj6 %195
-        %197 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %int_0
-        %200 = OpAtomicLoad %uint %197 %uint_1 %uint_0
-               OpStore %b53 %200
-        %202 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %int_0
-        %203 = OpLoad %uint %202 None
-               OpStore %rwg %203
-        %205 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %int_0
-        %206 = OpLoad %float %205 None
-               OpStore %rb5 %206
-        %208 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %int_0
-        %210 = OpAtomicLoad %int %208 %uint_1 %uint_0
-               OpStore %g55 %210
+        %203 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+        %204 = OpLoad %uint %203 None
+               OpStore %g42 %204
+        %206 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_5
+        %208 = OpLoad %uint %206 None
+               OpStore %kj6 %208
+        %210 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint_0 %counters %uint_0
+        %212 = OpArrayLength %uint %counters 0
+        %213 = OpISub %uint %212 %uint_1
+        %214 = OpBitcast %uint %int_0
+        %216 = OpExtInst %uint %78 UMin %214 %213
+        %217 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %216
+        %219 = OpAtomicLoad %uint %217 %uint_1 %uint_0
+               OpStore %b53 %219
+        %221 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %223 = OpArrayLength %uint %indices 0
+        %224 = OpISub %uint %223 %uint_1
+        %225 = OpBitcast %uint %int_0
+        %226 = OpExtInst %uint %78 UMin %225 %224
+        %227 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %226
+        %228 = OpLoad %uint %227 None
+               OpStore %rwg %228
+        %230 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %positions %uint_0
+        %231 = OpArrayLength %uint %positions 0
+        %232 = OpISub %uint %231 %uint_1
+        %233 = OpBitcast %uint %int_0
+        %234 = OpExtInst %uint %78 UMin %233 %232
+        %235 = OpAccessChain %_ptr_StorageBuffer_float %positions %uint_0 %234
+        %236 = OpLoad %float %235 None
+               OpStore %rb5 %236
+        %238 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %LUT %uint_0
+        %240 = OpArrayLength %uint %LUT 0
+        %241 = OpISub %uint %240 %uint_1
+        %242 = OpBitcast %uint %int_0
+        %243 = OpExtInst %uint %78 UMin %242 %241
+        %244 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %243
+        %246 = OpAtomicLoad %int %244 %uint_1 %uint_0
+               OpStore %g55 %246
                OpReturn
                OpFunctionEnd
-%main_count_inner = OpFunction %void None %215
+%main_count_inner = OpFunction %void None %251
 %GlobalInvocationID = OpFunctionParameter %v3uint
-        %216 = OpLabel
+        %252 = OpLabel
 %triangleIndex = OpVariable %_ptr_Function_uint Function
          %i0 = OpVariable %_ptr_Function_uint Function
          %i1 = OpVariable %_ptr_Function_uint Function
@@ -447,143 +483,167 @@
  %voxelPos_0 = OpVariable %_ptr_Function_v3float Function
  %voxelIndex = OpVariable %_ptr_Function_uint Function
       %acefg = OpVariable %_ptr_Function_uint Function
-        %217 = OpCompositeExtract %uint %GlobalInvocationID 0
-               OpStore %triangleIndex %217
-        %219 = OpLoad %uint %triangleIndex None
-        %220 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-        %221 = OpLoad %uint %220 None
-        %222 = OpUGreaterThanEqual %bool %219 %221
-               OpSelectionMerge %224 None
-               OpBranchConditional %222 %225 %224
-        %225 = OpLabel
+        %253 = OpCompositeExtract %uint %GlobalInvocationID 0
+               OpStore %triangleIndex %253
+        %255 = OpLoad %uint %triangleIndex None
+        %256 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+        %257 = OpLoad %uint %256 None
+        %258 = OpUGreaterThanEqual %bool %255 %257
+               OpSelectionMerge %260 None
+               OpBranchConditional %258 %261 %260
+        %261 = OpLabel
                OpReturn
-        %224 = OpLabel
-        %226 = OpFunctionCall %void %doIgnore
-        %227 = OpLoad %uint %triangleIndex None
-        %228 = OpIMul %uint %uint_3 %227
-        %229 = OpIAdd %uint %228 %uint_0
-        %230 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %229
-        %231 = OpLoad %uint %230 None
-               OpStore %i0 %231
-        %233 = OpLoad %uint %triangleIndex None
-        %234 = OpIMul %uint %uint_3 %233
-        %235 = OpIAdd %uint %234 %uint_1
-        %236 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %235
-        %237 = OpLoad %uint %236 None
-               OpStore %i1 %237
-        %239 = OpLoad %uint %triangleIndex None
-        %240 = OpIMul %uint %uint_3 %239
-        %241 = OpIAdd %uint %240 %uint_2
-        %242 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %241
-        %243 = OpLoad %uint %242 None
-               OpStore %i2 %243
-        %245 = OpLoad %uint %i0 None
-        %246 = OpFunctionCall %v3float %loadPosition %245
-               OpStore %p0 %246
-        %248 = OpLoad %uint %i1 None
-        %249 = OpFunctionCall %v3float %loadPosition %248
-               OpStore %p1 %249
-        %251 = OpLoad %uint %i2 None
-        %252 = OpFunctionCall %v3float %loadPosition %251
-               OpStore %p2 %252
-        %254 = OpLoad %v3float %p0 None
-        %255 = OpLoad %v3float %p1 None
-        %256 = OpFAdd %v3float %254 %255
-        %257 = OpLoad %v3float %p2 None
-        %258 = OpFAdd %v3float %256 %257
-        %259 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
-        %261 = OpFDiv %v3float %258 %259
-               OpStore %center %261
-        %263 = OpLoad %v3float %center None
-        %264 = OpFunctionCall %v3float %toVoxelPos %263
-               OpStore %voxelPos_0 %264
-        %266 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %267 = OpLoad %uint %266 None
-        %268 = OpLoad %v3float %voxelPos_0 None
-        %269 = OpFunctionCall %uint %toIndex1D %267 %268
-               OpStore %voxelIndex %269
-        %271 = OpLoad %uint %voxelIndex None
-        %272 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %271
-        %273 = OpAtomicIAdd %uint %272 %uint_1 %uint_0 %uint_1
-               OpStore %acefg %273
-        %275 = OpLoad %uint %triangleIndex None
-        %276 = OpIEqual %bool %275 %uint_0
-               OpSelectionMerge %277 None
-               OpBranchConditional %276 %278 %277
-        %278 = OpLabel
-        %279 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_4
-        %280 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %260 = OpLabel
+        %262 = OpFunctionCall %void %doIgnore
+        %263 = OpLoad %uint %triangleIndex None
+        %264 = OpIMul %uint %uint_3 %263
+        %265 = OpIAdd %uint %264 %uint_0
+        %266 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %267 = OpArrayLength %uint %indices 0
+        %268 = OpISub %uint %267 %uint_1
+        %269 = OpExtInst %uint %78 UMin %265 %268
+        %270 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %269
+        %271 = OpLoad %uint %270 None
+               OpStore %i0 %271
+        %273 = OpLoad %uint %triangleIndex None
+        %274 = OpIMul %uint %uint_3 %273
+        %275 = OpIAdd %uint %274 %uint_1
+        %276 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %277 = OpArrayLength %uint %indices 0
+        %278 = OpISub %uint %277 %uint_1
+        %279 = OpExtInst %uint %78 UMin %275 %278
+        %280 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %279
         %281 = OpLoad %uint %280 None
-               OpStore %279 %281 None
-        %282 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_8
-        %284 = OpAccessChain %_ptr_Function_float %center %uint_0
-        %285 = OpLoad %float %284 None
-               OpStore %282 %285 None
-        %286 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_9
-        %288 = OpAccessChain %_ptr_Function_float %center %uint_1
-        %289 = OpLoad %float %288 None
-               OpStore %286 %289 None
-        %290 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_10
-        %292 = OpAccessChain %_ptr_Function_float %center %uint_2
-        %293 = OpLoad %float %292 None
-               OpStore %290 %293 None
-               OpBranch %277
-        %277 = OpLabel
+               OpStore %i1 %281
+        %283 = OpLoad %uint %triangleIndex None
+        %284 = OpIMul %uint %uint_3 %283
+        %285 = OpIAdd %uint %284 %uint_2
+        %286 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %287 = OpArrayLength %uint %indices 0
+        %288 = OpISub %uint %287 %uint_1
+        %289 = OpExtInst %uint %78 UMin %285 %288
+        %290 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %289
+        %291 = OpLoad %uint %290 None
+               OpStore %i2 %291
+        %293 = OpLoad %uint %i0 None
+        %294 = OpFunctionCall %v3float %loadPosition %293
+               OpStore %p0 %294
+        %296 = OpLoad %uint %i1 None
+        %297 = OpFunctionCall %v3float %loadPosition %296
+               OpStore %p1 %297
+        %299 = OpLoad %uint %i2 None
+        %300 = OpFunctionCall %v3float %loadPosition %299
+               OpStore %p2 %300
+        %302 = OpLoad %v3float %p0 None
+        %303 = OpLoad %v3float %p1 None
+        %304 = OpFAdd %v3float %302 %303
+        %305 = OpLoad %v3float %p2 None
+        %306 = OpFAdd %v3float %304 %305
+        %307 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
+        %309 = OpFDiv %v3float %306 %307
+               OpStore %center %309
+        %311 = OpLoad %v3float %center None
+        %312 = OpFunctionCall %v3float %toVoxelPos %311
+               OpStore %voxelPos_0 %312
+        %314 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %315 = OpLoad %uint %314 None
+        %316 = OpLoad %v3float %voxelPos_0 None
+        %317 = OpFunctionCall %uint %toIndex1D %315 %316
+               OpStore %voxelIndex %317
+        %319 = OpLoad %uint %voxelIndex None
+        %320 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint_0 %counters %uint_0
+        %321 = OpArrayLength %uint %counters 0
+        %322 = OpISub %uint %321 %uint_1
+        %323 = OpExtInst %uint %78 UMin %319 %322
+        %324 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %323
+        %325 = OpAtomicIAdd %uint %324 %uint_1 %uint_0 %uint_1
+               OpStore %acefg %325
+        %327 = OpLoad %uint %triangleIndex None
+        %328 = OpIEqual %bool %327 %uint_0
+               OpSelectionMerge %329 None
+               OpBranchConditional %328 %330 %329
+        %330 = OpLabel
+        %331 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_0 %uint_4
+        %332 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %333 = OpLoad %uint %332 None
+               OpStore %331 %333 None
+        %334 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_8
+        %336 = OpAccessChain %_ptr_Function_float %center %uint_0
+        %337 = OpLoad %float %336 None
+               OpStore %334 %337 None
+        %338 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_9
+        %340 = OpAccessChain %_ptr_Function_float %center %uint_1
+        %341 = OpLoad %float %340 None
+               OpStore %338 %341 None
+        %342 = OpAccessChain %_ptr_StorageBuffer_float %25 %uint_0 %uint_10
+        %344 = OpAccessChain %_ptr_Function_float %center %uint_2
+        %345 = OpLoad %float %344 None
+               OpStore %342 %345 None
+               OpBranch %329
+        %329 = OpLabel
                OpReturn
                OpFunctionEnd
-%main_create_lut_inner = OpFunction %void None %215
+%main_create_lut_inner = OpFunction %void None %251
 %GlobalInvocationID_0 = OpFunctionParameter %v3uint
-        %296 = OpLabel
+        %348 = OpLabel
 %voxelIndex_0 = OpVariable %_ptr_Function_uint Function
   %maxVoxels = OpVariable %_ptr_Function_uint Function
 %numTriangles = OpVariable %_ptr_Function_uint Function
      %offset = OpVariable %_ptr_Function_int Function
-        %297 = OpCompositeExtract %uint %GlobalInvocationID_0 0
-               OpStore %voxelIndex_0 %297
-        %299 = OpFunctionCall %void %doIgnore
-        %300 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %301 = OpLoad %uint %300 None
-        %302 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %303 = OpLoad %uint %302 None
-        %304 = OpIMul %uint %301 %303
-        %305 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %306 = OpLoad %uint %305 None
-        %307 = OpIMul %uint %304 %306
-               OpStore %maxVoxels %307
-        %309 = OpLoad %uint %voxelIndex_0 None
-        %310 = OpLoad %uint %maxVoxels None
-        %311 = OpUGreaterThanEqual %bool %309 %310
-               OpSelectionMerge %312 None
-               OpBranchConditional %311 %313 %312
-        %313 = OpLabel
+        %349 = OpCompositeExtract %uint %GlobalInvocationID_0 0
+               OpStore %voxelIndex_0 %349
+        %351 = OpFunctionCall %void %doIgnore
+        %352 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %353 = OpLoad %uint %352 None
+        %354 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %355 = OpLoad %uint %354 None
+        %356 = OpIMul %uint %353 %355
+        %357 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %358 = OpLoad %uint %357 None
+        %359 = OpIMul %uint %356 %358
+               OpStore %maxVoxels %359
+        %361 = OpLoad %uint %voxelIndex_0 None
+        %362 = OpLoad %uint %maxVoxels None
+        %363 = OpUGreaterThanEqual %bool %361 %362
+               OpSelectionMerge %364 None
+               OpBranchConditional %363 %365 %364
+        %365 = OpLabel
                OpReturn
-        %312 = OpLabel
-        %314 = OpLoad %uint %voxelIndex_0 None
-        %315 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %314
-        %316 = OpAtomicLoad %uint %315 %uint_1 %uint_0
-               OpStore %numTriangles %316
+        %364 = OpLabel
+        %366 = OpLoad %uint %voxelIndex_0 None
+        %367 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint_0 %counters %uint_0
+        %368 = OpArrayLength %uint %counters 0
+        %369 = OpISub %uint %368 %uint_1
+        %370 = OpExtInst %uint %78 UMin %366 %369
+        %371 = OpAccessChain %_ptr_StorageBuffer_uint_0 %counters %uint_0 %370
+        %372 = OpAtomicLoad %uint %371 %uint_1 %uint_0
+               OpStore %numTriangles %372
                OpStore %offset %int_n1
-        %320 = OpLoad %uint %numTriangles None
-        %321 = OpUGreaterThan %bool %320 %uint_0
-               OpSelectionMerge %322 None
-               OpBranchConditional %321 %323 %322
-        %323 = OpLabel
-        %324 = OpAccessChain %_ptr_StorageBuffer_uint_0 %25 %uint_0 %uint_0
-        %325 = OpLoad %uint %numTriangles None
-        %326 = OpAtomicIAdd %uint %324 %uint_1 %uint_0 %325
-        %327 = OpBitcast %int %326
-               OpStore %offset %327 None
-               OpBranch %322
-        %322 = OpLabel
-        %328 = OpLoad %uint %voxelIndex_0 None
-        %329 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %328
-        %330 = OpLoad %int %offset None
-               OpAtomicStore %329 %uint_1 %uint_0 %330
+        %376 = OpLoad %uint %numTriangles None
+        %377 = OpUGreaterThan %bool %376 %uint_0
+               OpSelectionMerge %378 None
+               OpBranchConditional %377 %379 %378
+        %379 = OpLabel
+        %380 = OpAccessChain %_ptr_StorageBuffer_uint_0 %25 %uint_0 %uint_0
+        %381 = OpLoad %uint %numTriangles None
+        %382 = OpAtomicIAdd %uint %380 %uint_1 %uint_0 %381
+        %383 = OpBitcast %int %382
+               OpStore %offset %383 None
+               OpBranch %378
+        %378 = OpLabel
+        %384 = OpLoad %uint %voxelIndex_0 None
+        %385 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %LUT %uint_0
+        %386 = OpArrayLength %uint %LUT 0
+        %387 = OpISub %uint %386 %uint_1
+        %388 = OpExtInst %uint %78 UMin %384 %387
+        %389 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %388
+        %390 = OpLoad %int %offset None
+               OpAtomicStore %389 %uint_1 %uint_0 %390
                OpReturn
                OpFunctionEnd
-%main_sort_triangles_inner = OpFunction %void None %215
+%main_sort_triangles_inner = OpFunction %void None %251
 %GlobalInvocationID_1 = OpFunctionParameter %v3uint
-        %334 = OpLabel
+        %394 = OpLabel
 %triangleIndex_0 = OpVariable %_ptr_Function_uint Function
        %i0_0 = OpVariable %_ptr_Function_uint Function
        %i1_0 = OpVariable %_ptr_Function_uint Function
@@ -595,112 +655,128 @@
  %voxelPos_1 = OpVariable %_ptr_Function_v3float Function
 %voxelIndex_1 = OpVariable %_ptr_Function_uint Function
 %triangleOffset = OpVariable %_ptr_Function_int Function
-        %335 = OpCompositeExtract %uint %GlobalInvocationID_1 0
-               OpStore %triangleIndex_0 %335
-        %337 = OpFunctionCall %void %doIgnore
-        %338 = OpLoad %uint %triangleIndex_0 None
-        %339 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-        %340 = OpLoad %uint %339 None
-        %341 = OpUGreaterThanEqual %bool %338 %340
-               OpSelectionMerge %342 None
-               OpBranchConditional %341 %343 %342
-        %343 = OpLabel
+        %395 = OpCompositeExtract %uint %GlobalInvocationID_1 0
+               OpStore %triangleIndex_0 %395
+        %397 = OpFunctionCall %void %doIgnore
+        %398 = OpLoad %uint %triangleIndex_0 None
+        %399 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+        %400 = OpLoad %uint %399 None
+        %401 = OpUGreaterThanEqual %bool %398 %400
+               OpSelectionMerge %402 None
+               OpBranchConditional %401 %403 %402
+        %403 = OpLabel
                OpReturn
-        %342 = OpLabel
-        %344 = OpLoad %uint %triangleIndex_0 None
-        %345 = OpIMul %uint %uint_3 %344
-        %346 = OpIAdd %uint %345 %uint_0
-        %347 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %346
-        %348 = OpLoad %uint %347 None
-               OpStore %i0_0 %348
-        %350 = OpLoad %uint %triangleIndex_0 None
-        %351 = OpIMul %uint %uint_3 %350
-        %352 = OpIAdd %uint %351 %uint_1
-        %353 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %352
-        %354 = OpLoad %uint %353 None
-               OpStore %i1_0 %354
-        %356 = OpLoad %uint %triangleIndex_0 None
-        %357 = OpIMul %uint %uint_3 %356
-        %358 = OpIAdd %uint %357 %uint_2
-        %359 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %358
-        %360 = OpLoad %uint %359 None
-               OpStore %i2_0 %360
-        %362 = OpLoad %uint %i0_0 None
-        %363 = OpFunctionCall %v3float %loadPosition %362
-               OpStore %p0_0 %363
-        %365 = OpLoad %uint %i1_0 None
-        %366 = OpFunctionCall %v3float %loadPosition %365
-               OpStore %p1_0 %366
-        %368 = OpLoad %uint %i2_0 None
-        %369 = OpFunctionCall %v3float %loadPosition %368
-               OpStore %p2_0 %369
-        %371 = OpLoad %v3float %p0_0 None
-        %372 = OpLoad %v3float %p1_0 None
-        %373 = OpFAdd %v3float %371 %372
-        %374 = OpLoad %v3float %p2_0 None
-        %375 = OpFAdd %v3float %373 %374
-        %376 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
-        %377 = OpFDiv %v3float %375 %376
-               OpStore %center_0 %377
-        %379 = OpLoad %v3float %center_0 None
-        %380 = OpFunctionCall %v3float %toVoxelPos %379
-               OpStore %voxelPos_1 %380
-        %382 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
-        %383 = OpLoad %uint %382 None
-        %384 = OpLoad %v3float %voxelPos_1 None
-        %385 = OpFunctionCall %uint %toIndex1D %383 %384
-               OpStore %voxelIndex_1 %385
-        %387 = OpLoad %uint %voxelIndex_1 None
-        %388 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %387
-        %389 = OpAtomicIAdd %int %388 %uint_1 %uint_0 %int_1
-               OpStore %triangleOffset %389
+        %402 = OpLabel
+        %404 = OpLoad %uint %triangleIndex_0 None
+        %405 = OpIMul %uint %uint_3 %404
+        %406 = OpIAdd %uint %405 %uint_0
+        %407 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %408 = OpArrayLength %uint %indices 0
+        %409 = OpISub %uint %408 %uint_1
+        %410 = OpExtInst %uint %78 UMin %406 %409
+        %411 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %410
+        %412 = OpLoad %uint %411 None
+               OpStore %i0_0 %412
+        %414 = OpLoad %uint %triangleIndex_0 None
+        %415 = OpIMul %uint %uint_3 %414
+        %416 = OpIAdd %uint %415 %uint_1
+        %417 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %418 = OpArrayLength %uint %indices 0
+        %419 = OpISub %uint %418 %uint_1
+        %420 = OpExtInst %uint %78 UMin %416 %419
+        %421 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %420
+        %422 = OpLoad %uint %421 None
+               OpStore %i1_0 %422
+        %424 = OpLoad %uint %triangleIndex_0 None
+        %425 = OpIMul %uint %uint_3 %424
+        %426 = OpIAdd %uint %425 %uint_2
+        %427 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %indices %uint_0
+        %428 = OpArrayLength %uint %indices 0
+        %429 = OpISub %uint %428 %uint_1
+        %430 = OpExtInst %uint %78 UMin %426 %429
+        %431 = OpAccessChain %_ptr_StorageBuffer_uint %indices %uint_0 %430
+        %432 = OpLoad %uint %431 None
+               OpStore %i2_0 %432
+        %434 = OpLoad %uint %i0_0 None
+        %435 = OpFunctionCall %v3float %loadPosition %434
+               OpStore %p0_0 %435
+        %437 = OpLoad %uint %i1_0 None
+        %438 = OpFunctionCall %v3float %loadPosition %437
+               OpStore %p1_0 %438
+        %440 = OpLoad %uint %i2_0 None
+        %441 = OpFunctionCall %v3float %loadPosition %440
+               OpStore %p2_0 %441
+        %443 = OpLoad %v3float %p0_0 None
+        %444 = OpLoad %v3float %p1_0 None
+        %445 = OpFAdd %v3float %443 %444
+        %446 = OpLoad %v3float %p2_0 None
+        %447 = OpFAdd %v3float %445 %446
+        %448 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
+        %449 = OpFDiv %v3float %447 %448
+               OpStore %center_0 %449
+        %451 = OpLoad %v3float %center_0 None
+        %452 = OpFunctionCall %v3float %toVoxelPos %451
+               OpStore %voxelPos_1 %452
+        %454 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
+        %455 = OpLoad %uint %454 None
+        %456 = OpLoad %v3float %voxelPos_1 None
+        %457 = OpFunctionCall %uint %toIndex1D %455 %456
+               OpStore %voxelIndex_1 %457
+        %459 = OpLoad %uint %voxelIndex_1 None
+        %460 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %LUT %uint_0
+        %461 = OpArrayLength %uint %LUT 0
+        %462 = OpISub %uint %461 %uint_1
+        %463 = OpExtInst %uint %78 UMin %459 %462
+        %464 = OpAccessChain %_ptr_StorageBuffer_int %LUT %uint_0 %463
+        %465 = OpAtomicIAdd %int %464 %uint_1 %uint_0 %int_1
+               OpStore %triangleOffset %465
                OpReturn
                OpFunctionEnd
-%tint_div_u32 = OpFunction %uint None %394
+%tint_div_u32 = OpFunction %uint None %470
         %lhs = OpFunctionParameter %uint
         %rhs = OpFunctionParameter %uint
-        %395 = OpLabel
-        %396 = OpIEqual %bool %rhs %uint_0
-        %397 = OpSelect %uint %396 %uint_1 %rhs
-        %398 = OpUDiv %uint %lhs %397
-               OpReturnValue %398
+        %471 = OpLabel
+        %472 = OpIEqual %bool %rhs %uint_0
+        %473 = OpSelect %uint %472 %uint_1 %rhs
+        %474 = OpUDiv %uint %lhs %473
+               OpReturnValue %474
                OpFunctionEnd
-%tint_mod_u32 = OpFunction %uint None %394
+%tint_mod_u32 = OpFunction %uint None %470
       %lhs_0 = OpFunctionParameter %uint
       %rhs_0 = OpFunctionParameter %uint
-        %401 = OpLabel
-        %402 = OpIEqual %bool %rhs_0 %uint_0
-        %403 = OpSelect %uint %402 %uint_1 %rhs_0
-        %404 = OpUDiv %uint %lhs_0 %403
-        %405 = OpIMul %uint %404 %403
-        %406 = OpISub %uint %lhs_0 %405
-               OpReturnValue %406
+        %477 = OpLabel
+        %478 = OpIEqual %bool %rhs_0 %uint_0
+        %479 = OpSelect %uint %478 %uint_1 %rhs_0
+        %480 = OpUDiv %uint %lhs_0 %479
+        %481 = OpIMul %uint %480 %479
+        %482 = OpISub %uint %lhs_0 %481
+               OpReturnValue %482
                OpFunctionEnd
-%tint_v3f32_to_v3u32 = OpFunction %v3uint None %408
+%tint_v3f32_to_v3u32 = OpFunction %v3uint None %484
       %value = OpFunctionParameter %v3float
-        %409 = OpLabel
-        %410 = OpConvertFToU %v3uint %value
-        %411 = OpFOrdGreaterThanEqual %v3bool %value %412
-        %414 = OpSelect %v3uint %411 %410 %415
-        %416 = OpFOrdLessThanEqual %v3bool %value %417
-        %419 = OpSelect %v3uint %416 %414 %420
-               OpReturnValue %419
+        %485 = OpLabel
+        %486 = OpConvertFToU %v3uint %value
+        %487 = OpFOrdGreaterThanEqual %v3bool %value %488
+        %490 = OpSelect %v3uint %487 %486 %491
+        %492 = OpFOrdLessThanEqual %v3bool %value %493
+        %495 = OpSelect %v3uint %492 %490 %496
+               OpReturnValue %495
                OpFunctionEnd
- %main_count = OpFunction %void None %188
-        %423 = OpLabel
-        %424 = OpLoad %v3uint %main_count_global_invocation_id_Input None
-        %425 = OpFunctionCall %void %main_count_inner %424
+ %main_count = OpFunction %void None %201
+        %499 = OpLabel
+        %500 = OpLoad %v3uint %main_count_global_invocation_id_Input None
+        %501 = OpFunctionCall %void %main_count_inner %500
                OpReturn
                OpFunctionEnd
-%main_create_lut = OpFunction %void None %188
-        %427 = OpLabel
-        %428 = OpLoad %v3uint %main_create_lut_global_invocation_id_Input None
-        %429 = OpFunctionCall %void %main_create_lut_inner %428
+%main_create_lut = OpFunction %void None %201
+        %503 = OpLabel
+        %504 = OpLoad %v3uint %main_create_lut_global_invocation_id_Input None
+        %505 = OpFunctionCall %void %main_create_lut_inner %504
                OpReturn
                OpFunctionEnd
-%main_sort_triangles = OpFunction %void None %188
-        %431 = OpLabel
-        %432 = OpLoad %v3uint %main_sort_triangles_global_invocation_id_Input None
-        %433 = OpFunctionCall %void %main_sort_triangles_inner %432
+%main_sort_triangles = OpFunction %void None %201
+        %507 = OpLabel
+        %508 = OpLoad %v3uint %main_sort_triangles_global_invocation_id_Input None
+        %509 = OpFunctionCall %void %main_sort_triangles_inner %508
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1121.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.dxc.hlsl
index 5b2073e..b001adf7 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.dxc.hlsl
@@ -30,21 +30,27 @@
 
 
 void main_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_3 = 0u;
+  lightsBuffer.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 32u);
   uint index = GlobalInvocationID.x;
   if ((index >= config[0].x)) {
     return;
   }
-  lightsBuffer.Store(((32u * index) + 4u), asuint(((asfloat(lightsBuffer.Load(((32u * index) + 4u))) - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))))));
-  if ((asfloat(lightsBuffer.Load(((32u * index) + 4u))) < asfloat(uniforms[0].y))) {
-    lightsBuffer.Store(((32u * index) + 4u), asuint(asfloat(uniforms[1].y)));
+  lightsBuffer.Store(((32u * min(index, (tint_symbol_4 - 1u))) + 4u), asuint(((asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 4u))) - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))))));
+  if ((asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 4u))) < asfloat(uniforms[0].y))) {
+    uint tint_symbol_5 = 0u;
+    lightsBuffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 32u);
+    lightsBuffer.Store(((32u * min(index, (tint_symbol_6 - 1u))) + 4u), asuint(asfloat(uniforms[1].y)));
   }
   float4x4 M = uniforms_load_1(96u);
   float viewNear = (-(M[3][2]) / (-1.0f + M[2][2]));
   float viewFar = (-(M[3][2]) / (1.0f + M[2][2]));
-  float4 lightPos = asfloat(lightsBuffer.Load4((32u * index)));
+  float4 lightPos = asfloat(lightsBuffer.Load4((32u * min(index, (tint_symbol_4 - 1u)))));
   lightPos = mul(lightPos, uniforms_load_1(32u));
   lightPos = (lightPos / lightPos.w);
-  float lightRadius = asfloat(lightsBuffer.Load(((32u * index) + 28u)));
+  float lightRadius = asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 28u)));
   float4 boxMin = (lightPos - float4(float3((lightRadius).xxx), 0.0f));
   float4 boxMax = (lightPos + float4(float3((lightRadius).xxx), 0.0f));
   float4 frustumPlanes[6] = (float4[6])0;
@@ -70,23 +76,23 @@
           {
             for(uint i = 0u; (i < 6u); i = (i + 1u)) {
               float4 p = float4(0.0f, 0.0f, 0.0f, 0.0f);
-              if ((frustumPlanes[i].x > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].x > 0.0f)) {
                 p.x = boxMax.x;
               } else {
                 p.x = boxMin.x;
               }
-              if ((frustumPlanes[i].y > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].y > 0.0f)) {
                 p.y = boxMax.y;
               } else {
                 p.y = boxMin.y;
               }
-              if ((frustumPlanes[i].z > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].z > 0.0f)) {
                 p.z = boxMax.z;
               } else {
                 p.z = boxMin.z;
               }
               p.w = 1.0f;
-              dp = (dp + min(0.0f, dot(p, frustumPlanes[i])));
+              dp = (dp + min(0.0f, dot(p, frustumPlanes[min(i, 5u)])));
             }
           }
           if ((dp >= 0.0f)) {
@@ -98,11 +104,11 @@
             if ((tint_tmp)) {
               continue;
             }
-            uint offset = tileLightIdatomicAdd((260u * tileId), 1u);
+            uint offset = tileLightIdatomicAdd((260u * min(tileId, 3u)), 1u);
             if ((offset >= config[1].x)) {
               continue;
             }
-            tileLightId.Store((((260u * tileId) + 4u) + (4u * offset)), asuint(GlobalInvocationID.x));
+            tileLightId.Store((((260u * min(tileId, 3u)) + 4u) + (4u * min(offset, 63u))), asuint(GlobalInvocationID.x));
           }
         }
       }
diff --git a/test/tint/bug/tint/1121.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.fxc.hlsl
index 5b2073e..b001adf7 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.fxc.hlsl
@@ -30,21 +30,27 @@
 
 
 void main_inner(uint3 GlobalInvocationID) {
+  uint tint_symbol_3 = 0u;
+  lightsBuffer.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 32u);
   uint index = GlobalInvocationID.x;
   if ((index >= config[0].x)) {
     return;
   }
-  lightsBuffer.Store(((32u * index) + 4u), asuint(((asfloat(lightsBuffer.Load(((32u * index) + 4u))) - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))))));
-  if ((asfloat(lightsBuffer.Load(((32u * index) + 4u))) < asfloat(uniforms[0].y))) {
-    lightsBuffer.Store(((32u * index) + 4u), asuint(asfloat(uniforms[1].y)));
+  lightsBuffer.Store(((32u * min(index, (tint_symbol_4 - 1u))) + 4u), asuint(((asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 4u))) - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))))));
+  if ((asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 4u))) < asfloat(uniforms[0].y))) {
+    uint tint_symbol_5 = 0u;
+    lightsBuffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 32u);
+    lightsBuffer.Store(((32u * min(index, (tint_symbol_6 - 1u))) + 4u), asuint(asfloat(uniforms[1].y)));
   }
   float4x4 M = uniforms_load_1(96u);
   float viewNear = (-(M[3][2]) / (-1.0f + M[2][2]));
   float viewFar = (-(M[3][2]) / (1.0f + M[2][2]));
-  float4 lightPos = asfloat(lightsBuffer.Load4((32u * index)));
+  float4 lightPos = asfloat(lightsBuffer.Load4((32u * min(index, (tint_symbol_4 - 1u)))));
   lightPos = mul(lightPos, uniforms_load_1(32u));
   lightPos = (lightPos / lightPos.w);
-  float lightRadius = asfloat(lightsBuffer.Load(((32u * index) + 28u)));
+  float lightRadius = asfloat(lightsBuffer.Load(((32u * min(index, (tint_symbol_4 - 1u))) + 28u)));
   float4 boxMin = (lightPos - float4(float3((lightRadius).xxx), 0.0f));
   float4 boxMax = (lightPos + float4(float3((lightRadius).xxx), 0.0f));
   float4 frustumPlanes[6] = (float4[6])0;
@@ -70,23 +76,23 @@
           {
             for(uint i = 0u; (i < 6u); i = (i + 1u)) {
               float4 p = float4(0.0f, 0.0f, 0.0f, 0.0f);
-              if ((frustumPlanes[i].x > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].x > 0.0f)) {
                 p.x = boxMax.x;
               } else {
                 p.x = boxMin.x;
               }
-              if ((frustumPlanes[i].y > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].y > 0.0f)) {
                 p.y = boxMax.y;
               } else {
                 p.y = boxMin.y;
               }
-              if ((frustumPlanes[i].z > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)].z > 0.0f)) {
                 p.z = boxMax.z;
               } else {
                 p.z = boxMin.z;
               }
               p.w = 1.0f;
-              dp = (dp + min(0.0f, dot(p, frustumPlanes[i])));
+              dp = (dp + min(0.0f, dot(p, frustumPlanes[min(i, 5u)])));
             }
           }
           if ((dp >= 0.0f)) {
@@ -98,11 +104,11 @@
             if ((tint_tmp)) {
               continue;
             }
-            uint offset = tileLightIdatomicAdd((260u * tileId), 1u);
+            uint offset = tileLightIdatomicAdd((260u * min(tileId, 3u)), 1u);
             if ((offset >= config[1].x)) {
               continue;
             }
-            tileLightId.Store((((260u * tileId) + 4u) + (4u * offset)), asuint(GlobalInvocationID.x));
+            tileLightId.Store((((260u * min(tileId, 3u)) + 4u) + (4u * min(offset, 63u))), asuint(GlobalInvocationID.x));
           }
         }
       }
diff --git a/test/tint/bug/tint/1121.wgsl.expected.glsl b/test/tint/bug/tint/1121.wgsl.expected.glsl
index 1e2f99f..7d8f691 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.glsl
@@ -55,31 +55,37 @@
     return;
   }
   uint v_3 = index;
-  uint v_4 = index;
-  float v_5 = (lightsBuffer.lights[v_4].position.y - 0.10000000149011611938f);
-  float v_6 = float(index);
-  lightsBuffer.lights[v_3].position[1u] = (v_5 + (0.00100000004749745131f * (v_6 - (64.0f * floor((float(index) / 64.0f))))));
-  uint v_7 = index;
-  if ((lightsBuffer.lights[v_7].position.y < v_2.inner.tint_symbol.y)) {
-    uint v_8 = index;
-    lightsBuffer.lights[v_8].position[1u] = v_2.inner.tint_symbol_1.y;
+  uint v_4 = min(v_3, (uint(lightsBuffer.lights.length()) - 1u));
+  uint v_5 = index;
+  uint v_6 = min(v_5, (uint(lightsBuffer.lights.length()) - 1u));
+  float v_7 = (lightsBuffer.lights[v_6].position.y - 0.10000000149011611938f);
+  float v_8 = float(index);
+  lightsBuffer.lights[v_4].position[1u] = (v_7 + (0.00100000004749745131f * (v_8 - (64.0f * floor((float(index) / 64.0f))))));
+  uint v_9 = index;
+  uint v_10 = min(v_9, (uint(lightsBuffer.lights.length()) - 1u));
+  if ((lightsBuffer.lights[v_10].position.y < v_2.inner.tint_symbol.y)) {
+    uint v_11 = index;
+    uint v_12 = min(v_11, (uint(lightsBuffer.lights.length()) - 1u));
+    lightsBuffer.lights[v_12].position[1u] = v_2.inner.tint_symbol_1.y;
   }
   mat4 M = v_2.inner.projectionMatrix;
-  float viewNear = (-(M[3].z) / (-1.0f + M[2].z));
-  float viewFar = (-(M[3].z) / (1.0f + M[2].z));
-  uint v_9 = index;
-  vec4 lightPos = lightsBuffer.lights[v_9].position;
+  float viewNear = (-(M[3u].z) / (-1.0f + M[2u].z));
+  float viewFar = (-(M[3u].z) / (1.0f + M[2u].z));
+  uint v_13 = index;
+  uint v_14 = min(v_13, (uint(lightsBuffer.lights.length()) - 1u));
+  vec4 lightPos = lightsBuffer.lights[v_14].position;
   lightPos = (v_2.inner.viewMatrix * lightPos);
   lightPos = (lightPos / lightPos.w);
-  uint v_10 = index;
-  float lightRadius = lightsBuffer.lights[v_10].radius;
-  vec4 v_11 = lightPos;
-  vec4 boxMin = (v_11 - vec4(vec3(lightRadius), 0.0f));
-  vec4 v_12 = lightPos;
-  vec4 boxMax = (v_12 + vec4(vec3(lightRadius), 0.0f));
+  uint v_15 = index;
+  uint v_16 = min(v_15, (uint(lightsBuffer.lights.length()) - 1u));
+  float lightRadius = lightsBuffer.lights[v_16].radius;
+  vec4 v_17 = lightPos;
+  vec4 boxMin = (v_17 - vec4(vec3(lightRadius), 0.0f));
+  vec4 v_18 = lightPos;
+  vec4 boxMax = (v_18 + vec4(vec3(lightRadius), 0.0f));
   vec4 frustumPlanes[6] = vec4[6](vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f));
-  frustumPlanes[4] = vec4(0.0f, 0.0f, -1.0f, viewNear);
-  frustumPlanes[5] = vec4(0.0f, 0.0f, 1.0f, -(viewFar));
+  frustumPlanes[4u] = vec4(0.0f, 0.0f, -1.0f, viewNear);
+  frustumPlanes[5u] = vec4(0.0f, 0.0f, 1.0f, -(viewFar));
   int TILE_SIZE = 16;
   int TILE_COUNT_X = 2;
   int TILE_COUNT_Y = 2;
@@ -98,17 +104,17 @@
             break;
           }
           ivec2 tilePixel0Idx = ivec2((x * TILE_SIZE), (y * TILE_SIZE));
-          vec2 v_13 = (2.0f * vec2(tilePixel0Idx));
-          vec2 floorCoord = ((v_13 / v_2.inner.fullScreenSize.xy) - vec2(1.0f));
-          ivec2 v_14 = tilePixel0Idx;
-          vec2 v_15 = (2.0f * vec2((v_14 + ivec2(TILE_SIZE))));
-          vec2 ceilCoord = ((v_15 / v_2.inner.fullScreenSize.xy) - vec2(1.0f));
-          vec2 viewFloorCoord = vec2((((-(viewNear) * floorCoord.x) - (M[2].x * viewNear)) / M[0].x), (((-(viewNear) * floorCoord.y) - (M[2].y * viewNear)) / M[1].y));
-          vec2 viewCeilCoord = vec2((((-(viewNear) * ceilCoord.x) - (M[2].x * viewNear)) / M[0].x), (((-(viewNear) * ceilCoord.y) - (M[2].y * viewNear)) / M[1].y));
-          frustumPlanes[0] = vec4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
-          frustumPlanes[1] = vec4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
-          frustumPlanes[2] = vec4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
-          frustumPlanes[3] = vec4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
+          vec2 v_19 = (2.0f * vec2(tilePixel0Idx));
+          vec2 floorCoord = ((v_19 / v_2.inner.fullScreenSize.xy) - vec2(1.0f));
+          ivec2 v_20 = tilePixel0Idx;
+          vec2 v_21 = (2.0f * vec2((v_20 + ivec2(TILE_SIZE))));
+          vec2 ceilCoord = ((v_21 / v_2.inner.fullScreenSize.xy) - vec2(1.0f));
+          vec2 viewFloorCoord = vec2((((-(viewNear) * floorCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * floorCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          vec2 viewCeilCoord = vec2((((-(viewNear) * ceilCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * ceilCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          frustumPlanes[0u] = vec4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
+          frustumPlanes[1u] = vec4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
+          frustumPlanes[2u] = vec4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
+          frustumPlanes[3u] = vec4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
           float dp = 0.0f;
           {
             uint i = 0u;
@@ -118,29 +124,29 @@
                 break;
               }
               vec4 p = vec4(0.0f);
-              uint v_16 = i;
-              if ((frustumPlanes[v_16].x > 0.0f)) {
+              uint v_22 = min(i, 5u);
+              if ((frustumPlanes[v_22].x > 0.0f)) {
                 p[0u] = boxMax.x;
               } else {
                 p[0u] = boxMin.x;
               }
-              uint v_17 = i;
-              if ((frustumPlanes[v_17].y > 0.0f)) {
+              uint v_23 = min(i, 5u);
+              if ((frustumPlanes[v_23].y > 0.0f)) {
                 p[1u] = boxMax.y;
               } else {
                 p[1u] = boxMin.y;
               }
-              uint v_18 = i;
-              if ((frustumPlanes[v_18].z > 0.0f)) {
+              uint v_24 = min(i, 5u);
+              if ((frustumPlanes[v_24].z > 0.0f)) {
                 p[2u] = boxMax.z;
               } else {
                 p[2u] = boxMin.z;
               }
               p[3u] = 1.0f;
-              float v_19 = dp;
-              vec4 v_20 = p;
-              uint v_21 = i;
-              dp = (v_19 + min(0.0f, dot(v_20, frustumPlanes[v_21])));
+              float v_25 = dp;
+              vec4 v_26 = p;
+              uint v_27 = min(i, 5u);
+              dp = (v_25 + min(0.0f, dot(v_26, frustumPlanes[v_27])));
               {
                 i = (i + 1u);
               }
@@ -149,29 +155,29 @@
           }
           if ((dp >= 0.0f)) {
             uint tileId = uint((x + (y * TILE_COUNT_X)));
-            bool v_22 = false;
+            bool v_28 = false;
             if ((tileId < 0u)) {
-              v_22 = true;
+              v_28 = true;
             } else {
-              v_22 = (tileId >= v_1.inner.numTiles);
+              v_28 = (tileId >= v_1.inner.numTiles);
             }
-            if (v_22) {
+            if (v_28) {
               {
                 x = (x + 1);
               }
               continue;
             }
-            uint v_23 = tileId;
-            uint offset = atomicAdd(v.inner.data[v_23].count, 1u);
+            uint v_29 = min(tileId, 3u);
+            uint offset = atomicAdd(v.inner.data[v_29].count, 1u);
             if ((offset >= v_1.inner.numTileLightSlot)) {
               {
                 x = (x + 1);
               }
               continue;
             }
-            uint v_24 = tileId;
-            uint v_25 = offset;
-            v.inner.data[v_24].lightId[v_25] = GlobalInvocationID[0u];
+            uint v_30 = min(tileId, 3u);
+            uint v_31 = min(offset, 63u);
+            v.inner.data[v_30].lightId[v_31] = GlobalInvocationID[0u];
           }
           {
             x = (x + 1);
diff --git a/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
index a323990..2023094 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.ir.dxc.hlsl
@@ -20,28 +20,40 @@
   if ((index >= config[0u].x)) {
     return;
   }
-  uint v_1 = (index * 32u);
-  float v_2 = (asfloat(lightsBuffer.Load((4u + (index * 32u)))) - 0.10000000149011611938f);
-  float v_3 = float(index);
-  lightsBuffer.Store((4u + v_1), asuint((v_2 + (0.00100000004749745131f * (v_3 - (64.0f * floor((float(index) / 64.0f))))))));
-  if ((asfloat(lightsBuffer.Load((4u + (index * 32u)))) < asfloat(uniforms[0u].y))) {
-    lightsBuffer.Store((4u + (index * 32u)), asuint(asfloat(uniforms[1u].y)));
+  uint v_1 = 0u;
+  lightsBuffer.GetDimensions(v_1);
+  uint v_2 = (min(index, ((v_1 / 32u) - 1u)) * 32u);
+  uint v_3 = 0u;
+  lightsBuffer.GetDimensions(v_3);
+  float v_4 = (asfloat(lightsBuffer.Load((4u + (min(index, ((v_3 / 32u) - 1u)) * 32u)))) - 0.10000000149011611938f);
+  float v_5 = float(index);
+  lightsBuffer.Store((4u + v_2), asuint((v_4 + (0.00100000004749745131f * (v_5 - (64.0f * floor((float(index) / 64.0f))))))));
+  uint v_6 = 0u;
+  lightsBuffer.GetDimensions(v_6);
+  if ((asfloat(lightsBuffer.Load((4u + (min(index, ((v_6 / 32u) - 1u)) * 32u)))) < asfloat(uniforms[0u].y))) {
+    uint v_7 = 0u;
+    lightsBuffer.GetDimensions(v_7);
+    lightsBuffer.Store((4u + (min(index, ((v_7 / 32u) - 1u)) * 32u)), asuint(asfloat(uniforms[1u].y)));
   }
   float4x4 M = v(96u);
-  float viewNear = (-(M[int(3)].z) / (-1.0f + M[int(2)].z));
-  float viewFar = (-(M[int(3)].z) / (1.0f + M[int(2)].z));
-  float4 lightPos = asfloat(lightsBuffer.Load4((0u + (index * 32u))));
-  float4x4 v_4 = v(32u);
-  lightPos = mul(lightPos, v_4);
+  float viewNear = (-(M[3u].z) / (-1.0f + M[2u].z));
+  float viewFar = (-(M[3u].z) / (1.0f + M[2u].z));
+  uint v_8 = 0u;
+  lightsBuffer.GetDimensions(v_8);
+  float4 lightPos = asfloat(lightsBuffer.Load4((0u + (min(index, ((v_8 / 32u) - 1u)) * 32u))));
+  float4x4 v_9 = v(32u);
+  lightPos = mul(lightPos, v_9);
   lightPos = (lightPos / lightPos.w);
-  float lightRadius = asfloat(lightsBuffer.Load((28u + (index * 32u))));
-  float4 v_5 = lightPos;
-  float4 boxMin = (v_5 - float4(float3((lightRadius).xxx), 0.0f));
-  float4 v_6 = lightPos;
-  float4 boxMax = (v_6 + float4(float3((lightRadius).xxx), 0.0f));
+  uint v_10 = 0u;
+  lightsBuffer.GetDimensions(v_10);
+  float lightRadius = asfloat(lightsBuffer.Load((28u + (min(index, ((v_10 / 32u) - 1u)) * 32u))));
+  float4 v_11 = lightPos;
+  float4 boxMin = (v_11 - float4(float3((lightRadius).xxx), 0.0f));
+  float4 v_12 = lightPos;
+  float4 boxMax = (v_12 + float4(float3((lightRadius).xxx), 0.0f));
   float4 frustumPlanes[6] = (float4[6])0;
-  frustumPlanes[int(4)] = float4(0.0f, 0.0f, -1.0f, viewNear);
-  frustumPlanes[int(5)] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
+  frustumPlanes[4u] = float4(0.0f, 0.0f, -1.0f, viewNear);
+  frustumPlanes[5u] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
   int TILE_SIZE = int(16);
   int TILE_COUNT_X = int(2);
   int TILE_COUNT_Y = int(2);
@@ -60,17 +72,17 @@
             break;
           }
           int2 tilePixel0Idx = int2((x * TILE_SIZE), (y * TILE_SIZE));
-          float2 v_7 = (2.0f * float2(tilePixel0Idx));
-          float2 floorCoord = ((v_7 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
-          int2 v_8 = tilePixel0Idx;
-          float2 v_9 = (2.0f * float2((v_8 + int2((TILE_SIZE).xx))));
-          float2 ceilCoord = ((v_9 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
-          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord.x) - (M[int(2)].x * viewNear)) / M[int(0)].x), (((-(viewNear) * floorCoord.y) - (M[int(2)].y * viewNear)) / M[int(1)].y));
-          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord.x) - (M[int(2)].x * viewNear)) / M[int(0)].x), (((-(viewNear) * ceilCoord.y) - (M[int(2)].y * viewNear)) / M[int(1)].y));
-          frustumPlanes[int(0)] = float4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
-          frustumPlanes[int(1)] = float4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
-          frustumPlanes[int(2)] = float4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
-          frustumPlanes[int(3)] = float4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
+          float2 v_13 = (2.0f * float2(tilePixel0Idx));
+          float2 floorCoord = ((v_13 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
+          int2 v_14 = tilePixel0Idx;
+          float2 v_15 = (2.0f * float2((v_14 + int2((TILE_SIZE).xx))));
+          float2 ceilCoord = ((v_15 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
+          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * floorCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * ceilCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          frustumPlanes[0u] = float4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
+          frustumPlanes[1u] = float4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
+          frustumPlanes[2u] = float4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
+          frustumPlanes[3u] = float4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
           float dp = 0.0f;
           {
             uint i = 0u;
@@ -80,29 +92,29 @@
                 break;
               }
               float4 p = (0.0f).xxxx;
-              uint v_10 = i;
-              if ((frustumPlanes[v_10].x > 0.0f)) {
+              uint v_16 = min(i, 5u);
+              if ((frustumPlanes[v_16].x > 0.0f)) {
                 p.x = boxMax.x;
               } else {
                 p.x = boxMin.x;
               }
-              uint v_11 = i;
-              if ((frustumPlanes[v_11].y > 0.0f)) {
+              uint v_17 = min(i, 5u);
+              if ((frustumPlanes[v_17].y > 0.0f)) {
                 p.y = boxMax.y;
               } else {
                 p.y = boxMin.y;
               }
-              uint v_12 = i;
-              if ((frustumPlanes[v_12].z > 0.0f)) {
+              uint v_18 = min(i, 5u);
+              if ((frustumPlanes[v_18].z > 0.0f)) {
                 p.z = boxMax.z;
               } else {
                 p.z = boxMin.z;
               }
               p.w = 1.0f;
-              float v_13 = dp;
-              float4 v_14 = p;
-              uint v_15 = i;
-              dp = (v_13 + min(0.0f, dot(v_14, frustumPlanes[v_15])));
+              float v_19 = dp;
+              float4 v_20 = p;
+              uint v_21 = min(i, 5u);
+              dp = (v_19 + min(0.0f, dot(v_20, frustumPlanes[v_21])));
               {
                 i = (i + 1u);
               }
@@ -111,28 +123,28 @@
           }
           if ((dp >= 0.0f)) {
             uint tileId = uint((x + (y * TILE_COUNT_X)));
-            bool v_16 = false;
+            bool v_22 = false;
             if ((tileId < 0u)) {
-              v_16 = true;
+              v_22 = true;
             } else {
-              v_16 = (tileId >= config[0u].y);
+              v_22 = (tileId >= config[0u].y);
             }
-            if (v_16) {
+            if (v_22) {
               {
                 x = (x + int(1));
               }
               continue;
             }
-            uint v_17 = 0u;
-            tileLightId.InterlockedAdd(uint((0u + (tileId * 260u))), 1u, v_17);
-            uint offset = v_17;
+            uint v_23 = 0u;
+            tileLightId.InterlockedAdd(uint((0u + (min(tileId, 3u) * 260u))), 1u, v_23);
+            uint offset = v_23;
             if ((offset >= config[1u].x)) {
               {
                 x = (x + int(1));
               }
               continue;
             }
-            tileLightId.Store(((4u + (tileId * 260u)) + (offset * 4u)), GlobalInvocationID.x);
+            tileLightId.Store(((4u + (min(tileId, 3u) * 260u)) + (min(offset, 63u) * 4u)), GlobalInvocationID.x);
           }
           {
             x = (x + int(1));
diff --git a/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
index a323990..2023094 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1121.wgsl.expected.ir.fxc.hlsl
@@ -20,28 +20,40 @@
   if ((index >= config[0u].x)) {
     return;
   }
-  uint v_1 = (index * 32u);
-  float v_2 = (asfloat(lightsBuffer.Load((4u + (index * 32u)))) - 0.10000000149011611938f);
-  float v_3 = float(index);
-  lightsBuffer.Store((4u + v_1), asuint((v_2 + (0.00100000004749745131f * (v_3 - (64.0f * floor((float(index) / 64.0f))))))));
-  if ((asfloat(lightsBuffer.Load((4u + (index * 32u)))) < asfloat(uniforms[0u].y))) {
-    lightsBuffer.Store((4u + (index * 32u)), asuint(asfloat(uniforms[1u].y)));
+  uint v_1 = 0u;
+  lightsBuffer.GetDimensions(v_1);
+  uint v_2 = (min(index, ((v_1 / 32u) - 1u)) * 32u);
+  uint v_3 = 0u;
+  lightsBuffer.GetDimensions(v_3);
+  float v_4 = (asfloat(lightsBuffer.Load((4u + (min(index, ((v_3 / 32u) - 1u)) * 32u)))) - 0.10000000149011611938f);
+  float v_5 = float(index);
+  lightsBuffer.Store((4u + v_2), asuint((v_4 + (0.00100000004749745131f * (v_5 - (64.0f * floor((float(index) / 64.0f))))))));
+  uint v_6 = 0u;
+  lightsBuffer.GetDimensions(v_6);
+  if ((asfloat(lightsBuffer.Load((4u + (min(index, ((v_6 / 32u) - 1u)) * 32u)))) < asfloat(uniforms[0u].y))) {
+    uint v_7 = 0u;
+    lightsBuffer.GetDimensions(v_7);
+    lightsBuffer.Store((4u + (min(index, ((v_7 / 32u) - 1u)) * 32u)), asuint(asfloat(uniforms[1u].y)));
   }
   float4x4 M = v(96u);
-  float viewNear = (-(M[int(3)].z) / (-1.0f + M[int(2)].z));
-  float viewFar = (-(M[int(3)].z) / (1.0f + M[int(2)].z));
-  float4 lightPos = asfloat(lightsBuffer.Load4((0u + (index * 32u))));
-  float4x4 v_4 = v(32u);
-  lightPos = mul(lightPos, v_4);
+  float viewNear = (-(M[3u].z) / (-1.0f + M[2u].z));
+  float viewFar = (-(M[3u].z) / (1.0f + M[2u].z));
+  uint v_8 = 0u;
+  lightsBuffer.GetDimensions(v_8);
+  float4 lightPos = asfloat(lightsBuffer.Load4((0u + (min(index, ((v_8 / 32u) - 1u)) * 32u))));
+  float4x4 v_9 = v(32u);
+  lightPos = mul(lightPos, v_9);
   lightPos = (lightPos / lightPos.w);
-  float lightRadius = asfloat(lightsBuffer.Load((28u + (index * 32u))));
-  float4 v_5 = lightPos;
-  float4 boxMin = (v_5 - float4(float3((lightRadius).xxx), 0.0f));
-  float4 v_6 = lightPos;
-  float4 boxMax = (v_6 + float4(float3((lightRadius).xxx), 0.0f));
+  uint v_10 = 0u;
+  lightsBuffer.GetDimensions(v_10);
+  float lightRadius = asfloat(lightsBuffer.Load((28u + (min(index, ((v_10 / 32u) - 1u)) * 32u))));
+  float4 v_11 = lightPos;
+  float4 boxMin = (v_11 - float4(float3((lightRadius).xxx), 0.0f));
+  float4 v_12 = lightPos;
+  float4 boxMax = (v_12 + float4(float3((lightRadius).xxx), 0.0f));
   float4 frustumPlanes[6] = (float4[6])0;
-  frustumPlanes[int(4)] = float4(0.0f, 0.0f, -1.0f, viewNear);
-  frustumPlanes[int(5)] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
+  frustumPlanes[4u] = float4(0.0f, 0.0f, -1.0f, viewNear);
+  frustumPlanes[5u] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
   int TILE_SIZE = int(16);
   int TILE_COUNT_X = int(2);
   int TILE_COUNT_Y = int(2);
@@ -60,17 +72,17 @@
             break;
           }
           int2 tilePixel0Idx = int2((x * TILE_SIZE), (y * TILE_SIZE));
-          float2 v_7 = (2.0f * float2(tilePixel0Idx));
-          float2 floorCoord = ((v_7 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
-          int2 v_8 = tilePixel0Idx;
-          float2 v_9 = (2.0f * float2((v_8 + int2((TILE_SIZE).xx))));
-          float2 ceilCoord = ((v_9 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
-          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord.x) - (M[int(2)].x * viewNear)) / M[int(0)].x), (((-(viewNear) * floorCoord.y) - (M[int(2)].y * viewNear)) / M[int(1)].y));
-          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord.x) - (M[int(2)].x * viewNear)) / M[int(0)].x), (((-(viewNear) * ceilCoord.y) - (M[int(2)].y * viewNear)) / M[int(1)].y));
-          frustumPlanes[int(0)] = float4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
-          frustumPlanes[int(1)] = float4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
-          frustumPlanes[int(2)] = float4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
-          frustumPlanes[int(3)] = float4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
+          float2 v_13 = (2.0f * float2(tilePixel0Idx));
+          float2 floorCoord = ((v_13 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
+          int2 v_14 = tilePixel0Idx;
+          float2 v_15 = (2.0f * float2((v_14 + int2((TILE_SIZE).xx))));
+          float2 ceilCoord = ((v_15 / asfloat(uniforms[10u]).xy) - (1.0f).xx);
+          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * floorCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord.x) - (M[2u].x * viewNear)) / M[0u].x), (((-(viewNear) * ceilCoord.y) - (M[2u].y * viewNear)) / M[1u].y));
+          frustumPlanes[0u] = float4(1.0f, 0.0f, (-(viewFloorCoord.x) / viewNear), 0.0f);
+          frustumPlanes[1u] = float4(-1.0f, 0.0f, (viewCeilCoord.x / viewNear), 0.0f);
+          frustumPlanes[2u] = float4(0.0f, 1.0f, (-(viewFloorCoord.y) / viewNear), 0.0f);
+          frustumPlanes[3u] = float4(0.0f, -1.0f, (viewCeilCoord.y / viewNear), 0.0f);
           float dp = 0.0f;
           {
             uint i = 0u;
@@ -80,29 +92,29 @@
                 break;
               }
               float4 p = (0.0f).xxxx;
-              uint v_10 = i;
-              if ((frustumPlanes[v_10].x > 0.0f)) {
+              uint v_16 = min(i, 5u);
+              if ((frustumPlanes[v_16].x > 0.0f)) {
                 p.x = boxMax.x;
               } else {
                 p.x = boxMin.x;
               }
-              uint v_11 = i;
-              if ((frustumPlanes[v_11].y > 0.0f)) {
+              uint v_17 = min(i, 5u);
+              if ((frustumPlanes[v_17].y > 0.0f)) {
                 p.y = boxMax.y;
               } else {
                 p.y = boxMin.y;
               }
-              uint v_12 = i;
-              if ((frustumPlanes[v_12].z > 0.0f)) {
+              uint v_18 = min(i, 5u);
+              if ((frustumPlanes[v_18].z > 0.0f)) {
                 p.z = boxMax.z;
               } else {
                 p.z = boxMin.z;
               }
               p.w = 1.0f;
-              float v_13 = dp;
-              float4 v_14 = p;
-              uint v_15 = i;
-              dp = (v_13 + min(0.0f, dot(v_14, frustumPlanes[v_15])));
+              float v_19 = dp;
+              float4 v_20 = p;
+              uint v_21 = min(i, 5u);
+              dp = (v_19 + min(0.0f, dot(v_20, frustumPlanes[v_21])));
               {
                 i = (i + 1u);
               }
@@ -111,28 +123,28 @@
           }
           if ((dp >= 0.0f)) {
             uint tileId = uint((x + (y * TILE_COUNT_X)));
-            bool v_16 = false;
+            bool v_22 = false;
             if ((tileId < 0u)) {
-              v_16 = true;
+              v_22 = true;
             } else {
-              v_16 = (tileId >= config[0u].y);
+              v_22 = (tileId >= config[0u].y);
             }
-            if (v_16) {
+            if (v_22) {
               {
                 x = (x + int(1));
               }
               continue;
             }
-            uint v_17 = 0u;
-            tileLightId.InterlockedAdd(uint((0u + (tileId * 260u))), 1u, v_17);
-            uint offset = v_17;
+            uint v_23 = 0u;
+            tileLightId.InterlockedAdd(uint((0u + (min(tileId, 3u) * 260u))), 1u, v_23);
+            uint offset = v_23;
             if ((offset >= config[1u].x)) {
               {
                 x = (x + int(1));
               }
               continue;
             }
-            tileLightId.Store(((4u + (tileId * 260u)) + (offset * 4u)), GlobalInvocationID.x);
+            tileLightId.Store(((4u + (min(tileId, 3u) * 260u)) + (min(offset, 63u) * 4u)), GlobalInvocationID.x);
           }
           {
             x = (x + int(1));
diff --git a/test/tint/bug/tint/1121.wgsl.expected.ir.msl b/test/tint/bug/tint/1121.wgsl.expected.ir.msl
index 4c25e32..e8a8217 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1121.wgsl.expected.ir.msl
@@ -54,6 +54,7 @@
   device Tiles* tileLightId;
   const constant Config* config;
   const constant Uniforms* uniforms;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
@@ -61,27 +62,27 @@
   if ((index >= (*tint_module_vars.config).numLights)) {
     return;
   }
-  device float4* const v = (&(*tint_module_vars.lightsBuffer).lights[index].position);
-  float const v_1 = ((*tint_module_vars.lightsBuffer).lights[index].position[1u] - 0.10000000149011611938f);
+  device float4* const v = (&(*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].position);
+  float const v_1 = ((*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].position[1u] - 0.10000000149011611938f);
   float const v_2 = float(index);
   (*v)[1u] = (v_1 + (0.00100000004749745131f * (v_2 - (64.0f * floor((float(index) / 64.0f))))));
-  if (((*tint_module_vars.lightsBuffer).lights[index].position[1u] < (*tint_module_vars.uniforms).min[1u])) {
-    (*tint_module_vars.lightsBuffer).lights[index].position[1u] = (*tint_module_vars.uniforms).max[1u];
+  if (((*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].position[1u] < (*tint_module_vars.uniforms).min[1u])) {
+    (*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].position[1u] = (*tint_module_vars.uniforms).max[1u];
   }
   float4x4 M = (*tint_module_vars.uniforms).projectionMatrix;
-  float viewNear = (-(M[3][2]) / (-1.0f + M[2][2]));
-  float viewFar = (-(M[3][2]) / (1.0f + M[2][2]));
-  float4 lightPos = (*tint_module_vars.lightsBuffer).lights[index].position;
+  float viewNear = (-(M[3u][2u]) / (-1.0f + M[2u][2u]));
+  float viewFar = (-(M[3u][2u]) / (1.0f + M[2u][2u]));
+  float4 lightPos = (*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].position;
   lightPos = ((*tint_module_vars.uniforms).viewMatrix * lightPos);
   lightPos = (lightPos / lightPos[3u]);
-  float lightRadius = (*tint_module_vars.lightsBuffer).lights[index].radius;
+  float lightRadius = (*tint_module_vars.lightsBuffer).lights[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].radius;
   float4 const v_3 = lightPos;
   float4 boxMin = (v_3 - float4(float3(lightRadius), 0.0f));
   float4 const v_4 = lightPos;
   float4 boxMax = (v_4 + float4(float3(lightRadius), 0.0f));
   tint_array<float4, 6> frustumPlanes = {};
-  frustumPlanes[4] = float4(0.0f, 0.0f, -1.0f, viewNear);
-  frustumPlanes[5] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
+  frustumPlanes[4u] = float4(0.0f, 0.0f, -1.0f, viewNear);
+  frustumPlanes[5u] = float4(0.0f, 0.0f, 1.0f, -(viewFar));
   int const TILE_SIZE = 16;
   int const TILE_COUNT_X = 2;
   int const TILE_COUNT_Y = 2;
@@ -105,12 +106,12 @@
           int2 const v_6 = tilePixel0Idx;
           float2 const v_7 = (2.0f * float2(as_type<int2>((as_type<uint2>(v_6) + as_type<uint2>(int2(TILE_SIZE))))));
           float2 ceilCoord = ((v_7 / (*tint_module_vars.uniforms).fullScreenSize.xy) - float2(1.0f));
-          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord[0u]) - (M[2][0] * viewNear)) / M[0][0]), (((-(viewNear) * floorCoord[1u]) - (M[2][1] * viewNear)) / M[1][1]));
-          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord[0u]) - (M[2][0] * viewNear)) / M[0][0]), (((-(viewNear) * ceilCoord[1u]) - (M[2][1] * viewNear)) / M[1][1]));
-          frustumPlanes[0] = float4(1.0f, 0.0f, (-(viewFloorCoord[0u]) / viewNear), 0.0f);
-          frustumPlanes[1] = float4(-1.0f, 0.0f, (viewCeilCoord[0u] / viewNear), 0.0f);
-          frustumPlanes[2] = float4(0.0f, 1.0f, (-(viewFloorCoord[1u]) / viewNear), 0.0f);
-          frustumPlanes[3] = float4(0.0f, -1.0f, (viewCeilCoord[1u] / viewNear), 0.0f);
+          float2 viewFloorCoord = float2((((-(viewNear) * floorCoord[0u]) - (M[2u][0u] * viewNear)) / M[0u][0u]), (((-(viewNear) * floorCoord[1u]) - (M[2u][1u] * viewNear)) / M[1u][1u]));
+          float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord[0u]) - (M[2u][0u] * viewNear)) / M[0u][0u]), (((-(viewNear) * ceilCoord[1u]) - (M[2u][1u] * viewNear)) / M[1u][1u]));
+          frustumPlanes[0u] = float4(1.0f, 0.0f, (-(viewFloorCoord[0u]) / viewNear), 0.0f);
+          frustumPlanes[1u] = float4(-1.0f, 0.0f, (viewCeilCoord[0u] / viewNear), 0.0f);
+          frustumPlanes[2u] = float4(0.0f, 1.0f, (-(viewFloorCoord[1u]) / viewNear), 0.0f);
+          frustumPlanes[3u] = float4(0.0f, -1.0f, (viewCeilCoord[1u] / viewNear), 0.0f);
           float dp = 0.0f;
           {
             uint i = 0u;
@@ -120,23 +121,23 @@
                 break;
               }
               float4 p = 0.0f;
-              if ((frustumPlanes[i][0u] > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)][0u] > 0.0f)) {
                 p[0u] = boxMax[0u];
               } else {
                 p[0u] = boxMin[0u];
               }
-              if ((frustumPlanes[i][1u] > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)][1u] > 0.0f)) {
                 p[1u] = boxMax[1u];
               } else {
                 p[1u] = boxMin[1u];
               }
-              if ((frustumPlanes[i][2u] > 0.0f)) {
+              if ((frustumPlanes[min(i, 5u)][2u] > 0.0f)) {
                 p[2u] = boxMax[2u];
               } else {
                 p[2u] = boxMin[2u];
               }
               p[3u] = 1.0f;
-              dp = (dp + min(0.0f, dot(p, frustumPlanes[i])));
+              dp = (dp + min(0.0f, dot(p, frustumPlanes[min(i, 5u)])));
               {
                 i = (i + 1u);
               }
@@ -157,14 +158,14 @@
               }
               continue;
             }
-            uint offset = atomic_fetch_add_explicit((&(*tint_module_vars.tileLightId).data[tileId].count), 1u, memory_order_relaxed);
+            uint offset = atomic_fetch_add_explicit((&(*tint_module_vars.tileLightId).data[min(tileId, 3u)].count), 1u, memory_order_relaxed);
             if ((offset >= (*tint_module_vars.config).numTileLightSlot)) {
               {
                 x = as_type<int>((as_type<uint>(x) + as_type<uint>(1)));
               }
               continue;
             }
-            (*tint_module_vars.tileLightId).data[tileId].lightId[offset] = GlobalInvocationID[0u];
+            (*tint_module_vars.tileLightId).data[min(tileId, 3u)].lightId[min(offset, 63u)] = GlobalInvocationID[0u];
           }
           {
             x = as_type<int>((as_type<uint>(x) + as_type<uint>(1)));
@@ -180,7 +181,7 @@
   }
 }
 
-kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], device LightsBuffer_packed_vec3* lightsBuffer [[buffer(2)]], device Tiles* tileLightId [[buffer(3)]], const constant Config* config [[buffer(0)]], const constant Uniforms* uniforms [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.lightsBuffer=lightsBuffer, .tileLightId=tileLightId, .config=config, .uniforms=uniforms};
+kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], device LightsBuffer_packed_vec3* lightsBuffer [[buffer(2)]], device Tiles* tileLightId [[buffer(3)]], const constant Config* config [[buffer(0)]], const constant Uniforms* uniforms [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.lightsBuffer=lightsBuffer, .tileLightId=tileLightId, .config=config, .uniforms=uniforms, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/1121.wgsl.expected.msl b/test/tint/bug/tint/1121.wgsl.expected.msl
index 339e957..bce5a25 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.msl
+++ b/test/tint/bug/tint/1121.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct LightData_tint_packed_vec3 {
   /* 0x0000 */ float4 position;
   /* 0x0010 */ packed_float3 color;
@@ -24,6 +27,10 @@
   /* 0x0000 */ tint_array<LightData_tint_packed_vec3, 1> lights;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct LightData {
   float4 position;
   float3 color;
@@ -60,22 +67,22 @@
   /* 0x00a0 */ float4 fullScreenSize;
 };
 
-void tint_symbol_inner(uint3 GlobalInvocationID, const constant Config* const tint_symbol_1, device LightsBuffer_tint_packed_vec3* const tint_symbol_2, const constant Uniforms* const tint_symbol_3, device Tiles* const tint_symbol_4) {
+void tint_symbol_inner(uint3 GlobalInvocationID, const constant Config* const tint_symbol_1, device LightsBuffer_tint_packed_vec3* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3, const constant Uniforms* const tint_symbol_4, device Tiles* const tint_symbol_5) {
   uint index = GlobalInvocationID[0];
   if ((index >= (*(tint_symbol_1)).numLights)) {
     return;
   }
-  (*(tint_symbol_2)).lights[index].position[1] = (((*(tint_symbol_2)).lights[index].position[1] - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))));
-  if (((*(tint_symbol_2)).lights[index].position[1] < (*(tint_symbol_3)).min[1])) {
-    (*(tint_symbol_2)).lights[index].position[1] = (*(tint_symbol_3)).max[1];
+  (*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].position[1] = (((*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].position[1] - 0.10000000149011611938f) + (0.00100000004749745131f * (float(index) - (64.0f * floor((float(index) / 64.0f))))));
+  if (((*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].position[1] < (*(tint_symbol_4)).min[1])) {
+    (*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].position[1] = (*(tint_symbol_4)).max[1];
   }
-  float4x4 M = (*(tint_symbol_3)).projectionMatrix;
+  float4x4 M = (*(tint_symbol_4)).projectionMatrix;
   float viewNear = (-(M[3][2]) / (-1.0f + M[2][2]));
   float viewFar = (-(M[3][2]) / (1.0f + M[2][2]));
-  float4 lightPos = (*(tint_symbol_2)).lights[index].position;
-  lightPos = ((*(tint_symbol_3)).viewMatrix * lightPos);
+  float4 lightPos = (*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].position;
+  lightPos = ((*(tint_symbol_4)).viewMatrix * lightPos);
   lightPos = (lightPos / lightPos[3]);
-  float lightRadius = (*(tint_symbol_2)).lights[index].radius;
+  float lightRadius = (*(tint_symbol_2)).lights[min(index, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].radius;
   float4 boxMin = (lightPos - float4(float3(lightRadius), 0.0f));
   float4 boxMax = (lightPos + float4(float3(lightRadius), 0.0f));
   tint_array<float4, 6> frustumPlanes = {};
@@ -85,10 +92,12 @@
   int const TILE_COUNT_X = 2;
   int const TILE_COUNT_Y = 2;
   for(int y = 0; (y < TILE_COUNT_Y); y = as_type<int>((as_type<uint>(y) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     for(int x = 0; (x < TILE_COUNT_X); x = as_type<int>((as_type<uint>(x) + as_type<uint>(1)))) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       int2 tilePixel0Idx = int2(as_type<int>((as_type<uint>(x) * as_type<uint>(TILE_SIZE))), as_type<int>((as_type<uint>(y) * as_type<uint>(TILE_SIZE))));
-      float2 floorCoord = (((2.0f * float2(tilePixel0Idx)) / (*(tint_symbol_3)).fullScreenSize.xy) - float2(1.0f));
-      float2 ceilCoord = (((2.0f * float2(as_type<int2>((as_type<uint2>(tilePixel0Idx) + as_type<uint2>(int2(TILE_SIZE)))))) / (*(tint_symbol_3)).fullScreenSize.xy) - float2(1.0f));
+      float2 floorCoord = (((2.0f * float2(tilePixel0Idx)) / (*(tint_symbol_4)).fullScreenSize.xy) - float2(1.0f));
+      float2 ceilCoord = (((2.0f * float2(as_type<int2>((as_type<uint2>(tilePixel0Idx) + as_type<uint2>(int2(TILE_SIZE)))))) / (*(tint_symbol_4)).fullScreenSize.xy) - float2(1.0f));
       float2 viewFloorCoord = float2((((-(viewNear) * floorCoord[0]) - (M[2][0] * viewNear)) / M[0][0]), (((-(viewNear) * floorCoord[1]) - (M[2][1] * viewNear)) / M[1][1]));
       float2 viewCeilCoord = float2((((-(viewNear) * ceilCoord[0]) - (M[2][0] * viewNear)) / M[0][0]), (((-(viewNear) * ceilCoord[1]) - (M[2][1] * viewNear)) / M[1][1]));
       frustumPlanes[0] = float4(1.0f, 0.0f, (-(viewFloorCoord[0]) / viewNear), 0.0f);
@@ -97,42 +106,43 @@
       frustumPlanes[3] = float4(0.0f, -1.0f, (viewCeilCoord[1] / viewNear), 0.0f);
       float dp = 0.0f;
       for(uint i = 0u; (i < 6u); i = (i + 1u)) {
+        TINT_ISOLATE_UB(tint_volatile_false_2);
         float4 p = 0.0f;
-        if ((frustumPlanes[i][0] > 0.0f)) {
+        if ((frustumPlanes[min(i, 5u)][0] > 0.0f)) {
           p[0] = boxMax[0];
         } else {
           p[0] = boxMin[0];
         }
-        if ((frustumPlanes[i][1] > 0.0f)) {
+        if ((frustumPlanes[min(i, 5u)][1] > 0.0f)) {
           p[1] = boxMax[1];
         } else {
           p[1] = boxMin[1];
         }
-        if ((frustumPlanes[i][2] > 0.0f)) {
+        if ((frustumPlanes[min(i, 5u)][2] > 0.0f)) {
           p[2] = boxMax[2];
         } else {
           p[2] = boxMin[2];
         }
         p[3] = 1.0f;
-        dp = (dp + fmin(0.0f, dot(p, frustumPlanes[i])));
+        dp = (dp + fmin(0.0f, dot(p, frustumPlanes[min(i, 5u)])));
       }
       if ((dp >= 0.0f)) {
         uint tileId = uint(as_type<int>((as_type<uint>(x) + as_type<uint>(as_type<int>((as_type<uint>(y) * as_type<uint>(TILE_COUNT_X)))))));
         if (((tileId < 0u) || (tileId >= (*(tint_symbol_1)).numTiles))) {
           continue;
         }
-        uint offset = atomic_fetch_add_explicit(&((*(tint_symbol_4)).data[tileId].count), 1u, memory_order_relaxed);
+        uint offset = atomic_fetch_add_explicit(&((*(tint_symbol_5)).data[min(tileId, 3u)].count), 1u, memory_order_relaxed);
         if ((offset >= (*(tint_symbol_1)).numTileLightSlot)) {
           continue;
         }
-        (*(tint_symbol_4)).data[tileId].lightId[offset] = GlobalInvocationID[0];
+        (*(tint_symbol_5)).data[min(tileId, 3u)].lightId[min(offset, 63u)] = GlobalInvocationID[0];
       }
     }
   }
 }
 
-kernel void tint_symbol(const constant Config* tint_symbol_5 [[buffer(0)]], device LightsBuffer_tint_packed_vec3* tint_symbol_6 [[buffer(2)]], const constant Uniforms* tint_symbol_7 [[buffer(1)]], device Tiles* tint_symbol_8 [[buffer(3)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  tint_symbol_inner(GlobalInvocationID, tint_symbol_5, tint_symbol_6, tint_symbol_7, tint_symbol_8);
+kernel void tint_symbol(const constant Config* tint_symbol_6 [[buffer(0)]], device LightsBuffer_tint_packed_vec3* tint_symbol_7 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_8 [[buffer(30)]], const constant Uniforms* tint_symbol_9 [[buffer(1)]], device Tiles* tint_symbol_10 [[buffer(3)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  tint_symbol_inner(GlobalInvocationID, tint_symbol_6, tint_symbol_7, tint_symbol_8, tint_symbol_9, tint_symbol_10);
   return;
 }
 
diff --git a/test/tint/bug/tint/1121.wgsl.expected.spvasm b/test/tint/bug/tint/1121.wgsl.expected.spvasm
index c2d93af..0180203 100644
--- a/test/tint/bug/tint/1121.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1121.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 429
+; Bound: 460
 ; Schema: 0
                OpCapability Shader
-         %66 = OpExtInstImport "GLSL.std.450"
+         %55 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_global_invocation_id_Input
                OpExecutionMode %main LocalSize 64 1 1
@@ -149,9 +149,10 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
        %bool = OpTypeBool
+%_ptr_StorageBuffer__runtimearr_LightData = OpTypePointer StorageBuffer %_runtimearr_LightData
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_1 = OpConstant %uint 1
 %float_0_100000001 = OpConstant %float 0.100000001
    %float_64 = OpConstant %float 64
 %float_0_00100000005 = OpConstant %float 0.00100000005
@@ -161,35 +162,34 @@
      %uint_3 = OpConstant %uint 3
 %_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-        %int = OpTypeInt 32 1
-      %int_3 = OpConstant %int 3
 %_ptr_Function_float = OpTypePointer Function %float
-%TILE_COUNT_X = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
    %float_n1 = OpConstant %float -1
     %float_1 = OpConstant %float 1
-     %uint_2 = OpConstant %uint 2
     %float_0 = OpConstant %float 0
      %uint_6 = OpConstant %uint 6
 %_arr_v4float_uint_6 = OpTypeArray %v4float %uint_6
 %_ptr_Function__arr_v4float_uint_6 = OpTypePointer Function %_arr_v4float_uint_6
-        %159 = OpConstantNull %_arr_v4float_uint_6
-      %int_4 = OpConstant %int 4
-      %int_5 = OpConstant %int 5
+        %181 = OpConstantNull %_arr_v4float_uint_6
+     %uint_5 = OpConstant %uint 5
+        %int = OpTypeInt 32 1
   %TILE_SIZE = OpConstant %int 16
+%TILE_COUNT_X = OpConstant %int 2
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
       %v2int = OpTypeVector %int 2
 %_ptr_Function_v2int = OpTypePointer Function %v2int
     %v2float = OpTypeVector %float 2
     %float_2 = OpConstant %float 2
-        %210 = OpConstantComposite %v2float %float_1 %float_1
+        %233 = OpConstantComposite %v2float %float_1 %float_1
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_1 = OpConstant %int 1
-        %327 = OpConstantNull %v4float
+        %349 = OpConstantNull %v4float
        %true = OpConstantTrue %bool
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+    %uint_63 = OpConstant %uint 63
 %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
-        %425 = OpTypeFunction %void
+      %int_1 = OpConstant %int 1
+        %456 = OpTypeFunction %void
  %main_inner = OpFunction %void None %34
 %GlobalInvocationID = OpFunctionParameter %v3uint
          %35 = OpLabel
@@ -201,7 +201,7 @@
 %lightRadius = OpVariable %_ptr_Function_float Function
      %boxMin = OpVariable %_ptr_Function_v4float Function
      %boxMax = OpVariable %_ptr_Function_v4float Function
-%frustumPlanes = OpVariable %_ptr_Function__arr_v4float_uint_6 Function %159
+%frustumPlanes = OpVariable %_ptr_Function__arr_v4float_uint_6 Function %181
           %y = OpVariable %_ptr_Function_int Function
           %x = OpVariable %_ptr_Function_int Function
 %tilePixel0Idx = OpVariable %_ptr_Function_v2int Function
@@ -211,7 +211,7 @@
 %viewCeilCoord = OpVariable %_ptr_Function_v2float Function
          %dp = OpVariable %_ptr_Function_float Function
           %i = OpVariable %_ptr_Function_uint Function
-          %p = OpVariable %_ptr_Function_v4float Function %327
+          %p = OpVariable %_ptr_Function_v4float Function %349
      %tileId = OpVariable %_ptr_Function_uint Function
      %offset = OpVariable %_ptr_Function_uint Function
          %36 = OpCompositeExtract %uint %GlobalInvocationID 0
@@ -226,420 +226,451 @@
                OpReturn
          %46 = OpLabel
          %48 = OpLoad %uint %index None
-         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %48 %uint_0
-         %51 = OpLoad %uint %index None
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %51 %uint_0
-         %53 = OpAccessChain %_ptr_StorageBuffer_float %52 %uint_1
-         %56 = OpLoad %float %53 None
-         %57 = OpFSub %float %56 %float_0_100000001
-         %59 = OpLoad %uint %index None
-         %60 = OpConvertUToF %float %59
-         %61 = OpLoad %uint %index None
-         %62 = OpConvertUToF %float %61
-         %63 = OpFDiv %float %62 %float_64
-         %65 = OpExtInst %float %66 Floor %63
-         %67 = OpFMul %float %float_64 %65
-         %68 = OpFSub %float %60 %67
-         %69 = OpFMul %float %float_0_00100000005 %68
-         %71 = OpFAdd %float %57 %69
-         %72 = OpAccessChain %_ptr_StorageBuffer_float %49 %uint_1
-               OpStore %72 %71 None
-         %73 = OpLoad %uint %index None
-         %74 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %73 %uint_0
-         %75 = OpAccessChain %_ptr_StorageBuffer_float %74 %uint_1
-         %76 = OpLoad %float %75 None
-         %77 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_0
-         %79 = OpAccessChain %_ptr_Uniform_float %77 %uint_1
-         %81 = OpLoad %float %79 None
-         %82 = OpFOrdLessThan %bool %76 %81
-               OpSelectionMerge %83 None
-               OpBranchConditional %82 %84 %83
-         %84 = OpLabel
-         %85 = OpLoad %uint %index None
-         %86 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %85 %uint_0
-         %87 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_1
-         %88 = OpAccessChain %_ptr_Uniform_float %87 %uint_1
+         %49 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+         %51 = OpArrayLength %uint %lightsBuffer 0
+         %52 = OpISub %uint %51 %uint_1
+         %54 = OpExtInst %uint %55 UMin %48 %52
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %54 %uint_0
+         %58 = OpLoad %uint %index None
+         %59 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+         %60 = OpArrayLength %uint %lightsBuffer 0
+         %61 = OpISub %uint %60 %uint_1
+         %62 = OpExtInst %uint %55 UMin %58 %61
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %62 %uint_0
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %63 %uint_1
+         %66 = OpLoad %float %64 None
+         %67 = OpFSub %float %66 %float_0_100000001
+         %69 = OpLoad %uint %index None
+         %70 = OpConvertUToF %float %69
+         %71 = OpLoad %uint %index None
+         %72 = OpConvertUToF %float %71
+         %73 = OpFDiv %float %72 %float_64
+         %75 = OpExtInst %float %55 Floor %73
+         %76 = OpFMul %float %float_64 %75
+         %77 = OpFSub %float %70 %76
+         %78 = OpFMul %float %float_0_00100000005 %77
+         %80 = OpFAdd %float %67 %78
+         %81 = OpAccessChain %_ptr_StorageBuffer_float %56 %uint_1
+               OpStore %81 %80 None
+         %82 = OpLoad %uint %index None
+         %83 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+         %84 = OpArrayLength %uint %lightsBuffer 0
+         %85 = OpISub %uint %84 %uint_1
+         %86 = OpExtInst %uint %55 UMin %82 %85
+         %87 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %86 %uint_0
+         %88 = OpAccessChain %_ptr_StorageBuffer_float %87 %uint_1
          %89 = OpLoad %float %88 None
-         %90 = OpAccessChain %_ptr_StorageBuffer_float %86 %uint_1
-               OpStore %90 %89 None
-               OpBranch %83
-         %83 = OpLabel
-         %91 = OpAccessChain %_ptr_Uniform_mat4v4float %23 %uint_0 %uint_3
-         %94 = OpLoad %mat4v4float %91 None
-               OpStore %M %94
-         %97 = OpAccessChain %_ptr_Function_v4float %M %int_3
-        %101 = OpAccessChain %_ptr_Function_float %97 %TILE_COUNT_X
-        %104 = OpLoad %float %101 None
-        %105 = OpFNegate %float %104
-        %106 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %107 = OpAccessChain %_ptr_Function_float %106 %TILE_COUNT_X
-        %108 = OpLoad %float %107 None
-        %109 = OpFAdd %float %float_n1 %108
-        %111 = OpFDiv %float %105 %109
-               OpStore %viewNear %111
-        %113 = OpAccessChain %_ptr_Function_v4float %M %int_3
-        %114 = OpAccessChain %_ptr_Function_float %113 %TILE_COUNT_X
-        %115 = OpLoad %float %114 None
-        %116 = OpFNegate %float %115
-        %117 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %118 = OpAccessChain %_ptr_Function_float %117 %TILE_COUNT_X
-        %119 = OpLoad %float %118 None
-        %120 = OpFAdd %float %float_1 %119
-        %122 = OpFDiv %float %116 %120
-               OpStore %viewFar %122
-        %124 = OpLoad %uint %index None
-        %125 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %124 %uint_0
-        %126 = OpLoad %v4float %125 None
-               OpStore %lightPos %126
-        %128 = OpAccessChain %_ptr_Uniform_mat4v4float %23 %uint_0 %uint_2
-        %130 = OpLoad %mat4v4float %128 None
-        %131 = OpLoad %v4float %lightPos None
-        %132 = OpMatrixTimesVector %v4float %130 %131
-               OpStore %lightPos %132 None
-        %133 = OpLoad %v4float %lightPos None
-        %134 = OpAccessChain %_ptr_Function_float %lightPos %uint_3
-        %135 = OpLoad %float %134 None
-        %136 = OpCompositeConstruct %v4float %135 %135 %135 %135
-        %137 = OpFDiv %v4float %133 %136
-               OpStore %lightPos %137 None
-        %138 = OpLoad %uint %index None
-        %139 = OpAccessChain %_ptr_StorageBuffer_float %lightsBuffer %uint_0 %138 %uint_2
-        %140 = OpLoad %float %139 None
-               OpStore %lightRadius %140
-        %142 = OpLoad %v4float %lightPos None
-        %143 = OpLoad %float %lightRadius None
-        %144 = OpCompositeConstruct %v3float %143 %143 %143
-        %145 = OpCompositeConstruct %v4float %144 %float_0
-        %147 = OpFSub %v4float %142 %145
-               OpStore %boxMin %147
+         %90 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_0
+         %92 = OpAccessChain %_ptr_Uniform_float %90 %uint_1
+         %94 = OpLoad %float %92 None
+         %95 = OpFOrdLessThan %bool %89 %94
+               OpSelectionMerge %96 None
+               OpBranchConditional %95 %97 %96
+         %97 = OpLabel
+         %98 = OpLoad %uint %index None
+         %99 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+        %100 = OpArrayLength %uint %lightsBuffer 0
+        %101 = OpISub %uint %100 %uint_1
+        %102 = OpExtInst %uint %55 UMin %98 %101
+        %103 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %102 %uint_0
+        %104 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_1
+        %105 = OpAccessChain %_ptr_Uniform_float %104 %uint_1
+        %106 = OpLoad %float %105 None
+        %107 = OpAccessChain %_ptr_StorageBuffer_float %103 %uint_1
+               OpStore %107 %106 None
+               OpBranch %96
+         %96 = OpLabel
+        %108 = OpAccessChain %_ptr_Uniform_mat4v4float %23 %uint_0 %uint_3
+        %111 = OpLoad %mat4v4float %108 None
+               OpStore %M %111
+        %114 = OpAccessChain %_ptr_Function_v4float %M %uint_3
+        %116 = OpAccessChain %_ptr_Function_float %114 %uint_2
+        %119 = OpLoad %float %116 None
+        %120 = OpFNegate %float %119
+        %121 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %122 = OpAccessChain %_ptr_Function_float %121 %uint_2
+        %123 = OpLoad %float %122 None
+        %124 = OpFAdd %float %float_n1 %123
+        %126 = OpFDiv %float %120 %124
+               OpStore %viewNear %126
+        %128 = OpAccessChain %_ptr_Function_v4float %M %uint_3
+        %129 = OpAccessChain %_ptr_Function_float %128 %uint_2
+        %130 = OpLoad %float %129 None
+        %131 = OpFNegate %float %130
+        %132 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %133 = OpAccessChain %_ptr_Function_float %132 %uint_2
+        %134 = OpLoad %float %133 None
+        %135 = OpFAdd %float %float_1 %134
+        %137 = OpFDiv %float %131 %135
+               OpStore %viewFar %137
+        %139 = OpLoad %uint %index None
+        %140 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+        %141 = OpArrayLength %uint %lightsBuffer 0
+        %142 = OpISub %uint %141 %uint_1
+        %143 = OpExtInst %uint %55 UMin %139 %142
+        %144 = OpAccessChain %_ptr_StorageBuffer_v4float %lightsBuffer %uint_0 %143 %uint_0
+        %145 = OpLoad %v4float %144 None
+               OpStore %lightPos %145
+        %147 = OpAccessChain %_ptr_Uniform_mat4v4float %23 %uint_0 %uint_2
+        %148 = OpLoad %mat4v4float %147 None
         %149 = OpLoad %v4float %lightPos None
-        %150 = OpLoad %float %lightRadius None
-        %151 = OpCompositeConstruct %v3float %150 %150 %150
-        %152 = OpCompositeConstruct %v4float %151 %float_0
-        %153 = OpFAdd %v4float %149 %152
-               OpStore %boxMax %153
-        %160 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %int_4
-        %162 = OpLoad %float %viewNear None
-        %163 = OpCompositeConstruct %v4float %float_0 %float_0 %float_n1 %162
-               OpStore %160 %163 None
-        %164 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %int_5
-        %166 = OpLoad %float %viewFar None
-        %167 = OpFNegate %float %166
-        %168 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %167
-               OpStore %164 %168 None
-               OpBranch %170
-        %170 = OpLabel
+        %150 = OpMatrixTimesVector %v4float %148 %149
+               OpStore %lightPos %150 None
+        %151 = OpLoad %v4float %lightPos None
+        %152 = OpAccessChain %_ptr_Function_float %lightPos %uint_3
+        %153 = OpLoad %float %152 None
+        %154 = OpCompositeConstruct %v4float %153 %153 %153 %153
+        %155 = OpFDiv %v4float %151 %154
+               OpStore %lightPos %155 None
+        %156 = OpLoad %uint %index None
+        %157 = OpAccessChain %_ptr_StorageBuffer__runtimearr_LightData %lightsBuffer %uint_0
+        %158 = OpArrayLength %uint %lightsBuffer 0
+        %159 = OpISub %uint %158 %uint_1
+        %160 = OpExtInst %uint %55 UMin %156 %159
+        %161 = OpAccessChain %_ptr_StorageBuffer_float %lightsBuffer %uint_0 %160 %uint_2
+        %162 = OpLoad %float %161 None
+               OpStore %lightRadius %162
+        %164 = OpLoad %v4float %lightPos None
+        %165 = OpLoad %float %lightRadius None
+        %166 = OpCompositeConstruct %v3float %165 %165 %165
+        %167 = OpCompositeConstruct %v4float %166 %float_0
+        %169 = OpFSub %v4float %164 %167
+               OpStore %boxMin %169
+        %171 = OpLoad %v4float %lightPos None
+        %172 = OpLoad %float %lightRadius None
+        %173 = OpCompositeConstruct %v3float %172 %172 %172
+        %174 = OpCompositeConstruct %v4float %173 %float_0
+        %175 = OpFAdd %v4float %171 %174
+               OpStore %boxMax %175
+        %182 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_4
+        %183 = OpLoad %float %viewNear None
+        %184 = OpCompositeConstruct %v4float %float_0 %float_0 %float_n1 %183
+               OpStore %182 %184 None
+        %185 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_5
+        %187 = OpLoad %float %viewFar None
+        %188 = OpFNegate %float %187
+        %189 = OpCompositeConstruct %v4float %float_0 %float_0 %float_1 %188
+               OpStore %185 %189 None
+               OpBranch %193
+        %193 = OpLabel
                OpStore %y %int_0
-               OpBranch %173
-        %173 = OpLabel
-               OpLoopMerge %174 %172 None
-               OpBranch %171
-        %171 = OpLabel
-        %178 = OpLoad %int %y None
-        %179 = OpSLessThan %bool %178 %TILE_COUNT_X
-               OpSelectionMerge %180 None
-               OpBranchConditional %179 %180 %181
-        %181 = OpLabel
-               OpBranch %174
-        %180 = OpLabel
-               OpBranch %182
-        %182 = OpLabel
+               OpBranch %196
+        %196 = OpLabel
+               OpLoopMerge %197 %195 None
+               OpBranch %194
+        %194 = OpLabel
+        %201 = OpLoad %int %y None
+        %202 = OpSLessThan %bool %201 %TILE_COUNT_X
+               OpSelectionMerge %203 None
+               OpBranchConditional %202 %203 %204
+        %204 = OpLabel
+               OpBranch %197
+        %203 = OpLabel
+               OpBranch %205
+        %205 = OpLabel
                OpStore %x %int_0
-               OpBranch %185
-        %185 = OpLabel
-               OpLoopMerge %186 %184 None
-               OpBranch %183
-        %183 = OpLabel
-        %188 = OpLoad %int %x None
-        %189 = OpSLessThan %bool %188 %TILE_COUNT_X
-               OpSelectionMerge %190 None
-               OpBranchConditional %189 %190 %191
-        %191 = OpLabel
-               OpBranch %186
-        %190 = OpLabel
-        %192 = OpLoad %int %x None
-        %193 = OpIMul %int %192 %TILE_SIZE
-        %194 = OpLoad %int %y None
-        %195 = OpIMul %int %194 %TILE_SIZE
-        %197 = OpCompositeConstruct %v2int %193 %195
-               OpStore %tilePixel0Idx %197
-        %200 = OpLoad %v2int %tilePixel0Idx None
-        %202 = OpConvertSToF %v2float %200
-        %203 = OpVectorTimesScalar %v2float %202 %float_2
-        %205 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_4
-        %206 = OpLoad %v4float %205 None
-        %207 = OpVectorShuffle %v2float %206 %206 0 1
-        %208 = OpFDiv %v2float %203 %207
-        %209 = OpFSub %v2float %208 %210
-               OpStore %floorCoord %209
-        %213 = OpLoad %v2int %tilePixel0Idx None
-        %214 = OpCompositeConstruct %v2int %TILE_SIZE %TILE_SIZE
-        %215 = OpIAdd %v2int %213 %214
-        %216 = OpConvertSToF %v2float %215
-        %217 = OpVectorTimesScalar %v2float %216 %float_2
-        %218 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_4
-        %219 = OpLoad %v4float %218 None
-        %220 = OpVectorShuffle %v2float %219 %219 0 1
-        %221 = OpFDiv %v2float %217 %220
-        %222 = OpFSub %v2float %221 %210
-               OpStore %ceilCoord %222
-        %224 = OpLoad %float %viewNear None
-        %225 = OpFNegate %float %224
-        %226 = OpAccessChain %_ptr_Function_float %floorCoord %uint_0
-        %227 = OpLoad %float %226 None
-        %228 = OpFMul %float %225 %227
-        %229 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %230 = OpAccessChain %_ptr_Function_float %229 %int_0
-        %231 = OpLoad %float %230 None
-        %232 = OpLoad %float %viewNear None
-        %233 = OpFMul %float %231 %232
-        %234 = OpFSub %float %228 %233
-        %235 = OpAccessChain %_ptr_Function_v4float %M %int_0
-        %236 = OpAccessChain %_ptr_Function_float %235 %int_0
-        %237 = OpLoad %float %236 None
-        %238 = OpFDiv %float %234 %237
-        %239 = OpLoad %float %viewNear None
-        %240 = OpFNegate %float %239
-        %241 = OpAccessChain %_ptr_Function_float %floorCoord %uint_1
-        %242 = OpLoad %float %241 None
-        %243 = OpFMul %float %240 %242
-        %244 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %245 = OpAccessChain %_ptr_Function_float %244 %int_1
-        %247 = OpLoad %float %245 None
-        %248 = OpLoad %float %viewNear None
-        %249 = OpFMul %float %247 %248
-        %250 = OpFSub %float %243 %249
-        %251 = OpAccessChain %_ptr_Function_v4float %M %int_1
-        %252 = OpAccessChain %_ptr_Function_float %251 %int_1
-        %253 = OpLoad %float %252 None
-        %254 = OpFDiv %float %250 %253
-        %255 = OpCompositeConstruct %v2float %238 %254
-               OpStore %viewFloorCoord %255
-        %257 = OpLoad %float %viewNear None
-        %258 = OpFNegate %float %257
-        %259 = OpAccessChain %_ptr_Function_float %ceilCoord %uint_0
+               OpBranch %208
+        %208 = OpLabel
+               OpLoopMerge %209 %207 None
+               OpBranch %206
+        %206 = OpLabel
+        %211 = OpLoad %int %x None
+        %212 = OpSLessThan %bool %211 %TILE_COUNT_X
+               OpSelectionMerge %213 None
+               OpBranchConditional %212 %213 %214
+        %214 = OpLabel
+               OpBranch %209
+        %213 = OpLabel
+        %215 = OpLoad %int %x None
+        %216 = OpIMul %int %215 %TILE_SIZE
+        %217 = OpLoad %int %y None
+        %218 = OpIMul %int %217 %TILE_SIZE
+        %220 = OpCompositeConstruct %v2int %216 %218
+               OpStore %tilePixel0Idx %220
+        %223 = OpLoad %v2int %tilePixel0Idx None
+        %225 = OpConvertSToF %v2float %223
+        %226 = OpVectorTimesScalar %v2float %225 %float_2
+        %228 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_4
+        %229 = OpLoad %v4float %228 None
+        %230 = OpVectorShuffle %v2float %229 %229 0 1
+        %231 = OpFDiv %v2float %226 %230
+        %232 = OpFSub %v2float %231 %233
+               OpStore %floorCoord %232
+        %236 = OpLoad %v2int %tilePixel0Idx None
+        %237 = OpCompositeConstruct %v2int %TILE_SIZE %TILE_SIZE
+        %238 = OpIAdd %v2int %236 %237
+        %239 = OpConvertSToF %v2float %238
+        %240 = OpVectorTimesScalar %v2float %239 %float_2
+        %241 = OpAccessChain %_ptr_Uniform_v4float %23 %uint_0 %uint_4
+        %242 = OpLoad %v4float %241 None
+        %243 = OpVectorShuffle %v2float %242 %242 0 1
+        %244 = OpFDiv %v2float %240 %243
+        %245 = OpFSub %v2float %244 %233
+               OpStore %ceilCoord %245
+        %247 = OpLoad %float %viewNear None
+        %248 = OpFNegate %float %247
+        %249 = OpAccessChain %_ptr_Function_float %floorCoord %uint_0
+        %250 = OpLoad %float %249 None
+        %251 = OpFMul %float %248 %250
+        %252 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %253 = OpAccessChain %_ptr_Function_float %252 %uint_0
+        %254 = OpLoad %float %253 None
+        %255 = OpLoad %float %viewNear None
+        %256 = OpFMul %float %254 %255
+        %257 = OpFSub %float %251 %256
+        %258 = OpAccessChain %_ptr_Function_v4float %M %uint_0
+        %259 = OpAccessChain %_ptr_Function_float %258 %uint_0
         %260 = OpLoad %float %259 None
-        %261 = OpFMul %float %258 %260
-        %262 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %263 = OpAccessChain %_ptr_Function_float %262 %int_0
-        %264 = OpLoad %float %263 None
-        %265 = OpLoad %float %viewNear None
-        %266 = OpFMul %float %264 %265
-        %267 = OpFSub %float %261 %266
-        %268 = OpAccessChain %_ptr_Function_v4float %M %int_0
-        %269 = OpAccessChain %_ptr_Function_float %268 %int_0
-        %270 = OpLoad %float %269 None
-        %271 = OpFDiv %float %267 %270
-        %272 = OpLoad %float %viewNear None
-        %273 = OpFNegate %float %272
-        %274 = OpAccessChain %_ptr_Function_float %ceilCoord %uint_1
+        %261 = OpFDiv %float %257 %260
+        %262 = OpLoad %float %viewNear None
+        %263 = OpFNegate %float %262
+        %264 = OpAccessChain %_ptr_Function_float %floorCoord %uint_1
+        %265 = OpLoad %float %264 None
+        %266 = OpFMul %float %263 %265
+        %267 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %268 = OpAccessChain %_ptr_Function_float %267 %uint_1
+        %269 = OpLoad %float %268 None
+        %270 = OpLoad %float %viewNear None
+        %271 = OpFMul %float %269 %270
+        %272 = OpFSub %float %266 %271
+        %273 = OpAccessChain %_ptr_Function_v4float %M %uint_1
+        %274 = OpAccessChain %_ptr_Function_float %273 %uint_1
         %275 = OpLoad %float %274 None
-        %276 = OpFMul %float %273 %275
-        %277 = OpAccessChain %_ptr_Function_v4float %M %TILE_COUNT_X
-        %278 = OpAccessChain %_ptr_Function_float %277 %int_1
-        %279 = OpLoad %float %278 None
-        %280 = OpLoad %float %viewNear None
-        %281 = OpFMul %float %279 %280
-        %282 = OpFSub %float %276 %281
-        %283 = OpAccessChain %_ptr_Function_v4float %M %int_1
-        %284 = OpAccessChain %_ptr_Function_float %283 %int_1
-        %285 = OpLoad %float %284 None
-        %286 = OpFDiv %float %282 %285
-        %287 = OpCompositeConstruct %v2float %271 %286
-               OpStore %viewCeilCoord %287
-        %289 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %int_0
-        %290 = OpAccessChain %_ptr_Function_float %viewFloorCoord %uint_0
-        %291 = OpLoad %float %290 None
-        %292 = OpFNegate %float %291
-        %293 = OpLoad %float %viewNear None
-        %294 = OpFDiv %float %292 %293
-        %295 = OpCompositeConstruct %v4float %float_1 %float_0 %294 %float_0
-               OpStore %289 %295 None
-        %296 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %int_1
-        %297 = OpAccessChain %_ptr_Function_float %viewCeilCoord %uint_0
-        %298 = OpLoad %float %297 None
-        %299 = OpLoad %float %viewNear None
-        %300 = OpFDiv %float %298 %299
-        %301 = OpCompositeConstruct %v4float %float_n1 %float_0 %300 %float_0
-               OpStore %296 %301 None
-        %302 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %TILE_COUNT_X
-        %303 = OpAccessChain %_ptr_Function_float %viewFloorCoord %uint_1
-        %304 = OpLoad %float %303 None
-        %305 = OpFNegate %float %304
-        %306 = OpLoad %float %viewNear None
-        %307 = OpFDiv %float %305 %306
-        %308 = OpCompositeConstruct %v4float %float_0 %float_1 %307 %float_0
-               OpStore %302 %308 None
-        %309 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %int_3
-        %310 = OpAccessChain %_ptr_Function_float %viewCeilCoord %uint_1
-        %311 = OpLoad %float %310 None
-        %312 = OpLoad %float %viewNear None
-        %313 = OpFDiv %float %311 %312
-        %314 = OpCompositeConstruct %v4float %float_0 %float_n1 %313 %float_0
-               OpStore %309 %314 None
+        %276 = OpFDiv %float %272 %275
+        %277 = OpCompositeConstruct %v2float %261 %276
+               OpStore %viewFloorCoord %277
+        %279 = OpLoad %float %viewNear None
+        %280 = OpFNegate %float %279
+        %281 = OpAccessChain %_ptr_Function_float %ceilCoord %uint_0
+        %282 = OpLoad %float %281 None
+        %283 = OpFMul %float %280 %282
+        %284 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %285 = OpAccessChain %_ptr_Function_float %284 %uint_0
+        %286 = OpLoad %float %285 None
+        %287 = OpLoad %float %viewNear None
+        %288 = OpFMul %float %286 %287
+        %289 = OpFSub %float %283 %288
+        %290 = OpAccessChain %_ptr_Function_v4float %M %uint_0
+        %291 = OpAccessChain %_ptr_Function_float %290 %uint_0
+        %292 = OpLoad %float %291 None
+        %293 = OpFDiv %float %289 %292
+        %294 = OpLoad %float %viewNear None
+        %295 = OpFNegate %float %294
+        %296 = OpAccessChain %_ptr_Function_float %ceilCoord %uint_1
+        %297 = OpLoad %float %296 None
+        %298 = OpFMul %float %295 %297
+        %299 = OpAccessChain %_ptr_Function_v4float %M %uint_2
+        %300 = OpAccessChain %_ptr_Function_float %299 %uint_1
+        %301 = OpLoad %float %300 None
+        %302 = OpLoad %float %viewNear None
+        %303 = OpFMul %float %301 %302
+        %304 = OpFSub %float %298 %303
+        %305 = OpAccessChain %_ptr_Function_v4float %M %uint_1
+        %306 = OpAccessChain %_ptr_Function_float %305 %uint_1
+        %307 = OpLoad %float %306 None
+        %308 = OpFDiv %float %304 %307
+        %309 = OpCompositeConstruct %v2float %293 %308
+               OpStore %viewCeilCoord %309
+        %311 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_0
+        %312 = OpAccessChain %_ptr_Function_float %viewFloorCoord %uint_0
+        %313 = OpLoad %float %312 None
+        %314 = OpFNegate %float %313
+        %315 = OpLoad %float %viewNear None
+        %316 = OpFDiv %float %314 %315
+        %317 = OpCompositeConstruct %v4float %float_1 %float_0 %316 %float_0
+               OpStore %311 %317 None
+        %318 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_1
+        %319 = OpAccessChain %_ptr_Function_float %viewCeilCoord %uint_0
+        %320 = OpLoad %float %319 None
+        %321 = OpLoad %float %viewNear None
+        %322 = OpFDiv %float %320 %321
+        %323 = OpCompositeConstruct %v4float %float_n1 %float_0 %322 %float_0
+               OpStore %318 %323 None
+        %324 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_2
+        %325 = OpAccessChain %_ptr_Function_float %viewFloorCoord %uint_1
+        %326 = OpLoad %float %325 None
+        %327 = OpFNegate %float %326
+        %328 = OpLoad %float %viewNear None
+        %329 = OpFDiv %float %327 %328
+        %330 = OpCompositeConstruct %v4float %float_0 %float_1 %329 %float_0
+               OpStore %324 %330 None
+        %331 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %uint_3
+        %332 = OpAccessChain %_ptr_Function_float %viewCeilCoord %uint_1
+        %333 = OpLoad %float %332 None
+        %334 = OpLoad %float %viewNear None
+        %335 = OpFDiv %float %333 %334
+        %336 = OpCompositeConstruct %v4float %float_0 %float_n1 %335 %float_0
+               OpStore %331 %336 None
                OpStore %dp %float_0
-               OpBranch %316
-        %316 = OpLabel
+               OpBranch %338
+        %338 = OpLabel
                OpStore %i %uint_0
-               OpBranch %319
-        %319 = OpLabel
-               OpLoopMerge %320 %318 None
-               OpBranch %317
-        %317 = OpLabel
-        %322 = OpLoad %uint %i None
-        %323 = OpULessThan %bool %322 %uint_6
-               OpSelectionMerge %324 None
-               OpBranchConditional %323 %324 %325
-        %325 = OpLabel
-               OpBranch %320
-        %324 = OpLabel
-        %328 = OpLoad %uint %i None
-        %329 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %328
-        %330 = OpAccessChain %_ptr_Function_float %329 %uint_0
-        %331 = OpLoad %float %330 None
-        %332 = OpFOrdGreaterThan %bool %331 %float_0
-               OpSelectionMerge %333 None
-               OpBranchConditional %332 %334 %335
-        %334 = OpLabel
-        %336 = OpAccessChain %_ptr_Function_float %boxMax %uint_0
-        %337 = OpLoad %float %336 None
-        %338 = OpAccessChain %_ptr_Function_float %p %uint_0
-               OpStore %338 %337 None
-               OpBranch %333
-        %335 = OpLabel
-        %339 = OpAccessChain %_ptr_Function_float %boxMin %uint_0
-        %340 = OpLoad %float %339 None
-        %341 = OpAccessChain %_ptr_Function_float %p %uint_0
-               OpStore %341 %340 None
-               OpBranch %333
-        %333 = OpLabel
-        %342 = OpLoad %uint %i None
-        %343 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %342
-        %344 = OpAccessChain %_ptr_Function_float %343 %uint_1
-        %345 = OpLoad %float %344 None
-        %346 = OpFOrdGreaterThan %bool %345 %float_0
-               OpSelectionMerge %347 None
-               OpBranchConditional %346 %348 %349
-        %348 = OpLabel
-        %350 = OpAccessChain %_ptr_Function_float %boxMax %uint_1
-        %351 = OpLoad %float %350 None
-        %352 = OpAccessChain %_ptr_Function_float %p %uint_1
-               OpStore %352 %351 None
-               OpBranch %347
-        %349 = OpLabel
-        %353 = OpAccessChain %_ptr_Function_float %boxMin %uint_1
-        %354 = OpLoad %float %353 None
-        %355 = OpAccessChain %_ptr_Function_float %p %uint_1
-               OpStore %355 %354 None
-               OpBranch %347
+               OpBranch %341
+        %341 = OpLabel
+               OpLoopMerge %342 %340 None
+               OpBranch %339
+        %339 = OpLabel
+        %344 = OpLoad %uint %i None
+        %345 = OpULessThan %bool %344 %uint_6
+               OpSelectionMerge %346 None
+               OpBranchConditional %345 %346 %347
         %347 = OpLabel
-        %356 = OpLoad %uint %i None
-        %357 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %356
-        %358 = OpAccessChain %_ptr_Function_float %357 %uint_2
-        %359 = OpLoad %float %358 None
-        %360 = OpFOrdGreaterThan %bool %359 %float_0
-               OpSelectionMerge %361 None
-               OpBranchConditional %360 %362 %363
-        %362 = OpLabel
-        %364 = OpAccessChain %_ptr_Function_float %boxMax %uint_2
-        %365 = OpLoad %float %364 None
-        %366 = OpAccessChain %_ptr_Function_float %p %uint_2
-               OpStore %366 %365 None
-               OpBranch %361
-        %363 = OpLabel
-        %367 = OpAccessChain %_ptr_Function_float %boxMin %uint_2
-        %368 = OpLoad %float %367 None
-        %369 = OpAccessChain %_ptr_Function_float %p %uint_2
-               OpStore %369 %368 None
-               OpBranch %361
-        %361 = OpLabel
-        %370 = OpAccessChain %_ptr_Function_float %p %uint_3
-               OpStore %370 %float_1 None
-        %371 = OpLoad %float %dp None
-        %372 = OpLoad %v4float %p None
-        %373 = OpLoad %uint %i None
-        %374 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %373
-        %375 = OpLoad %v4float %374 None
-        %376 = OpDot %float %372 %375
-        %377 = OpExtInst %float %66 FMin %float_0 %376
-        %378 = OpFAdd %float %371 %377
-               OpStore %dp %378 None
-               OpBranch %318
-        %318 = OpLabel
-        %379 = OpLoad %uint %i None
-        %380 = OpIAdd %uint %379 %uint_1
-               OpStore %i %380 None
-               OpBranch %319
-        %320 = OpLabel
-        %381 = OpLoad %float %dp None
-        %382 = OpFOrdGreaterThanEqual %bool %381 %float_0
-               OpSelectionMerge %383 None
-               OpBranchConditional %382 %384 %383
-        %384 = OpLabel
-        %385 = OpLoad %int %x None
-        %386 = OpLoad %int %y None
-        %387 = OpIMul %int %386 %TILE_COUNT_X
-        %388 = OpIAdd %int %385 %387
-        %389 = OpBitcast %uint %388
-               OpStore %tileId %389
-        %391 = OpLoad %uint %tileId None
-        %392 = OpULessThan %bool %391 %uint_0
-               OpSelectionMerge %393 None
-               OpBranchConditional %392 %394 %395
-        %394 = OpLabel
-               OpBranch %393
-        %395 = OpLabel
-        %396 = OpLoad %uint %tileId None
-        %397 = OpAccessChain %_ptr_Uniform_uint %19 %uint_0 %uint_1
-        %398 = OpLoad %uint %397 None
-        %399 = OpUGreaterThanEqual %bool %396 %398
-               OpBranch %393
-        %393 = OpLabel
-        %400 = OpPhi %bool %true %394 %399 %395
-               OpSelectionMerge %402 None
-               OpBranchConditional %400 %403 %402
-        %403 = OpLabel
-               OpBranch %184
-        %402 = OpLabel
-        %404 = OpLoad %uint %tileId None
-        %405 = OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0 %404 %uint_0
-        %407 = OpAtomicIAdd %uint %405 %uint_1 %uint_0 %uint_1
-               OpStore %offset %407
-        %409 = OpLoad %uint %offset None
-        %410 = OpAccessChain %_ptr_Uniform_uint %19 %uint_0 %uint_4
-        %411 = OpLoad %uint %410 None
-        %412 = OpUGreaterThanEqual %bool %409 %411
-               OpSelectionMerge %413 None
-               OpBranchConditional %412 %414 %413
-        %414 = OpLabel
-               OpBranch %184
-        %413 = OpLabel
-        %415 = OpLoad %uint %tileId None
-        %416 = OpLoad %uint %offset None
-        %417 = OpAccessChain %_ptr_StorageBuffer_uint_0 %9 %uint_0 %uint_0 %415 %uint_1 %416
-        %419 = OpCompositeExtract %uint %GlobalInvocationID 0
-               OpStore %417 %419 None
-               OpBranch %383
-        %383 = OpLabel
-               OpBranch %184
-        %184 = OpLabel
-        %420 = OpLoad %int %x None
-        %421 = OpIAdd %int %420 %int_1
-               OpStore %x %421 None
-               OpBranch %185
-        %186 = OpLabel
-               OpBranch %172
-        %172 = OpLabel
-        %422 = OpLoad %int %y None
-        %423 = OpIAdd %int %422 %int_1
-               OpStore %y %423 None
-               OpBranch %173
-        %174 = OpLabel
+               OpBranch %342
+        %346 = OpLabel
+        %350 = OpLoad %uint %i None
+        %351 = OpExtInst %uint %55 UMin %350 %uint_5
+        %352 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %351
+        %353 = OpAccessChain %_ptr_Function_float %352 %uint_0
+        %354 = OpLoad %float %353 None
+        %355 = OpFOrdGreaterThan %bool %354 %float_0
+               OpSelectionMerge %356 None
+               OpBranchConditional %355 %357 %358
+        %357 = OpLabel
+        %359 = OpAccessChain %_ptr_Function_float %boxMax %uint_0
+        %360 = OpLoad %float %359 None
+        %361 = OpAccessChain %_ptr_Function_float %p %uint_0
+               OpStore %361 %360 None
+               OpBranch %356
+        %358 = OpLabel
+        %362 = OpAccessChain %_ptr_Function_float %boxMin %uint_0
+        %363 = OpLoad %float %362 None
+        %364 = OpAccessChain %_ptr_Function_float %p %uint_0
+               OpStore %364 %363 None
+               OpBranch %356
+        %356 = OpLabel
+        %365 = OpLoad %uint %i None
+        %366 = OpExtInst %uint %55 UMin %365 %uint_5
+        %367 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %366
+        %368 = OpAccessChain %_ptr_Function_float %367 %uint_1
+        %369 = OpLoad %float %368 None
+        %370 = OpFOrdGreaterThan %bool %369 %float_0
+               OpSelectionMerge %371 None
+               OpBranchConditional %370 %372 %373
+        %372 = OpLabel
+        %374 = OpAccessChain %_ptr_Function_float %boxMax %uint_1
+        %375 = OpLoad %float %374 None
+        %376 = OpAccessChain %_ptr_Function_float %p %uint_1
+               OpStore %376 %375 None
+               OpBranch %371
+        %373 = OpLabel
+        %377 = OpAccessChain %_ptr_Function_float %boxMin %uint_1
+        %378 = OpLoad %float %377 None
+        %379 = OpAccessChain %_ptr_Function_float %p %uint_1
+               OpStore %379 %378 None
+               OpBranch %371
+        %371 = OpLabel
+        %380 = OpLoad %uint %i None
+        %381 = OpExtInst %uint %55 UMin %380 %uint_5
+        %382 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %381
+        %383 = OpAccessChain %_ptr_Function_float %382 %uint_2
+        %384 = OpLoad %float %383 None
+        %385 = OpFOrdGreaterThan %bool %384 %float_0
+               OpSelectionMerge %386 None
+               OpBranchConditional %385 %387 %388
+        %387 = OpLabel
+        %389 = OpAccessChain %_ptr_Function_float %boxMax %uint_2
+        %390 = OpLoad %float %389 None
+        %391 = OpAccessChain %_ptr_Function_float %p %uint_2
+               OpStore %391 %390 None
+               OpBranch %386
+        %388 = OpLabel
+        %392 = OpAccessChain %_ptr_Function_float %boxMin %uint_2
+        %393 = OpLoad %float %392 None
+        %394 = OpAccessChain %_ptr_Function_float %p %uint_2
+               OpStore %394 %393 None
+               OpBranch %386
+        %386 = OpLabel
+        %395 = OpAccessChain %_ptr_Function_float %p %uint_3
+               OpStore %395 %float_1 None
+        %396 = OpLoad %float %dp None
+        %397 = OpLoad %v4float %p None
+        %398 = OpLoad %uint %i None
+        %399 = OpExtInst %uint %55 UMin %398 %uint_5
+        %400 = OpAccessChain %_ptr_Function_v4float %frustumPlanes %399
+        %401 = OpLoad %v4float %400 None
+        %402 = OpDot %float %397 %401
+        %403 = OpExtInst %float %55 FMin %float_0 %402
+        %404 = OpFAdd %float %396 %403
+               OpStore %dp %404 None
+               OpBranch %340
+        %340 = OpLabel
+        %405 = OpLoad %uint %i None
+        %406 = OpIAdd %uint %405 %uint_1
+               OpStore %i %406 None
+               OpBranch %341
+        %342 = OpLabel
+        %407 = OpLoad %float %dp None
+        %408 = OpFOrdGreaterThanEqual %bool %407 %float_0
+               OpSelectionMerge %409 None
+               OpBranchConditional %408 %410 %409
+        %410 = OpLabel
+        %411 = OpLoad %int %x None
+        %412 = OpLoad %int %y None
+        %413 = OpIMul %int %412 %TILE_COUNT_X
+        %414 = OpIAdd %int %411 %413
+        %415 = OpBitcast %uint %414
+               OpStore %tileId %415
+        %417 = OpLoad %uint %tileId None
+        %418 = OpULessThan %bool %417 %uint_0
+               OpSelectionMerge %419 None
+               OpBranchConditional %418 %420 %421
+        %420 = OpLabel
+               OpBranch %419
+        %421 = OpLabel
+        %422 = OpLoad %uint %tileId None
+        %423 = OpAccessChain %_ptr_Uniform_uint %19 %uint_0 %uint_1
+        %424 = OpLoad %uint %423 None
+        %425 = OpUGreaterThanEqual %bool %422 %424
+               OpBranch %419
+        %419 = OpLabel
+        %426 = OpPhi %bool %true %420 %425 %421
+               OpSelectionMerge %428 None
+               OpBranchConditional %426 %429 %428
+        %429 = OpLabel
+               OpBranch %207
+        %428 = OpLabel
+        %430 = OpLoad %uint %tileId None
+        %431 = OpExtInst %uint %55 UMin %430 %uint_3
+        %432 = OpAccessChain %_ptr_StorageBuffer_uint %9 %uint_0 %uint_0 %431 %uint_0
+        %434 = OpAtomicIAdd %uint %432 %uint_1 %uint_0 %uint_1
+               OpStore %offset %434
+        %436 = OpLoad %uint %offset None
+        %437 = OpAccessChain %_ptr_Uniform_uint %19 %uint_0 %uint_4
+        %438 = OpLoad %uint %437 None
+        %439 = OpUGreaterThanEqual %bool %436 %438
+               OpSelectionMerge %440 None
+               OpBranchConditional %439 %441 %440
+        %441 = OpLabel
+               OpBranch %207
+        %440 = OpLabel
+        %442 = OpLoad %uint %tileId None
+        %443 = OpLoad %uint %offset None
+        %444 = OpExtInst %uint %55 UMin %442 %uint_3
+        %445 = OpExtInst %uint %55 UMin %443 %uint_63
+        %447 = OpAccessChain %_ptr_StorageBuffer_uint_0 %9 %uint_0 %uint_0 %444 %uint_1 %445
+        %449 = OpCompositeExtract %uint %GlobalInvocationID 0
+               OpStore %447 %449 None
+               OpBranch %409
+        %409 = OpLabel
+               OpBranch %207
+        %207 = OpLabel
+        %450 = OpLoad %int %x None
+        %451 = OpIAdd %int %450 %int_1
+               OpStore %x %451 None
+               OpBranch %208
+        %209 = OpLabel
+               OpBranch %195
+        %195 = OpLabel
+        %453 = OpLoad %int %y None
+        %454 = OpIAdd %int %453 %int_1
+               OpStore %y %454 None
+               OpBranch %196
+        %197 = OpLabel
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %425
-        %426 = OpLabel
-        %427 = OpLoad %v3uint %main_global_invocation_id_Input None
-        %428 = OpFunctionCall %void %main_inner %427
+       %main = OpFunction %void None %456
+        %457 = OpLabel
+        %458 = OpLoad %v3uint %main_global_invocation_id_Input None
+        %459 = OpFunctionCall %void %main_inner %458
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1321.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1321.wgsl.expected.dxc.hlsl
index d32425b..c69761e 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1321.wgsl.expected.dxc.hlsl
@@ -7,7 +7,7 @@
   int a_save = foo();
   {
     for(; ; ) {
-      float x = arr[a_save];
+      float x = arr[min(uint(a_save), 3u)];
       break;
     }
   }
diff --git a/test/tint/bug/tint/1321.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1321.wgsl.expected.fxc.hlsl
index d32425b..c69761e 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1321.wgsl.expected.fxc.hlsl
@@ -7,7 +7,7 @@
   int a_save = foo();
   {
     for(; ; ) {
-      float x = arr[a_save];
+      float x = arr[min(uint(a_save), 3u)];
       break;
     }
   }
diff --git a/test/tint/bug/tint/1321.wgsl.expected.glsl b/test/tint/bug/tint/1321.wgsl.expected.glsl
index 5f3ce69..287dfbf 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1321.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 void main() {
   float arr[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f);
   {
-    int v = foo();
+    uint v = min(uint(foo()), 3u);
     while(true) {
       float x = arr[v];
       break;
diff --git a/test/tint/bug/tint/1321.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1321.wgsl.expected.ir.dxc.hlsl
index 5b0e8af..13e6cc6 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1321.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 void main() {
   float arr[4] = (float[4])0;
   {
-    int v = foo();
+    uint v = min(uint(foo()), 3u);
     while(true) {
       float x = arr[v];
       break;
diff --git a/test/tint/bug/tint/1321.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1321.wgsl.expected.ir.fxc.hlsl
index 5b0e8af..13e6cc6 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1321.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 void main() {
   float arr[4] = (float[4])0;
   {
-    int v = foo();
+    uint v = min(uint(foo()), 3u);
     while(true) {
       float x = arr[v];
       break;
diff --git a/test/tint/bug/tint/1321.wgsl.expected.ir.msl b/test/tint/bug/tint/1321.wgsl.expected.ir.msl
index c842da8..4694675 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1321.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
   T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int foo() {
   return 1;
 }
@@ -20,8 +23,9 @@
 fragment void tint_symbol() {
   tint_array<float, 4> arr = tint_array<float, 4>{};
   {
-    thread float* const a = (&arr[foo()]);
+    thread float* const a = (&arr[min(uint(foo()), 3u)]);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       float const x = (*a);
       break;
     }
diff --git a/test/tint/bug/tint/1321.wgsl.expected.msl b/test/tint/bug/tint/1321.wgsl.expected.msl
index 3aa3b57..b0a12cf 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.msl
+++ b/test/tint/bug/tint/1321.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int foo() {
   return 1;
 }
@@ -22,8 +25,9 @@
   tint_array<float, 4> arr = tint_array<float, 4>{};
   {
     int const tint_symbol_1 = foo();
-    int const a_save = tint_symbol_1;
+    uint const a_save = min(uint(tint_symbol_1), 3u);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       {
         float const x = arr[a_save];
         break;
diff --git a/test/tint/bug/tint/1321.wgsl.expected.spvasm b/test/tint/bug/tint/1321.wgsl.expected.spvasm
index 04d1231..a4e2ac5 100644
--- a/test/tint/bug/tint/1321.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1321.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main"
                OpExecutionMode %main OriginUpperLeft
@@ -24,6 +25,7 @@
 %_arr_float_uint_4 = OpTypeArray %float %uint_4
 %_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4
          %16 = OpConstantNull %_arr_float_uint_4
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_float = OpTypePointer Function %float
         %foo = OpFunction %int None %3
           %4 = OpLabel
@@ -36,7 +38,9 @@
                OpBranch %17
          %17 = OpLabel
          %22 = OpFunctionCall %int %foo
-          %a = OpAccessChain %_ptr_Function_float %arr %22
+         %23 = OpBitcast %uint %22
+         %24 = OpExtInst %uint %25 UMin %23 %uint_3
+          %a = OpAccessChain %_ptr_Function_float %arr %24
                OpBranch %20
          %20 = OpLabel
                OpLoopMerge %21 %19 None
diff --git a/test/tint/bug/tint/1385.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1385.wgsl.expected.dxc.hlsl
index 636df25..ded88c1 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1385.wgsl.expected.dxc.hlsl
@@ -1,7 +1,10 @@
 ByteAddressBuffer data : register(t1);
 
 int foo() {
-  return asint(data.Load(0u));
+  uint tint_symbol_1 = 0u;
+  data.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  return asint(data.Load((4u * min(0u, (tint_symbol_2 - 1u)))));
 }
 
 [numthreads(16, 16, 1)]
diff --git a/test/tint/bug/tint/1385.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1385.wgsl.expected.fxc.hlsl
index 636df25..ded88c1 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1385.wgsl.expected.fxc.hlsl
@@ -1,7 +1,10 @@
 ByteAddressBuffer data : register(t1);
 
 int foo() {
-  return asint(data.Load(0u));
+  uint tint_symbol_1 = 0u;
+  data.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  return asint(data.Load((4u * min(0u, (tint_symbol_2 - 1u)))));
 }
 
 [numthreads(16, 16, 1)]
diff --git a/test/tint/bug/tint/1385.wgsl.expected.glsl b/test/tint/bug/tint/1385.wgsl.expected.glsl
index 4088289..b8c6f92 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1385.wgsl.expected.glsl
@@ -5,7 +5,9 @@
   int inner[];
 } v;
 int foo() {
-  return v.inner[0];
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(0), v_1);
+  return v.inner[v_2];
 }
 layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1385.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1385.wgsl.expected.ir.dxc.hlsl
index 57c109c..470d3f3 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1385.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,10 @@
 
 ByteAddressBuffer data : register(t1);
 int foo() {
-  return asint(data.Load(0u));
+  uint v = 0u;
+  data.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  return asint(data.Load((0u + (min(uint(int(0)), v_1) * 4u))));
 }
 
 [numthreads(16, 16, 1)]
diff --git a/test/tint/bug/tint/1385.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1385.wgsl.expected.ir.fxc.hlsl
index 57c109c..470d3f3 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1385.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,10 @@
 
 ByteAddressBuffer data : register(t1);
 int foo() {
-  return asint(data.Load(0u));
+  uint v = 0u;
+  data.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  return asint(data.Load((0u + (min(uint(int(0)), v_1) * 4u))));
 }
 
 [numthreads(16, 16, 1)]
diff --git a/test/tint/bug/tint/1385.wgsl.expected.ir.msl b/test/tint/bug/tint/1385.wgsl.expected.ir.msl
index 466b3db..d733fd6 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1385.wgsl.expected.ir.msl
@@ -15,13 +15,15 @@
 
 struct tint_module_vars_struct {
   const device tint_array<int, 1>* data;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 int foo(tint_module_vars_struct tint_module_vars) {
-  return (*tint_module_vars.data)[0];
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  return (*tint_module_vars.data)[min(uint(0), v)];
 }
 
-kernel void tint_symbol(const device tint_array<int, 1>* data [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.data=data};
+kernel void tint_symbol(const device tint_array<int, 1>* data [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.data=data, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   foo(tint_module_vars);
 }
diff --git a/test/tint/bug/tint/1385.wgsl.expected.msl b/test/tint/bug/tint/1385.wgsl.expected.msl
index c57afce..50a8298 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.msl
+++ b/test/tint/bug/tint/1385.wgsl.expected.msl
@@ -14,16 +14,20 @@
     T elements[N];
 };
 
-struct tint_symbol_3 {
+struct tint_symbol_4 {
   /* 0x0000 */ tint_array<int, 1> arr;
 };
 
-int foo(const device tint_array<int, 1>* const tint_symbol_1) {
-  return (*(tint_symbol_1))[0];
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+int foo(const device tint_array<int, 1>* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  return (*(tint_symbol_1))[min(0u, (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u))];
 }
 
-kernel void tint_symbol(const device tint_symbol_3* tint_symbol_2 [[buffer(0)]]) {
-  foo(&((*(tint_symbol_2)).arr));
+kernel void tint_symbol(const device tint_symbol_4* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]]) {
+  foo(&((*(tint_symbol_3)).arr), tint_symbol_5);
   return;
 }
 
diff --git a/test/tint/bug/tint/1385.wgsl.expected.spvasm b/test/tint/bug/tint/1385.wgsl.expected.spvasm
index 3ad5b2d..9412e72 100644
--- a/test/tint/bug/tint/1385.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1385.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 20
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 16 16 1
@@ -23,20 +24,27 @@
 %_ptr_StorageBuffer_data_block = OpTypePointer StorageBuffer %data_block
           %1 = OpVariable %_ptr_StorageBuffer_data_block StorageBuffer
           %7 = OpTypeFunction %int
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+%_ptr_StorageBuffer__runtimearr_int = OpTypePointer StorageBuffer %_runtimearr_int
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
        %void = OpTypeVoid
-         %17 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
         %foo = OpFunction %int None %7
           %8 = OpLabel
-          %9 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %int_0
-         %14 = OpLoad %int %9 None
-               OpReturnValue %14
+          %9 = OpAccessChain %_ptr_StorageBuffer__runtimearr_int %1 %uint_0
+         %13 = OpArrayLength %uint %1 0
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_0
+         %18 = OpExtInst %uint %19 UMin %16 %14
+         %20 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %18
+         %22 = OpLoad %int %20 None
+               OpReturnValue %22
                OpFunctionEnd
-       %main = OpFunction %void None %17
-         %18 = OpLabel
-         %19 = OpFunctionCall %int %foo
+       %main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %int %foo
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1474-a.wgsl.expected.ir.msl b/test/tint/bug/tint/1474-a.wgsl.expected.ir.msl
index 84d42b6..4d10141 100644
--- a/test/tint/bug/tint/1474-a.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1474-a.wgsl.expected.ir.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (true) {
       } else {
         break;
diff --git a/test/tint/bug/tint/1474-a.wgsl.expected.msl b/test/tint/bug/tint/1474-a.wgsl.expected.msl
index 593ea73..fab12b4 100644
--- a/test/tint/bug/tint/1474-a.wgsl.expected.msl
+++ b/test/tint/bug/tint/1474-a.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if (true) {
       break;
     } else {
diff --git a/test/tint/bug/tint/1538.wgsl.expected.glsl b/test/tint/bug/tint/1538.wgsl.expected.glsl
index 25e02d4..518f473 100644
--- a/test/tint/bug/tint/1538.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1538.wgsl.expected.glsl
@@ -21,11 +21,11 @@
 void main() {
   {
     while(true) {
-      if ((v.inner[0] == 0u)) {
+      if ((v.inner[0u] == 0u)) {
         break;
       }
       int s = f();
-      v.inner[0] = 0u;
+      v.inner[0u] = 0u;
       {
       }
       continue;
diff --git a/test/tint/bug/tint/1538.wgsl.expected.ir.msl b/test/tint/bug/tint/1538.wgsl.expected.ir.msl
index a178dd0..b03a29d 100644
--- a/test/tint/bug/tint/1538.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1538.wgsl.expected.ir.msl
@@ -1,6 +1,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 template<typename T, size_t N>
 struct tint_array {
   const constant T& operator[](size_t i) const constant { return elements[i]; }
@@ -24,6 +27,7 @@
 int f() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       g();
       break;
     }
@@ -36,11 +40,12 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.buf=buf};
   {
     while(true) {
-      if (((*tint_module_vars.buf)[0] == 0u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
+      if (((*tint_module_vars.buf)[0u] == 0u)) {
         break;
       }
       int s = f();
-      (*tint_module_vars.buf)[0] = 0u;
+      (*tint_module_vars.buf)[0u] = 0u;
       {
       }
       continue;
diff --git a/test/tint/bug/tint/1538.wgsl.expected.msl b/test/tint/bug/tint/1538.wgsl.expected.msl
index 3c8f688..05c5d2e 100644
--- a/test/tint/bug/tint/1538.wgsl.expected.msl
+++ b/test/tint/bug/tint/1538.wgsl.expected.msl
@@ -2,6 +2,9 @@
 
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 template<typename T, size_t N>
 struct tint_array {
     const constant T& operator[](size_t i) const constant { return elements[i]; }
@@ -20,6 +23,7 @@
 
 int f() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     g();
     break;
   }
@@ -29,6 +33,7 @@
 
 kernel void tint_symbol(device tint_array<uint, 1>* tint_symbol_1 [[buffer(0)]]) {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (((*(tint_symbol_1))[0] == 0u)) {
       break;
     }
diff --git a/test/tint/bug/tint/1538.wgsl.expected.spvasm b/test/tint/bug/tint/1538.wgsl.expected.spvasm
index c81d84b..5970166 100644
--- a/test/tint/bug/tint/1538.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1538.wgsl.expected.spvasm
@@ -62,7 +62,7 @@
                OpLoopMerge %27 %25 None
                OpBranch %24
          %24 = OpLabel
-         %28 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_0
+         %28 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_0
          %31 = OpLoad %uint %28 None
          %32 = OpIEqual %bool %31 %uint_0
                OpSelectionMerge %34 None
@@ -72,7 +72,7 @@
          %34 = OpLabel
          %36 = OpFunctionCall %int %f
                OpStore %s %36
-         %39 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_0
+         %39 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_0
                OpStore %39 %uint_0 None
                OpBranch %25
          %25 = OpLabel
diff --git a/test/tint/bug/tint/1557.wgsl.expected.ir.msl b/test/tint/bug/tint/1557.wgsl.expected.ir.msl
index a597fe8..adc3222 100644
--- a/test/tint/bug/tint/1557.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1557.wgsl.expected.ir.msl
@@ -1,6 +1,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant int* u;
 };
@@ -13,6 +16,7 @@
   int j = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((j >= 1)) {
         break;
       }
diff --git a/test/tint/bug/tint/1557.wgsl.expected.msl b/test/tint/bug/tint/1557.wgsl.expected.msl
index d572006..7bc61d7 100644
--- a/test/tint/bug/tint/1557.wgsl.expected.msl
+++ b/test/tint/bug/tint/1557.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   return 0;
 }
@@ -8,6 +12,7 @@
 void g() {
   int j = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((j >= 1)) {
       break;
     }
diff --git a/test/tint/bug/tint/1563.wgsl b/test/tint/bug/tint/1563.wgsl
index 7625bf8..2c377f4 100644
--- a/test/tint/bug/tint/1563.wgsl
+++ b/test/tint/bug/tint/1563.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn foo() -> f32 {
   let oob = 99;
   let b = vec4<f32>()[oob];  // 99 is out of bounds
diff --git a/test/tint/bug/tint/1604.wgsl.expected.ir.msl b/test/tint/bug/tint/1604.wgsl.expected.ir.msl
index da22029..afba81b 100644
--- a/test/tint/bug/tint/1604.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1604.wgsl.expected.ir.msl
@@ -5,6 +5,9 @@
   const constant int* x;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol(const constant int* x [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.x=x};
   switch((*tint_module_vars.x)) {
@@ -12,6 +15,7 @@
     {
       {
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false)
           return;
         }
       }
diff --git a/test/tint/bug/tint/1604.wgsl.expected.msl b/test/tint/bug/tint/1604.wgsl.expected.msl
index 0f45634..50eb1f2 100644
--- a/test/tint/bug/tint/1604.wgsl.expected.msl
+++ b/test/tint/bug/tint/1604.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol(const constant int* tint_symbol_1 [[buffer(0)]]) {
   switch(*(tint_symbol_1)) {
     case 0: {
       while(true) {
+        TINT_ISOLATE_UB(tint_volatile_false);
         return;
       }
       break;
diff --git a/test/tint/bug/tint/1605.wgsl.expected.ir.msl b/test/tint/bug/tint/1605.wgsl.expected.ir.msl
index 6312b71..15bb159 100644
--- a/test/tint/bug/tint/1605.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1605.wgsl.expected.ir.msl
@@ -5,10 +5,14 @@
   const constant int* b;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 bool func_3(tint_module_vars_struct tint_module_vars) {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < (*tint_module_vars.b))) {
       } else {
         break;
@@ -16,6 +20,7 @@
       {
         int j = -1;
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false_1)
           if ((j == 1)) {
           } else {
             break;
diff --git a/test/tint/bug/tint/1605.wgsl.expected.msl b/test/tint/bug/tint/1605.wgsl.expected.msl
index 18e89e5..65c5357 100644
--- a/test/tint/bug/tint/1605.wgsl.expected.msl
+++ b/test/tint/bug/tint/1605.wgsl.expected.msl
@@ -1,9 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 bool func_3(const constant int* const tint_symbol_1) {
   for(int i = 0; (i < *(tint_symbol_1)); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     for(int j = -1; (j == 1); j = as_type<int>((as_type<uint>(j) + as_type<uint>(1)))) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       return false;
     }
   }
diff --git a/test/tint/bug/tint/1641.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1641.wgsl.expected.dxc.hlsl
index 3a440db..1fe657e 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1641.wgsl.expected.dxc.hlsl
@@ -9,7 +9,7 @@
 float4 main_inner() {
   int zero = 0;
   Normals tint_symbol_1[1] = {{float3(0.0f, 0.0f, 1.0f)}};
-  return float4(tint_symbol_1[zero].f, 1.0f);
+  return float4(tint_symbol_1[min(uint(zero), 0u)].f, 1.0f);
 }
 
 tint_symbol main() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1641.wgsl.expected.fxc.hlsl
index 3a440db..1fe657e 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1641.wgsl.expected.fxc.hlsl
@@ -9,7 +9,7 @@
 float4 main_inner() {
   int zero = 0;
   Normals tint_symbol_1[1] = {{float3(0.0f, 0.0f, 1.0f)}};
-  return float4(tint_symbol_1[zero].f, 1.0f);
+  return float4(tint_symbol_1[min(uint(zero), 0u)].f, 1.0f);
 }
 
 tint_symbol main() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.glsl b/test/tint/bug/tint/1641.wgsl.expected.glsl
index 4cdbdad..c239447 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1641.wgsl.expected.glsl
@@ -7,7 +7,7 @@
 
 vec4 tint_symbol_inner() {
   int zero = 0;
-  return vec4(Normals[1](Normals(vec3(0.0f, 0.0f, 1.0f)))[zero].f, 1.0f);
+  return vec4(Normals[1](Normals(vec3(0.0f, 0.0f, 1.0f)))[min(uint(zero), 0u)].f, 1.0f);
 }
 void main() {
   gl_Position = tint_symbol_inner();
diff --git a/test/tint/bug/tint/1641.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1641.wgsl.expected.ir.dxc.hlsl
index 864a0f9..0a21a77 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1641.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 float4 main_inner() {
   int zero = int(0);
   Normals v[1] = {{float3(0.0f, 0.0f, 1.0f)}};
-  return float4(v[zero].f, 1.0f);
+  return float4(v[min(uint(zero), 0u)].f, 1.0f);
 }
 
 main_outputs main() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1641.wgsl.expected.ir.fxc.hlsl
index 864a0f9..0a21a77 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1641.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 float4 main_inner() {
   int zero = int(0);
   Normals v[1] = {{float3(0.0f, 0.0f, 1.0f)}};
-  return float4(v[zero].f, 1.0f);
+  return float4(v[min(uint(zero), 0u)].f, 1.0f);
 }
 
 main_outputs main() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.ir.msl b/test/tint/bug/tint/1641.wgsl.expected.ir.msl
index e4515f7..95c4f3e 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1641.wgsl.expected.ir.msl
@@ -23,7 +23,7 @@
 
 float4 tint_symbol_inner() {
   int const zero = 0;
-  return float4(tint_array<Normals, 1>{Normals{.f=float3(0.0f, 0.0f, 1.0f)}}[zero].f, 1.0f);
+  return float4(tint_array<Normals, 1>{Normals{.f=float3(0.0f, 0.0f, 1.0f)}}[min(uint(zero), 0u)].f, 1.0f);
 }
 
 vertex tint_symbol_outputs tint_symbol() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.msl b/test/tint/bug/tint/1641.wgsl.expected.msl
index b03793a..bba390c 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.msl
+++ b/test/tint/bug/tint/1641.wgsl.expected.msl
@@ -25,7 +25,7 @@
 float4 tint_symbol_inner() {
   int const zero = 0;
   tint_array<Normals, 1> const tint_symbol_2 = tint_array<Normals, 1>{Normals{.f=float3(0.0f, 0.0f, 1.0f)}};
-  return float4(tint_symbol_2[zero].f, 1.0f);
+  return float4(tint_symbol_2[min(uint(zero), 0u)].f, 1.0f);
 }
 
 vertex tint_symbol_1 tint_symbol() {
diff --git a/test/tint/bug/tint/1641.wgsl.expected.spvasm b/test/tint/bug/tint/1641.wgsl.expected.spvasm
index edcedc5..a55d867 100644
--- a/test/tint/bug/tint/1641.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1641.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %main "main" %main_position_Output %main___point_size_Output
                OpName %main_position_Output "main_position_Output"
@@ -38,21 +39,23 @@
          %20 = OpTypeFunction %v4float
         %int = OpTypeInt 32 1
        %zero = OpConstant %int 0
-%_ptr_Private_v3float = OpTypePointer Private %v3float
      %uint_0 = OpConstant %uint 0
+%_ptr_Private_v3float = OpTypePointer Private %v3float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
  %main_inner = OpFunction %v4float None %20
          %21 = OpLabel
-         %24 = OpAccessChain %_ptr_Private_v3float %7 %zero %uint_0
-         %27 = OpLoad %v3float %24 None
-         %28 = OpCompositeConstruct %v4float %27 %float_1
-               OpReturnValue %28
+         %24 = OpBitcast %uint %zero
+         %25 = OpExtInst %uint %26 UMin %24 %uint_0
+         %28 = OpAccessChain %_ptr_Private_v3float %7 %25 %uint_0
+         %30 = OpLoad %v3float %28 None
+         %31 = OpCompositeConstruct %v4float %30 %float_1
+               OpReturnValue %31
                OpFunctionEnd
-       %main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %main_inner
-               OpStore %main_position_Output %33 None
+       %main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %main_inner
+               OpStore %main_position_Output %36 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1653.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1653.wgsl.expected.dxc.hlsl
index a1dd962..8f9a8cd 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1653.wgsl.expected.dxc.hlsl
@@ -7,7 +7,7 @@
 
 float4 vs_main_inner(uint in_vertex_index) {
   float4 tint_symbol_3[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
-  return tint_symbol_3[in_vertex_index];
+  return tint_symbol_3[min(in_vertex_index, 2u)];
 }
 
 tint_symbol_2 vs_main(tint_symbol_1 tint_symbol) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1653.wgsl.expected.fxc.hlsl
index a1dd962..8f9a8cd 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1653.wgsl.expected.fxc.hlsl
@@ -7,7 +7,7 @@
 
 float4 vs_main_inner(uint in_vertex_index) {
   float4 tint_symbol_3[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
-  return tint_symbol_3[in_vertex_index];
+  return tint_symbol_3[min(in_vertex_index, 2u)];
 }
 
 tint_symbol_2 vs_main(tint_symbol_1 tint_symbol) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.glsl b/test/tint/bug/tint/1653.wgsl.expected.glsl
index c856a7a..f364009 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1653.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 vec4 vs_main_inner(uint in_vertex_index) {
-  return vec4[3](vec4(0.0f, 0.0f, 0.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f))[in_vertex_index];
+  return vec4[3](vec4(0.0f, 0.0f, 0.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f))[min(in_vertex_index, 2u)];
 }
 void main() {
   gl_Position = vs_main_inner(uint(gl_VertexID));
diff --git a/test/tint/bug/tint/1653.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1653.wgsl.expected.ir.dxc.hlsl
index f5193a1..9a1fb4e 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1653.wgsl.expected.ir.dxc.hlsl
@@ -9,7 +9,7 @@
 
 float4 vs_main_inner(uint in_vertex_index) {
   float4 v[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
-  return v[in_vertex_index];
+  return v[min(in_vertex_index, 2u)];
 }
 
 vs_main_outputs vs_main(vs_main_inputs inputs) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1653.wgsl.expected.ir.fxc.hlsl
index f5193a1..9a1fb4e 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1653.wgsl.expected.ir.fxc.hlsl
@@ -9,7 +9,7 @@
 
 float4 vs_main_inner(uint in_vertex_index) {
   float4 v[3] = {float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
-  return v[in_vertex_index];
+  return v[min(in_vertex_index, 2u)];
 }
 
 vs_main_outputs vs_main(vs_main_inputs inputs) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.ir.msl b/test/tint/bug/tint/1653.wgsl.expected.ir.msl
index 1283fc0..3c39813 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1653.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 };
 
 float4 vs_main_inner(uint in_vertex_index) {
-  return tint_array<float4, 3>{float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)}[in_vertex_index];
+  return tint_array<float4, 3>{float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)}[min(in_vertex_index, 2u)];
 }
 
 vertex vs_main_outputs vs_main(uint in_vertex_index [[vertex_id]]) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.msl b/test/tint/bug/tint/1653.wgsl.expected.msl
index 09bd662..09e26d6 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.msl
+++ b/test/tint/bug/tint/1653.wgsl.expected.msl
@@ -20,7 +20,7 @@
 
 float4 vs_main_inner(uint in_vertex_index) {
   tint_array<float4, 3> const tint_symbol_1 = tint_array<float4, 3>{float4(0.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(1.0f, 1.0f, 0.0f, 1.0f)};
-  return tint_symbol_1[in_vertex_index];
+  return tint_symbol_1[min(in_vertex_index, 2u)];
 }
 
 vertex tint_symbol vs_main(uint in_vertex_index [[vertex_id]]) {
diff --git a/test/tint/bug/tint/1653.wgsl.expected.spvasm b/test/tint/bug/tint/1653.wgsl.expected.spvasm
index 0034b2c..8ffc685 100644
--- a/test/tint/bug/tint/1653.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1653.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vs_main "vs_main" %vs_main_vertex_index_Input %vs_main_position_Output %vs_main___point_size_Output
                OpName %vs_main_vertex_index_Input "vs_main_vertex_index_Input"
@@ -36,21 +37,23 @@
          %14 = OpConstantComposite %_arr_v4float_uint_3 %15 %18 %19
          %10 = OpVariable %_ptr_Private__arr_v4float_uint_3 Private %14
          %22 = OpTypeFunction %v4float %uint
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v4float = OpTypePointer Private %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %vs_main_inner = OpFunction %v4float None %22
 %in_vertex_index = OpFunctionParameter %uint
          %23 = OpLabel
-         %24 = OpAccessChain %_ptr_Private_v4float %10 %in_vertex_index
-         %26 = OpLoad %v4float %24 None
-               OpReturnValue %26
+         %24 = OpExtInst %uint %25 UMin %in_vertex_index %uint_2
+         %27 = OpAccessChain %_ptr_Private_v4float %10 %24
+         %29 = OpLoad %v4float %27 None
+               OpReturnValue %29
                OpFunctionEnd
-    %vs_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpLoad %uint %vs_main_vertex_index_Input None
-         %32 = OpFunctionCall %v4float %vs_main_inner %31
-               OpStore %vs_main_position_Output %32 None
+    %vs_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpLoad %uint %vs_main_vertex_index_Input None
+         %35 = OpFunctionCall %v4float %vs_main_inner %34
+               OpStore %vs_main_position_Output %35 None
                OpStore %vs_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1666.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1666.wgsl.expected.dxc.hlsl
index 14804b7..5a211d5 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1666.wgsl.expected.dxc.hlsl
@@ -1,24 +1,27 @@
 void tint_symbol() {
   int idx = 3;
-  int x = int2(1, 2)[idx];
+  int x = int2(1, 2)[min(uint(idx), 1u)];
 }
 
 void tint_symbol_1() {
   int idx = 4;
-  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[idx];
+  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 
 void fixed_size_array() {
   int arr[2] = {1, 2};
   int idx = 3;
-  int x = arr[idx];
+  int x = arr[min(uint(idx), 1u)];
 }
 
 ByteAddressBuffer rarr : register(t0);
 
 void runtime_size_array() {
+  uint tint_symbol_3 = 0u;
+  rarr.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
   int idx = -1;
-  float x = asfloat(rarr.Load((4u * uint(idx))));
+  float x = asfloat(rarr.Load((4u * min(uint(idx), (tint_symbol_4 - 1u)))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1666.wgsl.expected.glsl b/test/tint/bug/tint/1666.wgsl.expected.glsl
index f8be681..6a9a99d 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1666.wgsl.expected.glsl
@@ -6,20 +6,22 @@
 } v;
 void vector() {
   int idx = 3;
-  int x = ivec2(1, 2)[idx];
+  int x = ivec2(1, 2)[min(uint(idx), 1u)];
 }
 void matrix() {
   int idx = 4;
-  vec2 x = mat2(vec2(1.0f, 2.0f), vec2(3.0f, 4.0f))[idx];
+  vec2 x = mat2(vec2(1.0f, 2.0f), vec2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 void fixed_size_array() {
   int arr[2] = int[2](1, 2);
   int idx = 3;
-  int x = arr[idx];
+  int x = arr[min(uint(idx), 1u)];
 }
 void runtime_size_array() {
   int idx = -1;
-  float x = v.inner[idx];
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(idx), v_1);
+  float x = v.inner[v_2];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1666.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1666.wgsl.expected.ir.dxc.hlsl
index 5c7dc9c..bca7c07 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1666.wgsl.expected.ir.dxc.hlsl
@@ -2,23 +2,26 @@
 ByteAddressBuffer rarr : register(t0);
 void tint_symbol() {
   int idx = int(3);
-  int x = int2(int(1), int(2))[idx];
+  int x = int2(int(1), int(2))[min(uint(idx), 1u)];
 }
 
 void tint_symbol_1() {
   int idx = int(4);
-  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[idx];
+  float2 x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 
 void fixed_size_array() {
   int arr[2] = {int(1), int(2)};
   int idx = int(3);
-  int x = arr[idx];
+  int x = arr[min(uint(idx), 1u)];
 }
 
 void runtime_size_array() {
   int idx = int(-1);
-  float x = asfloat(rarr.Load((0u + (uint(idx) * 4u))));
+  uint v = 0u;
+  rarr.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  float x = asfloat(rarr.Load((0u + (min(uint(idx), v_1) * 4u))));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1666.wgsl.expected.ir.msl b/test/tint/bug/tint/1666.wgsl.expected.ir.msl
index 5b8ce2a..da19049 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1666.wgsl.expected.ir.msl
@@ -15,31 +15,33 @@
 
 struct tint_module_vars_struct {
   const device tint_array<float, 1>* rarr;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void vector() {
   int const idx = 3;
-  int const x = int2(1, 2)[idx];
+  int const x = int2(1, 2)[min(uint(idx), 1u)];
 }
 
 void tint_symbol() {
   int const idx = 4;
-  float2 const x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[idx];
+  float2 const x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 
 void fixed_size_array() {
   tint_array<int, 2> const arr = tint_array<int, 2>{1, 2};
   int const idx = 3;
-  int const x = arr[idx];
+  int const x = arr[min(uint(idx), 1u)];
 }
 
 void runtime_size_array(tint_module_vars_struct tint_module_vars) {
   int const idx = -1;
-  float const x = (*tint_module_vars.rarr)[idx];
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  float const x = (*tint_module_vars.rarr)[min(uint(idx), v)];
 }
 
-kernel void f(const device tint_array<float, 1>* rarr [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.rarr=rarr};
+kernel void f(const device tint_array<float, 1>* rarr [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.rarr=rarr, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   vector();
   tint_symbol();
   fixed_size_array();
diff --git a/test/tint/bug/tint/1666.wgsl.expected.msl b/test/tint/bug/tint/1666.wgsl.expected.msl
index 9327f8a..af58a9e 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.msl
+++ b/test/tint/bug/tint/1666.wgsl.expected.msl
@@ -14,36 +14,40 @@
     T elements[N];
 };
 
-struct tint_symbol_3 {
+struct tint_symbol_4 {
   /* 0x0000 */ tint_array<float, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 void vector() {
   int const idx = 3;
-  int const x = int2(1, 2)[idx];
+  int const x = int2(1, 2)[min(uint(idx), 1u)];
 }
 
 void tint_symbol() {
   int const idx = 4;
-  float2 const x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[idx];
+  float2 const x = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f))[min(uint(idx), 1u)];
 }
 
 void fixed_size_array() {
   tint_array<int, 2> const arr = tint_array<int, 2>{1, 2};
   int const idx = 3;
-  int const x = arr[idx];
+  int const x = arr[min(uint(idx), 1u)];
 }
 
-void runtime_size_array(const device tint_array<float, 1>* const tint_symbol_1) {
+void runtime_size_array(const device tint_array<float, 1>* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
   int const idx = -1;
-  float const x = (*(tint_symbol_1))[idx];
+  float const x = (*(tint_symbol_1))[min(uint(idx), (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u))];
 }
 
-kernel void f(const device tint_symbol_3* tint_symbol_2 [[buffer(0)]]) {
+kernel void f(const device tint_symbol_4* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]]) {
   vector();
   tint_symbol();
   fixed_size_array();
-  runtime_size_array(&((*(tint_symbol_2)).arr));
+  runtime_size_array(&((*(tint_symbol_3)).arr), tint_symbol_5);
   return;
 }
 
diff --git a/test/tint/bug/tint/1666.wgsl.expected.spvasm b/test/tint/bug/tint/1666.wgsl.expected.spvasm
index cad0fba..803d9c3 100644
--- a/test/tint/bug/tint/1666.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1666.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %f "f"
                OpExecutionMode %f LocalSize 1 1 1
@@ -50,51 +51,64 @@
          %19 = OpTypeFunction %void
         %int = OpTypeInt 32 1
         %idx = OpConstant %int 3
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
       %int_2 = OpConstant %int 2
-         %24 = OpConstantComposite %v2int %int_1 %int_2
+         %29 = OpConstantComposite %v2int %int_1 %int_2
       %idx_0 = OpConstant %int 4
 %_ptr_Private_v2float = OpTypePointer Private %v2float
-       %uint = OpTypeInt 32 0
      %uint_2 = OpConstant %uint 2
 %_arr_int_uint_2 = OpTypeArray %int %uint_2
         %arr = OpConstantComposite %_arr_int_uint_2 %int_1 %int_2
 %_ptr_Function__arr_int_uint_2 = OpTypePointer Function %_arr_int_uint_2
 %_ptr_Function_int = OpTypePointer Function %int
       %idx_1 = OpConstant %int -1
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
      %uint_0 = OpConstant %uint 0
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %vector = OpFunction %void None %19
          %20 = OpLabel
-          %x = OpVectorExtractDynamic %int %24 %idx
+         %24 = OpBitcast %uint %idx
+         %25 = OpExtInst %uint %26 UMin %24 %uint_1
+          %x = OpVectorExtractDynamic %int %29 %25
                OpReturn
                OpFunctionEnd
      %matrix = OpFunction %void None %19
-         %29 = OpLabel
-         %31 = OpAccessChain %_ptr_Private_v2float %6 %idx_0
-        %x_0 = OpLoad %v2float %31 None
+         %34 = OpLabel
+         %36 = OpBitcast %uint %idx_0
+         %37 = OpExtInst %uint %26 UMin %36 %uint_1
+         %38 = OpAccessChain %_ptr_Private_v2float %6 %37
+        %x_0 = OpLoad %v2float %38 None
                OpReturn
                OpFunctionEnd
 %fixed_size_array = OpFunction %void None %19
-         %35 = OpLabel
-         %40 = OpVariable %_ptr_Function__arr_int_uint_2 Function
-               OpStore %40 %arr
-         %42 = OpAccessChain %_ptr_Function_int %40 %idx
-        %x_1 = OpLoad %int %42 None
+         %42 = OpLabel
+         %46 = OpVariable %_ptr_Function__arr_int_uint_2 Function
+               OpStore %46 %arr
+         %48 = OpBitcast %uint %idx
+         %49 = OpExtInst %uint %26 UMin %48 %uint_1
+         %50 = OpAccessChain %_ptr_Function_int %46 %49
+        %x_1 = OpLoad %int %50 None
                OpReturn
                OpFunctionEnd
 %runtime_size_array = OpFunction %void None %19
-         %46 = OpLabel
-         %48 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %idx_1
-        %x_2 = OpLoad %float %48 None
+         %54 = OpLabel
+         %56 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %1 %uint_0
+         %59 = OpArrayLength %uint %1 0
+         %60 = OpISub %uint %59 %uint_1
+         %61 = OpBitcast %uint %idx_1
+         %62 = OpExtInst %uint %26 UMin %61 %60
+         %63 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %62
+        %x_2 = OpLoad %float %63 None
                OpReturn
                OpFunctionEnd
           %f = OpFunction %void None %19
-         %53 = OpLabel
-         %54 = OpFunctionCall %void %vector
-         %55 = OpFunctionCall %void %matrix
-         %56 = OpFunctionCall %void %fixed_size_array
-         %57 = OpFunctionCall %void %runtime_size_array
+         %67 = OpLabel
+         %68 = OpFunctionCall %void %vector
+         %69 = OpFunctionCall %void %matrix
+         %70 = OpFunctionCall %void %fixed_size_array
+         %71 = OpFunctionCall %void %runtime_size_array
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1725.wgsl b/test/tint/bug/tint/1725.wgsl
index 04c6106..1e0a2b4 100644
--- a/test/tint/bug/tint/1725.wgsl
+++ b/test/tint/bug/tint/1725.wgsl
@@ -1,4 +1,4 @@
-// flags: --transform robustness,renamer --rename-all
+// flags: --transform renamer --rename-all
 @group(0) @binding(0) var<storage> data : array<u32>;
 
 @compute @workgroup_size(1)
diff --git a/test/tint/bug/tint/1737.wgsl.expected.glsl b/test/tint/bug/tint/1737.wgsl.expected.glsl
index 28d2045..e4e6563 100644
--- a/test/tint/bug/tint/1737.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1737.wgsl.expected.glsl
@@ -3,8 +3,8 @@
 shared float a[10];
 shared float b[20];
 void f() {
-  float x = a[0];
-  float y = b[0];
+  float x = a[0u];
+  float y = b[0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1737.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1737.wgsl.expected.ir.dxc.hlsl
index c399f1d..890a6fa 100644
--- a/test/tint/bug/tint/1737.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1737.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,8 @@
 groupshared float a[10];
 groupshared float b[20];
 void f() {
-  float x = a[int(0)];
-  float y = b[int(0)];
+  float x = a[0u];
+  float y = b[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1737.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1737.wgsl.expected.ir.fxc.hlsl
index c399f1d..890a6fa 100644
--- a/test/tint/bug/tint/1737.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1737.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,8 @@
 groupshared float a[10];
 groupshared float b[20];
 void f() {
-  float x = a[int(0)];
-  float y = b[int(0)];
+  float x = a[0u];
+  float y = b[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1737.wgsl.expected.ir.msl b/test/tint/bug/tint/1737.wgsl.expected.ir.msl
index d141773..2cc75da 100644
--- a/test/tint/bug/tint/1737.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1737.wgsl.expected.ir.msl
@@ -19,6 +19,6 @@
 };
 
 void f(tint_module_vars_struct tint_module_vars) {
-  float const x = (*tint_module_vars.a)[0];
-  float const y = (*tint_module_vars.b)[0];
+  float const x = (*tint_module_vars.a)[0u];
+  float const y = (*tint_module_vars.b)[0u];
 }
diff --git a/test/tint/bug/tint/1737.wgsl.expected.spvasm b/test/tint/bug/tint/1737.wgsl.expected.spvasm
index f4dc551..13514b7 100644
--- a/test/tint/bug/tint/1737.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1737.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 23
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -28,17 +28,16 @@
        %void = OpTypeVoid
          %13 = OpTypeFunction %void
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
           %f = OpFunction %void None %13
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_Workgroup_float %a %int_0
+         %15 = OpAccessChain %_ptr_Workgroup_float %a %uint_0
           %x = OpLoad %float %15 None
-         %20 = OpAccessChain %_ptr_Workgroup_float %b %int_0
-          %y = OpLoad %float %20 None
+         %19 = OpAccessChain %_ptr_Workgroup_float %b %uint_0
+          %y = OpLoad %float %19 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %13
-         %23 = OpLabel
+         %22 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1739.wgsl b/test/tint/bug/tint/1739.wgsl
index ef45dd5..83cddcb 100644
--- a/test/tint/bug/tint/1739.wgsl
+++ b/test/tint/bug/tint/1739.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @group(0) @binding(0) var t : texture_external;
 
 @group(0) @binding(1) var outImage : texture_storage_2d<rgba8unorm, write>;
diff --git a/test/tint/bug/tint/1764.wgsl.expected.glsl b/test/tint/bug/tint/1764.wgsl.expected.glsl
index b36f465..d26276d 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1764.wgsl.expected.glsl
@@ -18,7 +18,7 @@
     }
   }
   barrier();
-  W[0] = 42;
+  W[0u] = 42;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1764.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1764.wgsl.expected.ir.dxc.hlsl
index 40aba4a..901ae64 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1764.wgsl.expected.ir.dxc.hlsl
@@ -21,7 +21,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  W[int(0)] = int(42);
+  W[0u] = int(42);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1764.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1764.wgsl.expected.ir.fxc.hlsl
index 40aba4a..901ae64 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1764.wgsl.expected.ir.fxc.hlsl
@@ -21,7 +21,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  W[int(0)] = int(42);
+  W[0u] = int(42);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1764.wgsl.expected.ir.msl b/test/tint/bug/tint/1764.wgsl.expected.ir.msl
index 8e5721e..d5c3440 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1764.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<int, 246>* W;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int, 246> tint_symbol_1;
 };
@@ -26,6 +29,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 246u)) {
         break;
@@ -39,7 +43,7 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   threadgroup tint_array<int, 246>* const p = tint_module_vars.W;
-  (*p)[0] = 42;
+  (*p)[0u] = 42;
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/bug/tint/1764.wgsl.expected.msl b/test/tint/bug/tint/1764.wgsl.expected.msl
index b48b803..0205a7e 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.msl
+++ b/test/tint/bug/tint/1764.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int, 246>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 246u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_1))[i] = 0;
   }
diff --git a/test/tint/bug/tint/1764.wgsl.expected.spvasm b/test/tint/bug/tint/1764.wgsl.expected.spvasm
index 8c5c89b..d51ebb1 100644
--- a/test/tint/bug/tint/1764.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1764.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 39
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -31,8 +31,9 @@
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
+     %uint_0 = OpConstant %uint 0
      %int_42 = OpConstant %int 42
-         %35 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
  %main_inner = OpFunction %void None %12
 %tint_local_index = OpFunctionParameter %uint
          %13 = OpLabel
@@ -58,13 +59,13 @@
                OpBranch %17
          %18 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpAccessChain %_ptr_Workgroup_int %W %int_0
+         %32 = OpAccessChain %_ptr_Workgroup_int %W %uint_0
                OpStore %32 %int_42 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpLoad %uint %main_local_invocation_index_Input None
-         %38 = OpFunctionCall %void %main_inner %37
+       %main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpLoad %uint %main_local_invocation_index_Input None
+         %39 = OpFunctionCall %void %main_inner %38
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1776.spvasm.expected.dxc.hlsl b/test/tint/bug/tint/1776.spvasm.expected.dxc.hlsl
index 03495e0..4129c6c 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1776.spvasm.expected.dxc.hlsl
@@ -6,12 +6,15 @@
 ByteAddressBuffer sb : register(t0);
 
 S sb_load(uint offset) {
-  S tint_symbol = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
-  return tint_symbol;
+  S tint_symbol_3 = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
+  return tint_symbol_3;
 }
 
 void main_1() {
-  S x_18 = sb_load(32u);
+  uint tint_symbol_1 = 0u;
+  sb.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 32u);
+  S x_18 = sb_load((32u * min(1u, (tint_symbol_2 - 1u))));
   return;
 }
 
diff --git a/test/tint/bug/tint/1776.spvasm.expected.fxc.hlsl b/test/tint/bug/tint/1776.spvasm.expected.fxc.hlsl
index 03495e0..4129c6c 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1776.spvasm.expected.fxc.hlsl
@@ -6,12 +6,15 @@
 ByteAddressBuffer sb : register(t0);
 
 S sb_load(uint offset) {
-  S tint_symbol = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
-  return tint_symbol;
+  S tint_symbol_3 = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
+  return tint_symbol_3;
 }
 
 void main_1() {
-  S x_18 = sb_load(32u);
+  uint tint_symbol_1 = 0u;
+  sb.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 32u);
+  S x_18 = sb_load((32u * min(1u, (tint_symbol_2 - 1u))));
   return;
 }
 
diff --git a/test/tint/bug/tint/1776.spvasm.expected.glsl b/test/tint/bug/tint/1776.spvasm.expected.glsl
index d82f0ba..b064827 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.glsl
+++ b/test/tint/bug/tint/1776.spvasm.expected.glsl
@@ -14,7 +14,9 @@
   S inner[];
 } sb;
 void main_1() {
-  S x_18 = sb.inner[1];
+  uint v = (uint(sb.inner.length()) - 1u);
+  uint v_1 = min(uint(1), v);
+  S x_18 = sb.inner[v_1];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1776.spvasm.expected.ir.dxc.hlsl b/test/tint/bug/tint/1776.spvasm.expected.ir.dxc.hlsl
index 57e36ca..8814364 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1776.spvasm.expected.ir.dxc.hlsl
@@ -11,7 +11,10 @@
 }
 
 void main_1() {
-  S x_18 = v(32u);
+  uint v_2 = 0u;
+  sb.GetDimensions(v_2);
+  uint v_3 = ((v_2 / 32u) - 1u);
+  S x_18 = v((0u + (min(uint(int(1)), v_3) * 32u)));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1776.spvasm.expected.ir.fxc.hlsl b/test/tint/bug/tint/1776.spvasm.expected.ir.fxc.hlsl
index 57e36ca..8814364 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1776.spvasm.expected.ir.fxc.hlsl
@@ -11,7 +11,10 @@
 }
 
 void main_1() {
-  S x_18 = v(32u);
+  uint v_2 = 0u;
+  sb.GetDimensions(v_2);
+  uint v_3 = ((v_2 / 32u) - 1u);
+  S x_18 = v((0u + (min(uint(int(1)), v_3) * 32u)));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1776.spvasm.expected.ir.msl b/test/tint/bug/tint/1776.spvasm.expected.ir.msl
index 43ac809..6f9c015 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/1776.spvasm.expected.ir.msl
@@ -25,13 +25,15 @@
 
 struct tint_module_vars_struct {
   const device sb_block* sb;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void main_1(tint_module_vars_struct tint_module_vars) {
-  S const x_18 = (*tint_module_vars.sb).inner[1];
+  uint const v = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u);
+  S const x_18 = (*tint_module_vars.sb).inner[min(uint(1), v)];
 }
 
-kernel void tint_symbol(const device sb_block* sb [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb};
+kernel void tint_symbol(const device sb_block* sb [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   main_1(tint_module_vars);
 }
diff --git a/test/tint/bug/tint/1776.spvasm.expected.msl b/test/tint/bug/tint/1776.spvasm.expected.msl
index 0548772..55c50e7 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.msl
+++ b/test/tint/bug/tint/1776.spvasm.expected.msl
@@ -14,6 +14,10 @@
     T elements[N];
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct S {
   /* 0x0000 */ float4 a;
   /* 0x0010 */ int b;
@@ -24,13 +28,13 @@
   /* 0x0000 */ tint_array<S, 1> inner;
 };
 
-void main_1(const device sb_block* const tint_symbol_1) {
-  S const x_18 = (*(tint_symbol_1)).inner[1];
+void main_1(const device sb_block* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  S const x_18 = (*(tint_symbol_1)).inner[min(1u, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 32u) - 1u))];
   return;
 }
 
-kernel void tint_symbol(const device sb_block* tint_symbol_2 [[buffer(0)]]) {
-  main_1(tint_symbol_2);
+kernel void tint_symbol(const device sb_block* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_4 [[buffer(30)]]) {
+  main_1(tint_symbol_3, tint_symbol_4);
   return;
 }
 
diff --git a/test/tint/bug/tint/1776.spvasm.expected.spvasm b/test/tint/bug/tint/1776.spvasm.expected.spvasm
index a8248ad..c70f29e 100644
--- a/test/tint/bug/tint/1776.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/1776.spvasm.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 22
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -34,18 +35,25 @@
          %sb = OpVariable %_ptr_StorageBuffer_sb_block StorageBuffer
        %void = OpTypeVoid
          %11 = OpTypeFunction %void
-%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
+%_ptr_StorageBuffer__runtimearr_S = OpTypePointer StorageBuffer %_runtimearr_S
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
      %main_1 = OpFunction %void None %11
          %12 = OpLabel
-         %13 = OpAccessChain %_ptr_StorageBuffer_S %sb %uint_0 %int_1
-       %x_18 = OpLoad %S %13 None
+         %13 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %sb %uint_0
+         %17 = OpArrayLength %uint %sb 0
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %20 %18
+         %24 = OpAccessChain %_ptr_StorageBuffer_S %sb %uint_0 %22
+       %x_18 = OpLoad %S %24 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %11
-         %20 = OpLabel
-         %21 = OpFunctionCall %void %main_1
+         %28 = OpLabel
+         %29 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1776.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1776.wgsl.expected.dxc.hlsl
index 441c65d..ac3df7f 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1776.wgsl.expected.dxc.hlsl
@@ -6,12 +6,15 @@
 ByteAddressBuffer sb : register(t0);
 
 S sb_load(uint offset) {
-  S tint_symbol = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
-  return tint_symbol;
+  S tint_symbol_3 = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
+  return tint_symbol_3;
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  S x = sb_load(32u);
+  uint tint_symbol_1 = 0u;
+  sb.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 32u);
+  S x = sb_load((32u * min(1u, (tint_symbol_2 - 1u))));
   return;
 }
diff --git a/test/tint/bug/tint/1776.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1776.wgsl.expected.fxc.hlsl
index 441c65d..ac3df7f 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1776.wgsl.expected.fxc.hlsl
@@ -6,12 +6,15 @@
 ByteAddressBuffer sb : register(t0);
 
 S sb_load(uint offset) {
-  S tint_symbol = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
-  return tint_symbol;
+  S tint_symbol_3 = {asfloat(sb.Load4((offset + 0u))), asint(sb.Load((offset + 16u)))};
+  return tint_symbol_3;
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  S x = sb_load(32u);
+  uint tint_symbol_1 = 0u;
+  sb.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 32u);
+  S x = sb_load((32u * min(1u, (tint_symbol_2 - 1u))));
   return;
 }
diff --git a/test/tint/bug/tint/1776.wgsl.expected.glsl b/test/tint/bug/tint/1776.wgsl.expected.glsl
index 230400c..7de2dd2 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1776.wgsl.expected.glsl
@@ -15,5 +15,7 @@
 } v;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  S x = v.inner[1];
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  S x = v.inner[v_2];
 }
diff --git a/test/tint/bug/tint/1776.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1776.wgsl.expected.ir.dxc.hlsl
index 4cbf0db..8366375 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1776.wgsl.expected.ir.dxc.hlsl
@@ -12,6 +12,9 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  S x = v(32u);
+  uint v_2 = 0u;
+  sb.GetDimensions(v_2);
+  uint v_3 = ((v_2 / 32u) - 1u);
+  S x = v((0u + (min(uint(int(1)), v_3) * 32u)));
 }
 
diff --git a/test/tint/bug/tint/1776.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1776.wgsl.expected.ir.fxc.hlsl
index 4cbf0db..8366375 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1776.wgsl.expected.ir.fxc.hlsl
@@ -12,6 +12,9 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  S x = v(32u);
+  uint v_2 = 0u;
+  sb.GetDimensions(v_2);
+  uint v_3 = ((v_2 / 32u) - 1u);
+  S x = v((0u + (min(uint(int(1)), v_3) * 32u)));
 }
 
diff --git a/test/tint/bug/tint/1776.wgsl.expected.ir.msl b/test/tint/bug/tint/1776.wgsl.expected.ir.msl
index 37ee21d..86fd70f 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1776.wgsl.expected.ir.msl
@@ -21,9 +21,11 @@
 
 struct tint_module_vars_struct {
   const device tint_array<S, 1>* sb;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-kernel void tint_symbol(const device tint_array<S, 1>* sb [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb};
-  S const x = (*tint_module_vars.sb)[1];
+kernel void tint_symbol(const device tint_array<S, 1>* sb [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.sb=sb, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 32u) - 1u);
+  S const x = (*tint_module_vars.sb)[min(uint(1), v)];
 }
diff --git a/test/tint/bug/tint/1776.wgsl.expected.msl b/test/tint/bug/tint/1776.wgsl.expected.msl
index 38097d0..944f6b6 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.msl
+++ b/test/tint/bug/tint/1776.wgsl.expected.msl
@@ -24,8 +24,12 @@
   /* 0x0000 */ tint_array<S, 1> arr;
 };
 
-kernel void tint_symbol(const device tint_symbol_2* tint_symbol_1 [[buffer(0)]]) {
-  S const x = (*(tint_symbol_1)).arr[1];
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+kernel void tint_symbol(const device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]]) {
+  S const x = (*(tint_symbol_1)).arr[min(1u, (((*(tint_symbol_3)).array_lengths[0u][0u] / 32u) - 1u))];
   return;
 }
 
diff --git a/test/tint/bug/tint/1776.wgsl.expected.spvasm b/test/tint/bug/tint/1776.wgsl.expected.spvasm
index 46368bd..0e9657b 100644
--- a/test/tint/bug/tint/1776.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1776.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 19
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -32,13 +33,20 @@
           %1 = OpVariable %_ptr_StorageBuffer_sb_block StorageBuffer
        %void = OpTypeVoid
          %11 = OpTypeFunction %void
-%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
+%_ptr_StorageBuffer__runtimearr_S = OpTypePointer StorageBuffer %_runtimearr_S
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
        %main = OpFunction %void None %11
          %12 = OpLabel
-         %13 = OpAccessChain %_ptr_StorageBuffer_S %1 %uint_0 %int_1
-          %x = OpLoad %S %13 None
+         %13 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %1 %uint_0
+         %17 = OpArrayLength %uint %1 0
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %20 %18
+         %24 = OpAccessChain %_ptr_StorageBuffer_S %1 %uint_0 %22
+          %x = OpLoad %S %24 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1875.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1875.wgsl.expected.dxc.hlsl
index 605200d..4569e43 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1875.wgsl.expected.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer outputs : register(u1);
 
 void push_output(uint value) {
-  outputs.Store((4u * count), asuint(value));
+  uint tint_symbol_1 = 0u;
+  outputs.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 4u);
+  outputs.Store((4u * min(count, (tint_symbol_2 - 1u))), asuint(value));
   count = (count + 1u);
 }
 
diff --git a/test/tint/bug/tint/1875.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1875.wgsl.expected.fxc.hlsl
index 605200d..4569e43 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1875.wgsl.expected.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer outputs : register(u1);
 
 void push_output(uint value) {
-  outputs.Store((4u * count), asuint(value));
+  uint tint_symbol_1 = 0u;
+  outputs.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 4u);
+  outputs.Store((4u * min(count, (tint_symbol_2 - 1u))), asuint(value));
   count = (count + 1u);
 }
 
diff --git a/test/tint/bug/tint/1875.wgsl.expected.glsl b/test/tint/bug/tint/1875.wgsl.expected.glsl
index 815363e..a6f0139 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1875.wgsl.expected.glsl
@@ -7,7 +7,8 @@
 } outputs;
 void push_output(uint value) {
   uint v = count;
-  outputs.data[v] = value;
+  uint v_1 = min(v, (uint(outputs.data.length()) - 1u));
+  outputs.data[v_1] = value;
   count = (count + 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/tint/1875.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1875.wgsl.expected.ir.dxc.hlsl
index 74a3dd0..e723654 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1875.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 static uint count = 0u;
 RWByteAddressBuffer outputs : register(u1);
 void push_output(uint value) {
-  outputs.Store((0u + (count * 4u)), value);
+  uint v = 0u;
+  outputs.GetDimensions(v);
+  outputs.Store((0u + (min(count, ((v / 4u) - 1u)) * 4u)), value);
   count = (count + 1u);
 }
 
diff --git a/test/tint/bug/tint/1875.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1875.wgsl.expected.ir.fxc.hlsl
index 74a3dd0..e723654 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1875.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 static uint count = 0u;
 RWByteAddressBuffer outputs : register(u1);
 void push_output(uint value) {
-  outputs.Store((0u + (count * 4u)), value);
+  uint v = 0u;
+  outputs.GetDimensions(v);
+  outputs.Store((0u + (min(count, ((v / 4u) - 1u)) * 4u)), value);
   count = (count + 1u);
 }
 
diff --git a/test/tint/bug/tint/1875.wgsl.expected.ir.msl b/test/tint/bug/tint/1875.wgsl.expected.ir.msl
index 4200fee..5670822 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1875.wgsl.expected.ir.msl
@@ -20,16 +20,17 @@
 struct tint_module_vars_struct {
   thread uint* count;
   device Outputs* outputs;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void push_output(uint value, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.outputs).data[(*tint_module_vars.count)] = value;
+  (*tint_module_vars.outputs).data[min((*tint_module_vars.count), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))] = value;
   (*tint_module_vars.count) = ((*tint_module_vars.count) + 1u);
 }
 
-kernel void tint_symbol(device Outputs* outputs [[buffer(0)]]) {
+kernel void tint_symbol(device Outputs* outputs [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread uint count = 0u;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.count=(&count), .outputs=outputs};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.count=(&count), .outputs=outputs, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   uint a = 0u;
   uint b = 10u;
   uint c = 4294967294u;
diff --git a/test/tint/bug/tint/1875.wgsl.expected.msl b/test/tint/bug/tint/1875.wgsl.expected.msl
index f3abb69..5c10b9c 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.msl
+++ b/test/tint/bug/tint/1875.wgsl.expected.msl
@@ -18,16 +18,20 @@
   uint count;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Outputs {
   /* 0x0000 */ tint_array<uint, 1> data;
 };
 
-void push_output(uint value, thread tint_private_vars_struct* const tint_private_vars, device Outputs* const tint_symbol_1) {
-  (*(tint_symbol_1)).data[(*(tint_private_vars)).count] = value;
+void push_output(uint value, thread tint_private_vars_struct* const tint_private_vars, device Outputs* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  (*(tint_symbol_1)).data[min((*(tint_private_vars)).count, ((((*(tint_symbol_2)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] = value;
   (*(tint_private_vars)).count = ((*(tint_private_vars)).count + 1u);
 }
 
-kernel void tint_symbol(device Outputs* tint_symbol_2 [[buffer(0)]]) {
+kernel void tint_symbol(device Outputs* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_4 [[buffer(30)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
   tint_private_vars.count = 0u;
   uint a = 0u;
@@ -36,9 +40,9 @@
   a = (a + 1u);
   b = (b + 1u);
   c = (c + 1u);
-  push_output(a, &(tint_private_vars), tint_symbol_2);
-  push_output(b, &(tint_private_vars), tint_symbol_2);
-  push_output(c, &(tint_private_vars), tint_symbol_2);
+  push_output(a, &(tint_private_vars), tint_symbol_3, tint_symbol_4);
+  push_output(b, &(tint_private_vars), tint_symbol_3, tint_symbol_4);
+  push_output(c, &(tint_private_vars), tint_symbol_3, tint_symbol_4);
   return;
 }
 
diff --git a/test/tint/bug/tint/1875.wgsl.expected.spvasm b/test/tint/bug/tint/1875.wgsl.expected.spvasm
index 4d9a9fd..015f82e 100644
--- a/test/tint/bug/tint/1875.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1875.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -33,9 +34,10 @@
     %outputs = OpVariable %_ptr_StorageBuffer_Outputs StorageBuffer
        %void = OpTypeVoid
          %12 = OpTypeFunction %void %uint
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_1 = OpConstant %uint 1
-         %21 = OpTypeFunction %void
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+         %27 = OpTypeFunction %void
 %_ptr_Function_uint = OpTypePointer Function %uint
     %uint_10 = OpConstant %uint 10
 %uint_4294967294 = OpConstant %uint 4294967294
@@ -43,35 +45,39 @@
       %value = OpFunctionParameter %uint
          %13 = OpLabel
          %14 = OpLoad %uint %count None
-         %15 = OpAccessChain %_ptr_StorageBuffer_uint %outputs %uint_0 %14
-               OpStore %15 %value None
-         %17 = OpLoad %uint %count None
-         %18 = OpIAdd %uint %17 %uint_1
-               OpStore %count %18 None
+         %15 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %outputs %uint_0
+         %17 = OpArrayLength %uint %outputs 0
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpExtInst %uint %21 UMin %14 %18
+         %22 = OpAccessChain %_ptr_StorageBuffer_uint %outputs %uint_0 %20
+               OpStore %22 %value None
+         %24 = OpLoad %uint %count None
+         %25 = OpIAdd %uint %24 %uint_1
+               OpStore %count %25 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %21
-         %22 = OpLabel
+       %main = OpFunction %void None %27
+         %28 = OpLabel
           %a = OpVariable %_ptr_Function_uint Function
           %b = OpVariable %_ptr_Function_uint Function
           %c = OpVariable %_ptr_Function_uint Function
                OpStore %a %uint_0
                OpStore %b %uint_10
                OpStore %c %uint_4294967294
-         %29 = OpLoad %uint %a None
-         %30 = OpIAdd %uint %29 %uint_1
-               OpStore %a %30 None
-         %31 = OpLoad %uint %b None
-         %32 = OpIAdd %uint %31 %uint_1
-               OpStore %b %32 None
-         %33 = OpLoad %uint %c None
-         %34 = OpIAdd %uint %33 %uint_1
-               OpStore %c %34 None
          %35 = OpLoad %uint %a None
-         %36 = OpFunctionCall %void %push_output %35
+         %36 = OpIAdd %uint %35 %uint_1
+               OpStore %a %36 None
          %37 = OpLoad %uint %b None
-         %38 = OpFunctionCall %void %push_output %37
+         %38 = OpIAdd %uint %37 %uint_1
+               OpStore %b %38 None
          %39 = OpLoad %uint %c None
-         %40 = OpFunctionCall %void %push_output %39
+         %40 = OpIAdd %uint %39 %uint_1
+               OpStore %c %40 None
+         %41 = OpLoad %uint %a None
+         %42 = OpFunctionCall %void %push_output %41
+         %43 = OpLoad %uint %b None
+         %44 = OpFunctionCall %void %push_output %43
+         %45 = OpLoad %uint %c None
+         %46 = OpFunctionCall %void %push_output %45
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1934.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1934.wgsl.expected.dxc.hlsl
index 0f32de2..7208ab1 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/1934.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 void v() {
   int i = 1;
-  int b = (1).xx[i];
+  int b = (1).xx[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/tint/1934.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1934.wgsl.expected.fxc.hlsl
index 0f32de2..7208ab1 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/1934.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 void v() {
   int i = 1;
-  int b = (1).xx[i];
+  int b = (1).xx[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/tint/1934.wgsl.expected.glsl b/test/tint/bug/tint/1934.wgsl.expected.glsl
index 1d0633e..2a64645 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1934.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 void v() {
   int i = 1;
-  int b = ivec2(1)[i];
+  int b = ivec2(1)[min(uint(i), 1u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/1934.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1934.wgsl.expected.ir.dxc.hlsl
index a9374ec..d2ac7ef 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1934.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 void v() {
   int i = int(1);
-  int b = (int(1)).xx[i];
+  int b = (int(1)).xx[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1934.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1934.wgsl.expected.ir.fxc.hlsl
index a9374ec..d2ac7ef 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1934.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 void v() {
   int i = int(1);
-  int b = (int(1)).xx[i];
+  int b = (int(1)).xx[min(uint(i), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/1934.wgsl.expected.ir.msl b/test/tint/bug/tint/1934.wgsl.expected.ir.msl
index 64bafba..61cd140 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1934.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 void v() {
   int const i = 1;
-  int b = int2(1)[i];
+  int b = int2(1)[min(uint(i), 1u)];
 }
diff --git a/test/tint/bug/tint/1934.wgsl.expected.msl b/test/tint/bug/tint/1934.wgsl.expected.msl
index 0cb3d1a..5e44f5d 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.msl
+++ b/test/tint/bug/tint/1934.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 void v() {
   int const i = 1;
-  int b = int2(1)[i];
+  int b = int2(1)[min(uint(i), 1u)];
 }
 
diff --git a/test/tint/bug/tint/1934.wgsl.expected.spvasm b/test/tint/bug/tint/1934.wgsl.expected.spvasm
index 689183c..7777775 100644
--- a/test/tint/bug/tint/1934.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1934.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 14
+; Bound: 19
 ; Schema: 0
                OpCapability Shader
+         %10 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -15,17 +16,21 @@
           %3 = OpTypeFunction %void
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %v2int = OpTypeVector %int 2
-          %8 = OpConstantComposite %v2int %i %i
+         %13 = OpConstantComposite %v2int %i %i
 %_ptr_Function_int = OpTypePointer Function %int
           %v = OpFunction %void None %3
           %4 = OpLabel
           %b = OpVariable %_ptr_Function_int Function
-          %7 = OpVectorExtractDynamic %int %8 %i
-               OpStore %b %7
+          %8 = OpBitcast %uint %i
+          %9 = OpExtInst %uint %10 UMin %8 %uint_1
+         %12 = OpVectorExtractDynamic %int %13 %9
+               OpStore %b %12
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %3
-         %13 = OpLabel
+         %18 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/1976.wgsl.expected.glsl b/test/tint/bug/tint/1976.wgsl.expected.glsl
index 2a9e602..e8d3a58 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.glsl
+++ b/test/tint/bug/tint/1976.wgsl.expected.glsl
@@ -12,6 +12,7 @@
 uniform highp sampler2DMS texture0;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  ivec2 v_1 = ivec2(ivec2(0));
-  v.inner.colorSamples[0] = texelFetch(texture0, v_1, int(0))[0u];
+  uvec2 v_1 = (uvec2(textureSize(texture0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(0)), v_1));
+  v.inner.colorSamples[0u] = texelFetch(texture0, v_2, int(0))[0u];
 }
diff --git a/test/tint/bug/tint/1976.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/1976.wgsl.expected.ir.dxc.hlsl
index 0b0a3cb..2edea59 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/1976.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWByteAddressBuffer results : register(u2);
 [numthreads(1, 1, 1)]
 void main() {
-  int2 v = int2((int(0)).xx);
-  results.Store(0u, asuint(float4(texture0.Load(v, int(int(0)))).x));
+  uint3 v = (0u).xxx;
+  texture0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(0)).xx), v_1));
+  results.Store(0u, asuint(float4(texture0.Load(v_2, int(int(0)))).x));
 }
 
diff --git a/test/tint/bug/tint/1976.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/1976.wgsl.expected.ir.fxc.hlsl
index 0b0a3cb..2edea59 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/1976.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWByteAddressBuffer results : register(u2);
 [numthreads(1, 1, 1)]
 void main() {
-  int2 v = int2((int(0)).xx);
-  results.Store(0u, asuint(float4(texture0.Load(v, int(int(0)))).x));
+  uint3 v = (0u).xxx;
+  texture0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(0)).xx), v_1));
+  results.Store(0u, asuint(float4(texture0.Load(v_2, int(int(0)))).x));
 }
 
diff --git a/test/tint/bug/tint/1976.wgsl.expected.ir.msl b/test/tint/bug/tint/1976.wgsl.expected.ir.msl
index f8f0209..3f40776 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/1976.wgsl.expected.ir.msl
@@ -24,5 +24,6 @@
 
 kernel void tint_symbol(texture2d_ms<float, access::read> texture0 [[texture(0)]], device Results* results [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.texture0=texture0, .results=results};
-  (*tint_module_vars.results).colorSamples[0] = tint_module_vars.texture0.read(uint2(int2(0)), 0)[0u];
+  uint2 const v = (uint2(tint_module_vars.texture0.get_width(), tint_module_vars.texture0.get_height()) - uint2(1u));
+  (*tint_module_vars.results).colorSamples[0u] = tint_module_vars.texture0.read(min(uint2(int2(0)), v), 0)[0u];
 }
diff --git a/test/tint/bug/tint/1976.wgsl.expected.msl b/test/tint/bug/tint/1976.wgsl.expected.msl
index 00d4950..d48d7dc 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.msl
+++ b/test/tint/bug/tint/1976.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 struct Results {
   /* 0x0000 */ tint_array<float, 4> colorSamples;
 };
 
 kernel void tint_symbol(device Results* tint_symbol_1 [[buffer(0)]], texture2d_ms<float, access::read> tint_symbol_2 [[texture(0)]]) {
-  (*(tint_symbol_1)).colorSamples[0] = tint_symbol_2.read(uint2(int2(0)), 0)[0];
+  (*(tint_symbol_1)).colorSamples[0] = tint_symbol_2.read(uint2(tint_clamp(int2(0), int2(0), int2((uint2(tint_symbol_2.get_width(), tint_symbol_2.get_height()) - uint2(1u))))), 0)[0];
   return;
 }
 
diff --git a/test/tint/bug/tint/1976.wgsl.expected.spvasm b/test/tint/bug/tint/1976.wgsl.expected.spvasm
index 8a2aad5..7fd8c33 100644
--- a/test/tint/bug/tint/1976.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/1976.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -37,17 +39,24 @@
          %14 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-    %v4float = OpTypeVector %float 4
       %v2int = OpTypeVector %int 2
-         %24 = OpConstantNull %v2int
+         %26 = OpConstantNull %v2int
+    %v4float = OpTypeVector %float 4
+      %int_0 = OpConstant %int 0
        %main = OpFunction %void None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_StorageBuffer_float %5 %uint_0 %uint_0 %int_0
-         %21 = OpLoad %3 %texture0 None
-         %22 = OpImageFetch %v4float %21 %24 Sample %int_0
-         %26 = OpCompositeExtract %float %22 0
-               OpStore %16 %26 None
+         %16 = OpAccessChain %_ptr_StorageBuffer_float %5 %uint_0 %uint_0 %uint_0
+         %19 = OpLoad %3 %texture0 None
+         %20 = OpImageQuerySize %v2uint %19
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %26
+         %29 = OpExtInst %v2uint %30 UMin %25 %22
+         %31 = OpImageFetch %v4float %19 %29 Sample %int_0
+         %34 = OpCompositeExtract %float %31 0
+               OpStore %16 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2010.spvasm.expected.glsl b/test/tint/bug/tint/2010.spvasm.expected.glsl
index 2d8001e..7b93295 100644
--- a/test/tint/bug/tint/2010.spvasm.expected.glsl
+++ b/test/tint/bug/tint/2010.spvasm.expected.glsl
@@ -49,8 +49,9 @@
       }
       uint x_62 = (x_54 + x_52);
       if ((x_62 >= x_58)) {
-        vec4 x_67 = x_9.field0[x_62];
-        x_28[x_62] = S(((x_67.xy + x_67.zw) * 0.5f), x_62);
+        uint v_1 = min(x_62, (uint(x_9.field0.length()) - 1u));
+        vec4 x_67 = x_9.field0[v_1];
+        x_28[min(x_62, 4095u)] = S(((x_67.xy + x_67.zw) * 0.5f), x_62);
       }
       {
         x_55 = (x_54 + 32u);
@@ -61,7 +62,7 @@
   }
   barrier();
   int x_74 = int(x_58);
-  vec2 x_76 = x_28[0].field0;
+  vec2 x_76 = x_28[0u].field0;
   if ((x_52 == 0u)) {
     uvec2 x_80 = floatBitsToUint(x_76);
     uint x_81 = x_80[0u];
@@ -86,7 +87,7 @@
       uint x_94 = (x_88 + x_52);
       x_86 = x_85;
       if ((x_94 >= x_90)) {
-        vec2 x_99 = x_28[x_94].field0;
+        vec2 x_99 = x_28[min(x_94, 4095u)].field0;
         vec2 x_101 = min(x_85.xy, x_99);
         vec4 x_103_1 = x_85;
         x_103_1[0u] = x_101[0u];
@@ -115,10 +116,12 @@
   uint x_120 = atomicMax(x_36, floatBitsToUint(x_85.z));
   uint x_123 = atomicMax(x_37, floatBitsToUint(x_85.w));
   barrier();
-  float v_1 = uintBitsToFloat(atomicOr(x_34, 0u));
-  float v_2 = uintBitsToFloat(atomicOr(x_35, 0u));
-  float v_3 = uintBitsToFloat(atomicOr(x_36, 0u));
-  x_12.field0[0] = vec4(v_1, v_2, v_3, uintBitsToFloat(atomicOr(x_37, 0u)));
+  uint v_2 = (uint(x_12.field0.length()) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  float v_4 = uintBitsToFloat(atomicOr(x_34, 0u));
+  float v_5 = uintBitsToFloat(atomicOr(x_35, 0u));
+  float v_6 = uintBitsToFloat(atomicOr(x_36, 0u));
+  x_12.field0[v_3] = vec4(v_4, v_5, v_6, uintBitsToFloat(atomicOr(x_37, 0u)));
 }
 void tint_symbol_inner(uvec3 x_3_param, uint tint_local_index) {
   if ((tint_local_index < 1u)) {
@@ -128,16 +131,16 @@
     atomicExchange(x_37, 0u);
   }
   {
-    uint v_4 = 0u;
-    v_4 = tint_local_index;
+    uint v_7 = 0u;
+    v_7 = tint_local_index;
     while(true) {
-      uint v_5 = v_4;
-      if ((v_5 >= 4096u)) {
+      uint v_8 = v_7;
+      if ((v_8 >= 4096u)) {
         break;
       }
-      x_28[v_5] = S(vec2(0.0f), 0u);
+      x_28[v_8] = S(vec2(0.0f), 0u);
       {
-        v_4 = (v_5 + 32u);
+        v_7 = (v_8 + 32u);
       }
       continue;
     }
diff --git a/test/tint/bug/tint/2010.spvasm.expected.ir.msl b/test/tint/bug/tint/2010.spvasm.expected.ir.msl
index 96102ed..c9fa8dc 100644
--- a/test/tint/bug/tint/2010.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/2010.spvasm.expected.ir.msl
@@ -44,8 +44,12 @@
   const constant S_2* x_6;
   const device S_3* x_9;
   device S_4* x_12;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_6 {
   tint_array<S, 4096> tint_symbol_1;
   atomic_uint tint_symbol_2;
@@ -63,6 +67,7 @@
   x_54 = 0u;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint x_55 = 0u;
       x_58 = (*tint_module_vars.x_6).field0.field0;
       if ((x_54 < x_58)) {
@@ -71,8 +76,8 @@
       }
       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};
+        float4 const x_67 = (*tint_module_vars.x_9).field0[min(x_62, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 16u) - 1u))];
+        (*tint_module_vars.x_28)[min(x_62, 4095u)] = S{.field0=((x_67.xy + x_67.zw) * 0.5f), .field1=x_62};
       }
       {
         x_55 = (x_54 + 32u);
@@ -83,7 +88,7 @@
   }
   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;
+  float2 const x_76 = (*tint_module_vars.x_28)[0u].field0;
   if ((x_52 == 0u)) {
     uint2 const x_80 = as_type<uint2>(x_76);
     uint const x_81 = x_80[0u];
@@ -97,6 +102,7 @@
   x_88 = 1u;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       float4 x_111 = 0.0f;
       float4 x_86 = 0.0f;
       uint x_89 = 0u;
@@ -108,7 +114,7 @@
       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_99 = (*tint_module_vars.x_28)[min(x_94, 4095u)].field0;
         float2 const x_101 = min(x_85.xy, x_99);
         float4 x_103_1 = x_85;
         x_103_1[0u] = x_101[0u];
@@ -137,7 +143,9 @@
   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);
-  (*tint_module_vars.x_12).field0[0] = float4(as_type<float>(atomic_load_explicit(tint_module_vars.x_34, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_35, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_36, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_37, memory_order_relaxed)));
+  uint const v = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 16u) - 1u);
+  device float4* const v_1 = (&(*tint_module_vars.x_12).field0[min(uint(0), v)]);
+  (*v_1) = float4(as_type<float>(atomic_load_explicit(tint_module_vars.x_34, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_35, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_36, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_module_vars.x_37, memory_order_relaxed)));
 }
 
 void tint_symbol_inner(uint3 x_3_param, uint tint_local_index, tint_module_vars_struct tint_module_vars) {
@@ -148,16 +156,17 @@
     atomic_store_explicit(tint_module_vars.x_37, 0u, memory_order_relaxed);
   }
   {
-    uint v = 0u;
-    v = tint_local_index;
+    uint v_2 = 0u;
+    v_2 = tint_local_index;
     while(true) {
-      uint const v_1 = v;
-      if ((v_1 >= 4096u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_2)
+      uint const v_3 = v_2;
+      if ((v_3 >= 4096u)) {
         break;
       }
-      (*tint_module_vars.x_28)[v_1] = S{};
+      (*tint_module_vars.x_28)[v_3] = S{};
       {
-        v = (v_1 + 32u);
+        v_2 = (v_3 + 32u);
       }
       continue;
     }
@@ -167,8 +176,8 @@
   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_2 [[threadgroup(0)]], const constant S_2* x_6 [[buffer(0)]], const device S_3* x_9 [[buffer(2)]], device S_4* x_12 [[buffer(1)]]) {
+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_4 [[threadgroup(0)]], const constant S_2* x_6 [[buffer(0)]], const device S_3* x_9 [[buffer(2)]], device S_4* x_12 [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread uint3 x_3 = 0u;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.x_28=(&(*v_2).tint_symbol_1), .x_34=(&(*v_2).tint_symbol_2), .x_35=(&(*v_2).tint_symbol_3), .x_36=(&(*v_2).tint_symbol_4), .x_37=(&(*v_2).tint_symbol_5), .x_3=(&x_3), .x_6=x_6, .x_9=x_9, .x_12=x_12};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.x_28=(&(*v_4).tint_symbol_1), .x_34=(&(*v_4).tint_symbol_2), .x_35=(&(*v_4).tint_symbol_3), .x_36=(&(*v_4).tint_symbol_4), .x_37=(&(*v_4).tint_symbol_5), .x_3=(&x_3), .x_6=x_6, .x_9=x_9, .x_12=x_12, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(x_3_param, tint_local_index, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/2010.spvasm.expected.msl b/test/tint/bug/tint/2010.spvasm.expected.msl
index b445f40..229ebec 100644
--- a/test/tint/bug/tint/2010.spvasm.expected.msl
+++ b/test/tint/bug/tint/2010.spvasm.expected.msl
@@ -14,10 +14,17 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint3 x_3;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct S {
   float2 field0;
   uint field1;
@@ -31,6 +38,7 @@
     atomic_store_explicit(tint_symbol_6, 0u, memory_order_relaxed);
   }
   for(uint idx = local_idx; (idx < 4096u); idx = (idx + 32u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     S const tint_symbol_1 = S{};
     (*(tint_symbol_7))[i] = tint_symbol_1;
@@ -54,7 +62,7 @@
   /* 0x0000 */ tint_array<float4, 1> field0;
 };
 
-void main_1(thread tint_private_vars_struct* const tint_private_vars, const constant S_2* const tint_symbol_8, const device S_3* const tint_symbol_9, threadgroup tint_array<S, 4096>* const tint_symbol_10, threadgroup atomic_uint* const tint_symbol_11, threadgroup atomic_uint* const tint_symbol_12, threadgroup atomic_uint* const tint_symbol_13, threadgroup atomic_uint* const tint_symbol_14, device S_4* const tint_symbol_15) {
+void main_1(thread tint_private_vars_struct* const tint_private_vars, const constant S_2* const tint_symbol_8, const device S_3* const tint_symbol_9, const constant TintArrayLengths* const tint_symbol_10, threadgroup tint_array<S, 4096>* const tint_symbol_11, threadgroup atomic_uint* const tint_symbol_12, threadgroup atomic_uint* const tint_symbol_13, threadgroup atomic_uint* const tint_symbol_14, threadgroup atomic_uint* const tint_symbol_15, device S_4* const tint_symbol_16) {
   uint x_54 = 0u;
   uint x_58 = 0u;
   float4 x_85 = 0.0f;
@@ -62,6 +70,7 @@
   uint const x_52 = (*(tint_private_vars)).x_3[0];
   x_54 = 0u;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     uint x_55 = 0u;
     x_58 = (*(tint_symbol_8)).field0.field0;
     if ((x_54 < x_58)) {
@@ -70,9 +79,9 @@
     }
     uint const x_62 = (x_54 + x_52);
     if ((x_62 >= x_58)) {
-      float4 const x_67 = (*(tint_symbol_9)).field0[x_62];
+      float4 const x_67 = (*(tint_symbol_9)).field0[min(x_62, ((((*(tint_symbol_10)).array_lengths[0u][0u] - 0u) / 16u) - 1u))];
       S const tint_symbol_2 = S{.field0=((x_67.xy + x_67.zw) * 0.5f), .field1=x_62};
-      (*(tint_symbol_10))[x_62] = tint_symbol_2;
+      (*(tint_symbol_11))[min(x_62, 4095u)] = tint_symbol_2;
     }
     {
       x_55 = (x_54 + 32u);
@@ -81,19 +90,20 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   int const x_74 = as_type<int>(x_58);
-  float2 const x_76 = (*(tint_symbol_10))[0].field0;
+  float2 const x_76 = (*(tint_symbol_11))[0].field0;
   if ((x_52 == 0u)) {
     uint2 const x_80 = as_type<uint2>(x_76);
     uint const x_81 = x_80[0];
-    atomic_store_explicit(tint_symbol_11, x_81, memory_order_relaxed);
+    atomic_store_explicit(tint_symbol_12, x_81, memory_order_relaxed);
     uint const x_82 = x_80[1];
-    atomic_store_explicit(tint_symbol_12, x_82, memory_order_relaxed);
-    atomic_store_explicit(tint_symbol_13, x_81, memory_order_relaxed);
-    atomic_store_explicit(tint_symbol_14, x_82, memory_order_relaxed);
+    atomic_store_explicit(tint_symbol_13, x_82, memory_order_relaxed);
+    atomic_store_explicit(tint_symbol_14, x_81, memory_order_relaxed);
+    atomic_store_explicit(tint_symbol_15, x_82, memory_order_relaxed);
   }
   x_85 = x_76.xyxy;
   x_88 = 1u;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_2);
     float4 x_111 = 0.0f;
     float4 x_86 = 0.0f;
     uint x_89 = 0u;
@@ -105,7 +115,7 @@
     uint const x_94 = (x_88 + x_52);
     x_86 = x_85;
     if ((x_94 >= x_90)) {
-      float2 const x_99 = (*(tint_symbol_10))[x_94].field0;
+      float2 const x_99 = (*(tint_symbol_11))[min(x_94, 4095u)].field0;
       float2 const x_101 = fmin(x_85.xy, x_99);
       float4 x_103_1 = x_85;
       x_103_1[0] = x_101[0];
@@ -127,29 +137,29 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  uint const x_114 = atomic_fetch_min_explicit(tint_symbol_11, as_type<uint>(x_85[0]), memory_order_relaxed);
-  uint const x_117 = atomic_fetch_min_explicit(tint_symbol_12, as_type<uint>(x_85[1]), memory_order_relaxed);
-  uint const x_120 = atomic_fetch_max_explicit(tint_symbol_13, as_type<uint>(x_85[2]), memory_order_relaxed);
-  uint const x_123 = atomic_fetch_max_explicit(tint_symbol_14, as_type<uint>(x_85[3]), memory_order_relaxed);
+  uint const x_114 = atomic_fetch_min_explicit(tint_symbol_12, as_type<uint>(x_85[0]), memory_order_relaxed);
+  uint const x_117 = atomic_fetch_min_explicit(tint_symbol_13, as_type<uint>(x_85[1]), memory_order_relaxed);
+  uint const x_120 = atomic_fetch_max_explicit(tint_symbol_14, as_type<uint>(x_85[2]), memory_order_relaxed);
+  uint const x_123 = atomic_fetch_max_explicit(tint_symbol_15, as_type<uint>(x_85[3]), memory_order_relaxed);
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  (*(tint_symbol_15)).field0[0] = float4(as_type<float>(atomic_load_explicit(tint_symbol_11, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_12, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_13, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_14, memory_order_relaxed)));
+  (*(tint_symbol_16)).field0[min(0u, ((((*(tint_symbol_10)).array_lengths[0u][1u] - 0u) / 16u) - 1u))] = float4(as_type<float>(atomic_load_explicit(tint_symbol_12, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_13, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_14, memory_order_relaxed)), as_type<float>(atomic_load_explicit(tint_symbol_15, memory_order_relaxed)));
   return;
 }
 
-void tint_symbol_inner(uint3 x_3_param, uint local_invocation_index, thread tint_private_vars_struct* const tint_private_vars, threadgroup atomic_uint* const tint_symbol_16, threadgroup atomic_uint* const tint_symbol_17, threadgroup atomic_uint* const tint_symbol_18, threadgroup atomic_uint* const tint_symbol_19, threadgroup tint_array<S, 4096>* const tint_symbol_20, const constant S_2* const tint_symbol_21, const device S_3* const tint_symbol_22, device S_4* const tint_symbol_23) {
-  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
+void tint_symbol_inner(uint3 x_3_param, uint local_invocation_index, thread tint_private_vars_struct* const tint_private_vars, threadgroup atomic_uint* const tint_symbol_17, threadgroup atomic_uint* const tint_symbol_18, threadgroup atomic_uint* const tint_symbol_19, threadgroup atomic_uint* const tint_symbol_20, threadgroup tint_array<S, 4096>* const tint_symbol_21, const constant S_2* const tint_symbol_22, const device S_3* const tint_symbol_23, const constant TintArrayLengths* const tint_symbol_24, device S_4* const tint_symbol_25) {
+  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21);
   (*(tint_private_vars)).x_3 = x_3_param;
-  main_1(tint_private_vars, tint_symbol_21, tint_symbol_22, tint_symbol_20, tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_23);
+  main_1(tint_private_vars, tint_symbol_22, tint_symbol_23, tint_symbol_24, tint_symbol_21, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_25);
 }
 
-kernel void tint_symbol(const constant S_2* tint_symbol_29 [[buffer(0)]], const device S_3* tint_symbol_30 [[buffer(2)]], device S_4* tint_symbol_31 [[buffer(1)]], uint3 x_3_param [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
+kernel void tint_symbol(const constant S_2* tint_symbol_31 [[buffer(0)]], const device S_3* tint_symbol_32 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_33 [[buffer(30)]], device S_4* tint_symbol_34 [[buffer(1)]], uint3 x_3_param [[thread_position_in_threadgroup]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  threadgroup atomic_uint tint_symbol_24;
-  threadgroup atomic_uint tint_symbol_25;
   threadgroup atomic_uint tint_symbol_26;
   threadgroup atomic_uint tint_symbol_27;
-  threadgroup tint_array<S, 4096> tint_symbol_28;
-  tint_symbol_inner(x_3_param, local_invocation_index, &(tint_private_vars), &(tint_symbol_24), &(tint_symbol_25), &(tint_symbol_26), &(tint_symbol_27), &(tint_symbol_28), tint_symbol_29, tint_symbol_30, tint_symbol_31);
+  threadgroup atomic_uint tint_symbol_28;
+  threadgroup atomic_uint tint_symbol_29;
+  threadgroup tint_array<S, 4096> tint_symbol_30;
+  tint_symbol_inner(x_3_param, local_invocation_index, &(tint_private_vars), &(tint_symbol_26), &(tint_symbol_27), &(tint_symbol_28), &(tint_symbol_29), &(tint_symbol_30), tint_symbol_31, tint_symbol_32, tint_symbol_33, tint_symbol_34);
   return;
 }
 
diff --git a/test/tint/bug/tint/2010.spvasm.expected.spvasm b/test/tint/bug/tint/2010.spvasm.expected.spvasm
index e36da35..6fc8747 100644
--- a/test/tint/bug/tint/2010.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/2010.spvasm.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 218
+; Bound: 232
 ; Schema: 0
                OpCapability Shader
-        %132 = OpExtInstImport "GLSL.std.450"
+         %77 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_id_Input %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 32 1 1
@@ -133,7 +133,10 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
        %bool = OpTypeBool
+%_ptr_StorageBuffer__runtimearr_v4float = OpTypePointer StorageBuffer %_runtimearr_v4float
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
+  %uint_4095 = OpConstant %uint 4095
 %_ptr_Workgroup_S = OpTypePointer Workgroup %S
   %float_0_5 = OpConstant %float 0.5
     %uint_32 = OpConstant %uint 32
@@ -141,14 +144,14 @@
    %uint_264 = OpConstant %uint 264
         %int = OpTypeInt 32 1
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-      %int_0 = OpConstant %int 0
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_float = OpTypePointer Function %float
      %uint_3 = OpConstant %uint 3
+%_ptr_StorageBuffer__runtimearr_v4float_0 = OpTypePointer StorageBuffer %_runtimearr_v4float
+      %int_0 = OpConstant %int 0
 %_ptr_StorageBuffer_v4float_0 = OpTypePointer StorageBuffer %v4float
-        %190 = OpTypeFunction %void %v3uint %uint
-        %210 = OpConstantNull %S
+        %204 = OpTypeFunction %void %v3uint %uint
+        %224 = OpConstantNull %S
      %main_1 = OpFunction %void None %37
          %38 = OpLabel
        %x_54 = OpVariable %_ptr_Function_uint Function %41
@@ -188,35 +191,40 @@
                OpSelectionMerge %69 None
                OpBranchConditional %68 %70 %69
          %70 = OpLabel
-         %71 = OpAccessChain %_ptr_StorageBuffer_v4float %x_9 %uint_0 %x_62
-       %x_67 = OpLoad %v4float %71 None
-         %74 = OpAccessChain %_ptr_Workgroup_S %x_28 %x_62
-         %76 = OpVectorShuffle %v2float %x_67 %x_67 0 1
-         %77 = OpVectorShuffle %v2float %x_67 %x_67 2 3
-         %78 = OpFAdd %v2float %76 %77
-         %79 = OpVectorTimesScalar %v2float %78 %float_0_5
-         %81 = OpCompositeConstruct %S %79 %x_62
-               OpStore %74 %81 None
+         %71 = OpAccessChain %_ptr_StorageBuffer__runtimearr_v4float %x_9 %uint_0
+         %73 = OpArrayLength %uint %x_9 0
+         %74 = OpISub %uint %73 %uint_1
+         %76 = OpExtInst %uint %77 UMin %x_62 %74
+         %78 = OpAccessChain %_ptr_StorageBuffer_v4float %x_9 %uint_0 %76
+       %x_67 = OpLoad %v4float %78 None
+         %81 = OpExtInst %uint %77 UMin %x_62 %uint_4095
+         %83 = OpAccessChain %_ptr_Workgroup_S %x_28 %81
+         %85 = OpVectorShuffle %v2float %x_67 %x_67 0 1
+         %86 = OpVectorShuffle %v2float %x_67 %x_67 2 3
+         %87 = OpFAdd %v2float %85 %86
+         %88 = OpVectorTimesScalar %v2float %87 %float_0_5
+         %90 = OpCompositeConstruct %S %88 %x_62
+               OpStore %83 %90 None
                OpBranch %69
          %69 = OpLabel
                OpBranch %52
          %52 = OpLabel
-         %82 = OpLoad %uint %x_54 None
-         %83 = OpIAdd %uint %82 %uint_32
-               OpStore %x_55 %83 None
-         %85 = OpLoad %uint %x_55 None
-               OpStore %x_54 %85 None
+         %91 = OpLoad %uint %x_54 None
+         %92 = OpIAdd %uint %91 %uint_32
+               OpStore %x_55 %92 None
+         %94 = OpLoad %uint %x_55 None
+               OpStore %x_54 %94 None
                OpBranch %53
          %54 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %89 = OpLoad %uint %x_58 None
-       %x_74 = OpBitcast %int %89
-         %92 = OpAccessChain %_ptr_Workgroup_v2float %x_28 %int_0 %uint_0
-       %x_76 = OpLoad %v2float %92 None
-         %96 = OpIEqual %bool %x_52 %uint_0
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %97
-         %98 = OpLabel
+         %98 = OpLoad %uint %x_58 None
+       %x_74 = OpBitcast %int %98
+        %101 = OpAccessChain %_ptr_Workgroup_v2float %x_28 %uint_0 %uint_0
+       %x_76 = OpLoad %v2float %101 None
+        %104 = OpIEqual %bool %x_52 %uint_0
+               OpSelectionMerge %105 None
+               OpBranchConditional %104 %106 %105
+        %106 = OpLabel
        %x_80 = OpBitcast %v2uint %x_76
        %x_81 = OpCompositeExtract %uint %x_80 0
                OpAtomicStore %x_34 %uint_2 %uint_0 %x_81
@@ -224,150 +232,156 @@
                OpAtomicStore %x_35 %uint_2 %uint_0 %x_82
                OpAtomicStore %x_36 %uint_2 %uint_0 %x_81
                OpAtomicStore %x_37 %uint_2 %uint_0 %x_82
-               OpBranch %97
-         %97 = OpLabel
-        %107 = OpVectorShuffle %v4float %x_76 %x_76 0 1 0 1
-               OpStore %x_85 %107 None
+               OpBranch %105
+        %105 = OpLabel
+        %115 = OpVectorShuffle %v4float %x_76 %x_76 0 1 0 1
+               OpStore %x_85 %115 None
                OpStore %x_88 %uint_1 None
-               OpBranch %111
-        %111 = OpLabel
-               OpLoopMerge %112 %110 None
-               OpBranch %109
-        %109 = OpLabel
+               OpBranch %118
+        %118 = OpLabel
+               OpLoopMerge %119 %117 None
+               OpBranch %116
+        %116 = OpLabel
        %x_90 = OpBitcast %uint %x_74
-        %117 = OpLoad %uint %x_88 None
-        %118 = OpULessThan %bool %117 %x_90
-               OpSelectionMerge %119 None
-               OpBranchConditional %118 %119 %120
-        %120 = OpLabel
-               OpBranch %112
-        %119 = OpLabel
-        %121 = OpLoad %uint %x_88 None
-       %x_94 = OpIAdd %uint %121 %x_52
-        %123 = OpLoad %v4float %x_85 None
-               OpStore %x_86 %123 None
-        %124 = OpUGreaterThanEqual %bool %x_94 %x_90
-               OpSelectionMerge %125 None
-               OpBranchConditional %124 %126 %125
+        %124 = OpLoad %uint %x_88 None
+        %125 = OpULessThan %bool %124 %x_90
+               OpSelectionMerge %126 None
+               OpBranchConditional %125 %126 %127
+        %127 = OpLabel
+               OpBranch %119
         %126 = OpLabel
-        %127 = OpAccessChain %_ptr_Workgroup_v2float %x_28 %x_94 %uint_0
-       %x_99 = OpLoad %v2float %127 None
-        %129 = OpLoad %v4float %x_85 None
-        %130 = OpVectorShuffle %v2float %129 %129 0 1
-      %x_101 = OpExtInst %v2float %132 FMin %130 %x_99
-        %133 = OpLoad %v4float %x_85 None
-               OpStore %x_103_1 %133
-        %135 = OpCompositeExtract %float %x_101 0
-        %136 = OpAccessChain %_ptr_Function_float %x_103_1 %uint_0
-               OpStore %136 %135 None
+        %128 = OpLoad %uint %x_88 None
+       %x_94 = OpIAdd %uint %128 %x_52
+        %130 = OpLoad %v4float %x_85 None
+               OpStore %x_86 %130 None
+        %131 = OpUGreaterThanEqual %bool %x_94 %x_90
+               OpSelectionMerge %132 None
+               OpBranchConditional %131 %133 %132
+        %133 = OpLabel
+        %134 = OpExtInst %uint %77 UMin %x_94 %uint_4095
+        %135 = OpAccessChain %_ptr_Workgroup_v2float %x_28 %134 %uint_0
+       %x_99 = OpLoad %v2float %135 None
+        %137 = OpLoad %v4float %x_85 None
+        %138 = OpVectorShuffle %v2float %137 %137 0 1
+      %x_101 = OpExtInst %v2float %77 FMin %138 %x_99
+        %140 = OpLoad %v4float %x_85 None
+               OpStore %x_103_1 %140
+        %142 = OpCompositeExtract %float %x_101 0
+        %143 = OpAccessChain %_ptr_Function_float %x_103_1 %uint_0
+               OpStore %143 %142 None
       %x_103 = OpLoad %v4float %x_103_1 None
                OpStore %x_105_1 %x_103
-        %140 = OpCompositeExtract %float %x_101 1
-        %141 = OpAccessChain %_ptr_Function_float %x_105_1 %uint_1
-               OpStore %141 %140 None
-      %x_105 = OpLoad %v4float %x_105_1 None
-        %143 = OpLoad %v4float %x_105_1 None
-        %144 = OpVectorShuffle %v2float %143 %143 2 3
-      %x_107 = OpExtInst %v2float %132 FMax %144 %x_99
-               OpStore %x_109_1 %x_105
-        %147 = OpCompositeExtract %float %x_107 0
-        %148 = OpAccessChain %_ptr_Function_float %x_109_1 %uint_2
+        %147 = OpCompositeExtract %float %x_101 1
+        %148 = OpAccessChain %_ptr_Function_float %x_105_1 %uint_1
                OpStore %148 %147 None
-        %149 = OpLoad %v4float %x_109_1 None
-               OpStore %x_111 %149 None
-        %150 = OpCompositeExtract %float %x_107 1
-        %151 = OpAccessChain %_ptr_Function_float %x_111 %uint_3
-               OpStore %151 %150 None
-        %153 = OpLoad %v4float %x_111 None
-               OpStore %x_86 %153 None
-               OpBranch %125
-        %125 = OpLabel
-               OpBranch %110
-        %110 = OpLabel
-        %154 = OpLoad %uint %x_88 None
-        %155 = OpIAdd %uint %154 %uint_32
-               OpStore %x_89 %155 None
-        %156 = OpLoad %v4float %x_86 None
-               OpStore %x_85 %156 None
-        %157 = OpLoad %uint %x_89 None
-               OpStore %x_88 %157 None
-               OpBranch %111
-        %112 = OpLabel
+      %x_105 = OpLoad %v4float %x_105_1 None
+        %150 = OpLoad %v4float %x_105_1 None
+        %151 = OpVectorShuffle %v2float %150 %150 2 3
+      %x_107 = OpExtInst %v2float %77 FMax %151 %x_99
+               OpStore %x_109_1 %x_105
+        %154 = OpCompositeExtract %float %x_107 0
+        %155 = OpAccessChain %_ptr_Function_float %x_109_1 %uint_2
+               OpStore %155 %154 None
+        %156 = OpLoad %v4float %x_109_1 None
+               OpStore %x_111 %156 None
+        %157 = OpCompositeExtract %float %x_107 1
+        %158 = OpAccessChain %_ptr_Function_float %x_111 %uint_3
+               OpStore %158 %157 None
+        %160 = OpLoad %v4float %x_111 None
+               OpStore %x_86 %160 None
+               OpBranch %132
+        %132 = OpLabel
+               OpBranch %117
+        %117 = OpLabel
+        %161 = OpLoad %uint %x_88 None
+        %162 = OpIAdd %uint %161 %uint_32
+               OpStore %x_89 %162 None
+        %163 = OpLoad %v4float %x_86 None
+               OpStore %x_85 %163 None
+        %164 = OpLoad %uint %x_89 None
+               OpStore %x_88 %164 None
+               OpBranch %118
+        %119 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-        %159 = OpAccessChain %_ptr_Function_float %x_85 %uint_0
-        %160 = OpLoad %float %159 None
-        %161 = OpBitcast %uint %160
-      %x_114 = OpAtomicUMin %uint %x_34 %uint_2 %uint_0 %161
-        %163 = OpAccessChain %_ptr_Function_float %x_85 %uint_1
-        %164 = OpLoad %float %163 None
-        %165 = OpBitcast %uint %164
-      %x_117 = OpAtomicUMin %uint %x_35 %uint_2 %uint_0 %165
-        %167 = OpAccessChain %_ptr_Function_float %x_85 %uint_2
-        %168 = OpLoad %float %167 None
-        %169 = OpBitcast %uint %168
-      %x_120 = OpAtomicUMax %uint %x_36 %uint_2 %uint_0 %169
-        %171 = OpAccessChain %_ptr_Function_float %x_85 %uint_3
-        %172 = OpLoad %float %171 None
-        %173 = OpBitcast %uint %172
-      %x_123 = OpAtomicUMax %uint %x_37 %uint_2 %uint_0 %173
+        %166 = OpAccessChain %_ptr_Function_float %x_85 %uint_0
+        %167 = OpLoad %float %166 None
+        %168 = OpBitcast %uint %167
+      %x_114 = OpAtomicUMin %uint %x_34 %uint_2 %uint_0 %168
+        %170 = OpAccessChain %_ptr_Function_float %x_85 %uint_1
+        %171 = OpLoad %float %170 None
+        %172 = OpBitcast %uint %171
+      %x_117 = OpAtomicUMin %uint %x_35 %uint_2 %uint_0 %172
+        %174 = OpAccessChain %_ptr_Function_float %x_85 %uint_2
+        %175 = OpLoad %float %174 None
+        %176 = OpBitcast %uint %175
+      %x_120 = OpAtomicUMax %uint %x_36 %uint_2 %uint_0 %176
+        %178 = OpAccessChain %_ptr_Function_float %x_85 %uint_3
+        %179 = OpLoad %float %178 None
+        %180 = OpBitcast %uint %179
+      %x_123 = OpAtomicUMax %uint %x_37 %uint_2 %uint_0 %180
                OpControlBarrier %uint_2 %uint_2 %uint_264
-        %176 = OpAccessChain %_ptr_StorageBuffer_v4float_0 %x_12 %uint_0 %int_0
-        %178 = OpAtomicLoad %uint %x_34 %uint_2 %uint_0
-        %179 = OpBitcast %float %178
-        %180 = OpAtomicLoad %uint %x_35 %uint_2 %uint_0
-        %181 = OpBitcast %float %180
-        %182 = OpAtomicLoad %uint %x_36 %uint_2 %uint_0
-        %183 = OpBitcast %float %182
-        %184 = OpAtomicLoad %uint %x_37 %uint_2 %uint_0
-        %185 = OpBitcast %float %184
-        %186 = OpCompositeConstruct %v4float %179 %181 %183 %185
-               OpStore %176 %186 None
+        %183 = OpAccessChain %_ptr_StorageBuffer__runtimearr_v4float_0 %x_12 %uint_0
+        %185 = OpArrayLength %uint %x_12 0
+        %186 = OpISub %uint %185 %uint_1
+        %187 = OpBitcast %uint %int_0
+        %189 = OpExtInst %uint %77 UMin %187 %186
+        %190 = OpAccessChain %_ptr_StorageBuffer_v4float_0 %x_12 %uint_0 %189
+        %192 = OpAtomicLoad %uint %x_34 %uint_2 %uint_0
+        %193 = OpBitcast %float %192
+        %194 = OpAtomicLoad %uint %x_35 %uint_2 %uint_0
+        %195 = OpBitcast %float %194
+        %196 = OpAtomicLoad %uint %x_36 %uint_2 %uint_0
+        %197 = OpBitcast %float %196
+        %198 = OpAtomicLoad %uint %x_37 %uint_2 %uint_0
+        %199 = OpBitcast %float %198
+        %200 = OpCompositeConstruct %v4float %193 %195 %197 %199
+               OpStore %190 %200 None
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %190
+ %main_inner = OpFunction %void None %204
   %x_3_param = OpFunctionParameter %v3uint
 %tint_local_index = OpFunctionParameter %uint
-        %191 = OpLabel
-        %192 = OpULessThan %bool %tint_local_index %uint_1
-               OpSelectionMerge %193 None
-               OpBranchConditional %192 %194 %193
-        %194 = OpLabel
+        %205 = OpLabel
+        %206 = OpULessThan %bool %tint_local_index %uint_1
+               OpSelectionMerge %207 None
+               OpBranchConditional %206 %208 %207
+        %208 = OpLabel
                OpAtomicStore %x_34 %uint_2 %uint_0 %uint_0
                OpAtomicStore %x_35 %uint_2 %uint_0 %uint_0
                OpAtomicStore %x_36 %uint_2 %uint_0 %uint_0
                OpAtomicStore %x_37 %uint_2 %uint_0 %uint_0
-               OpBranch %193
-        %193 = OpLabel
-               OpBranch %199
-        %199 = OpLabel
-               OpBranch %202
-        %202 = OpLabel
-        %204 = OpPhi %uint %tint_local_index %199 %205 %201
-               OpLoopMerge %203 %201 None
-               OpBranch %200
-        %200 = OpLabel
-        %206 = OpUGreaterThanEqual %bool %204 %uint_4096
-               OpSelectionMerge %207 None
-               OpBranchConditional %206 %208 %207
-        %208 = OpLabel
-               OpBranch %203
+               OpBranch %207
         %207 = OpLabel
-        %209 = OpAccessChain %_ptr_Workgroup_S %x_28 %204
-               OpStore %209 %210 None
-               OpBranch %201
-        %201 = OpLabel
-        %205 = OpIAdd %uint %204 %uint_32
-               OpBranch %202
-        %203 = OpLabel
+               OpBranch %213
+        %213 = OpLabel
+               OpBranch %216
+        %216 = OpLabel
+        %218 = OpPhi %uint %tint_local_index %213 %219 %215
+               OpLoopMerge %217 %215 None
+               OpBranch %214
+        %214 = OpLabel
+        %220 = OpUGreaterThanEqual %bool %218 %uint_4096
+               OpSelectionMerge %221 None
+               OpBranchConditional %220 %222 %221
+        %222 = OpLabel
+               OpBranch %217
+        %221 = OpLabel
+        %223 = OpAccessChain %_ptr_Workgroup_S %x_28 %218
+               OpStore %223 %224 None
+               OpBranch %215
+        %215 = OpLabel
+        %219 = OpIAdd %uint %218 %uint_32
+               OpBranch %216
+        %217 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
                OpStore %x_3 %x_3_param None
-        %212 = OpFunctionCall %void %main_1
+        %226 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %37
-        %214 = OpLabel
-        %215 = OpLoad %v3uint %main_local_invocation_id_Input None
-        %216 = OpLoad %uint %main_local_invocation_index_Input None
-        %217 = OpFunctionCall %void %main_inner %215 %216
+        %228 = OpLabel
+        %229 = OpLoad %v3uint %main_local_invocation_id_Input None
+        %230 = OpLoad %uint %main_local_invocation_index_Input None
+        %231 = OpFunctionCall %void %main_inner %229 %230
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2038.wgsl.expected.glsl b/test/tint/bug/tint/2038.wgsl.expected.glsl
index 3bd3a18..7a77627 100644
--- a/test/tint/bug/tint/2038.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2038.wgsl.expected.glsl
@@ -7,9 +7,9 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   if (false) {
-    v.inner[0] = 1u;
+    v.inner[0u] = 1u;
   }
   if (false) {
-    v.inner[1] = 1u;
+    v.inner[1u] = 1u;
   }
 }
diff --git a/test/tint/bug/tint/2038.wgsl.expected.ir.msl b/test/tint/bug/tint/2038.wgsl.expected.ir.msl
index b288c65..db68d68 100644
--- a/test/tint/bug/tint/2038.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2038.wgsl.expected.ir.msl
@@ -20,9 +20,9 @@
 kernel void tint_symbol(device tint_array<uint, 2>* output [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
   if (false) {
-    (*tint_module_vars.output)[0] = 1u;
+    (*tint_module_vars.output)[0u] = 1u;
   }
   if (false) {
-    (*tint_module_vars.output)[1] = 1u;
+    (*tint_module_vars.output)[1u] = 1u;
   }
 }
diff --git a/test/tint/bug/tint/2038.wgsl.expected.spvasm b/test/tint/bug/tint/2038.wgsl.expected.spvasm
index 8eb6341..242fa70 100644
--- a/test/tint/bug/tint/2038.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2038.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 25
+; Bound: 22
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -28,25 +28,22 @@
       %false = OpConstantFalse %bool
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
      %uint_1 = OpConstant %uint 1
-      %int_1 = OpConstant %int 1
        %main = OpFunction %void None %9
          %10 = OpLabel
                OpSelectionMerge %11 None
                OpBranchConditional %false %12 %11
          %12 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_0
+         %15 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_0
                OpStore %15 %uint_1 None
                OpBranch %11
          %11 = OpLabel
-               OpSelectionMerge %21 None
-               OpBranchConditional %false %22 %21
-         %22 = OpLabel
-         %23 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_1
-               OpStore %23 %uint_1 None
-               OpBranch %21
-         %21 = OpLabel
+               OpSelectionMerge %19 None
+               OpBranchConditional %false %20 %19
+         %20 = OpLabel
+         %21 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_1
+               OpStore %21 %uint_1 None
+               OpBranch %19
+         %19 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2039.wgsl.expected.ir.msl b/test/tint/bug/tint/2039.wgsl.expected.ir.msl
index fd6830b..11378a4 100644
--- a/test/tint/bug/tint/2039.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2039.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   uint out = 0u;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       bool tint_continue = false;
       switch(2) {
         case 1:
diff --git a/test/tint/bug/tint/2039.wgsl.expected.msl b/test/tint/bug/tint/2039.wgsl.expected.msl
index 509d485..28d2df8 100644
--- a/test/tint/bug/tint/2039.wgsl.expected.msl
+++ b/test/tint/bug/tint/2039.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   uint out = 0u;
   bool tint_continue = false;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(2) {
       case 1: {
diff --git a/test/tint/bug/tint/2059.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/2059.wgsl.expected.dxc.hlsl
index 213f45b..6ac9ddf 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/2059.wgsl.expected.dxc.hlsl
@@ -167,7 +167,7 @@
   float3x3 m = float3x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
   {
     for(uint c = 0u; (c < 3u); c = (c + 1u)) {
-      set_matrix_column(m, c, float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u))));
+      set_matrix_column(m, min(c, 2u), float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u))));
     }
   }
   {
diff --git a/test/tint/bug/tint/2059.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/2059.wgsl.expected.fxc.hlsl
index 213f45b..6ac9ddf 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/2059.wgsl.expected.fxc.hlsl
@@ -167,7 +167,7 @@
   float3x3 m = float3x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
   {
     for(uint c = 0u; (c < 3u); c = (c + 1u)) {
-      set_matrix_column(m, c, float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u))));
+      set_matrix_column(m, min(c, 2u), float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u))));
     }
   }
   {
diff --git a/test/tint/bug/tint/2059.wgsl.expected.glsl b/test/tint/bug/tint/2059.wgsl.expected.glsl
index f24c636..86b8d1d 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2059.wgsl.expected.glsl
@@ -225,7 +225,7 @@
       } else {
         break;
       }
-      uint v_20 = c;
+      uint v_20 = min(c, 2u);
       float v_21 = float(((c * 3u) + 1u));
       float v_22 = float(((c * 3u) + 2u));
       m[v_20] = vec3(v_21, v_22, float(((c * 3u) + 3u)));
diff --git a/test/tint/bug/tint/2059.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/2059.wgsl.expected.ir.dxc.hlsl
index 8ad02fc..853da4d 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/2059.wgsl.expected.ir.dxc.hlsl
@@ -228,7 +228,7 @@
       } else {
         break;
       }
-      uint v_41 = c;
+      uint v_41 = min(c, 2u);
       float v_42 = float(((c * 3u) + 1u));
       float v_43 = float(((c * 3u) + 2u));
       m[v_41] = float3(v_42, v_43, float(((c * 3u) + 3u)));
diff --git a/test/tint/bug/tint/2059.wgsl.expected.ir.msl b/test/tint/bug/tint/2059.wgsl.expected.ir.msl
index 12a3ecb..60a731d 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2059.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S2_packed_vec3 {
   /* 0x0000 */ tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 1> m;
 };
@@ -72,6 +75,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 1u)) {
         break;
@@ -94,6 +98,7 @@
     uint v_2 = 0u;
     v_2 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 1u)) {
         break;
@@ -116,6 +121,7 @@
     uint v_4 = 0u;
     v_4 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_2)
       uint const v_5 = v_4;
       if ((v_5 >= 1u)) {
         break;
@@ -147,7 +153,7 @@
       } else {
         break;
       }
-      thread float3* const v_6 = (&m[c]);
+      thread float3* const v_6 = (&m[min(c, 2u)]);
       float const v_7 = float(((c * 3u) + 1u));
       float const v_8 = float(((c * 3u) + 2u));
       (*v_6) = float3(v_7, v_8, float(((c * 3u) + 3u)));
diff --git a/test/tint/bug/tint/2059.wgsl.expected.msl b/test/tint/bug/tint/2059.wgsl.expected.msl
index e397684..bd9d9bc 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.msl
+++ b/test/tint/bug/tint/2059.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   /* 0x0000 */ packed_float3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -63,7 +66,8 @@
 
 void assign_and_preserve_padding_3(device tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 1>* const dest, tint_array<float3x3, 1> value) {
   for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-    assign_and_preserve_padding(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding(&((*(dest))[min(i, 0u)]), value[min(i, 0u)]);
   }
 }
 
@@ -77,7 +81,8 @@
 
 void assign_and_preserve_padding_6(device tint_array<S_tint_packed_vec3, 1>* const dest, tint_array<S, 1> value) {
   for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false_1);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 0u)]), value[min(i, 0u)]);
   }
 }
 
@@ -87,14 +92,16 @@
 
 void assign_and_preserve_padding_7(device tint_array<S2_tint_packed_vec3, 1>* const dest, tint_array<S2, 1> value) {
   for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-    assign_and_preserve_padding_2(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false_2);
+    assign_and_preserve_padding_2(&((*(dest))[min(i, 0u)]), value[min(i, 0u)]);
   }
 }
 
 kernel void tint_symbol(device tint_array<tint_packed_vec3_f32_array_element, 3>* tint_symbol_8 [[buffer(0)]], device S_tint_packed_vec3* tint_symbol_9 [[buffer(1)]], device S2_tint_packed_vec3* tint_symbol_10 [[buffer(2)]], device S3_tint_packed_vec3* tint_symbol_11 [[buffer(3)]], device S4_tint_packed_vec3* tint_symbol_12 [[buffer(4)]], device tint_array<tint_array<tint_packed_vec3_f32_array_element, 3>, 1>* tint_symbol_13 [[buffer(5)]], device tint_array<S_tint_packed_vec3, 1>* tint_symbol_14 [[buffer(6)]], device tint_array<S2_tint_packed_vec3, 1>* tint_symbol_15 [[buffer(7)]]) {
   float3x3 m = float3x3(0.0f);
   for(uint c = 0u; (c < 3u); c = (c + 1u)) {
-    m[c] = float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u)));
+    TINT_ISOLATE_UB(tint_volatile_false_3);
+    m[min(c, 2u)] = float3(float(((c * 3u) + 1u)), float(((c * 3u) + 2u)), float(((c * 3u) + 3u)));
   }
   {
     float3x3 const a = m;
diff --git a/test/tint/bug/tint/2059.wgsl.expected.spvasm b/test/tint/bug/tint/2059.wgsl.expected.spvasm
index 2f67004..1746340 100644
--- a/test/tint/bug/tint/2059.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2059.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 370
+; Bound: 372
 ; Schema: 0
                OpCapability Shader
+         %60 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -196,27 +197,27 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
        %bool = OpTypeBool
-%_ptr_Function_v3float = OpTypePointer Function %v3float
      %uint_2 = OpConstant %uint 2
-        %116 = OpTypeFunction %void %mat3v3float
+%_ptr_Function_v3float = OpTypePointer Function %v3float
+        %118 = OpTypeFunction %void %mat3v3float
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
 %_arr_uint_uint_2 = OpTypeArray %uint %uint_2
-        %129 = OpTypeFunction %void %_arr_uint_uint_2 %mat3v3float
+        %131 = OpTypeFunction %void %_arr_uint_uint_2 %mat3v3float
 %_arr_uint_uint_1 = OpTypeArray %uint %uint_1
-        %143 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
-        %204 = OpTypeFunction %void %S
-        %211 = OpTypeFunction %void %_arr_uint_uint_1 %S
-        %231 = OpTypeFunction %void %S2
-        %239 = OpTypeFunction %void %_arr_uint_uint_1 %S2
-        %247 = OpTypeFunction %void %_arr_mat3v3float_uint_1
+        %145 = OpTypeFunction %void %_arr_uint_uint_1 %mat3v3float
+        %206 = OpTypeFunction %void %S
+        %213 = OpTypeFunction %void %_arr_uint_uint_1 %S
+        %233 = OpTypeFunction %void %S2
+        %241 = OpTypeFunction %void %_arr_uint_uint_1 %S2
+        %249 = OpTypeFunction %void %_arr_mat3v3float_uint_1
 %_ptr_Function__arr_mat3v3float_uint_1 = OpTypePointer Function %_arr_mat3v3float_uint_1
-        %267 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_mat3v3float_uint_1
-        %303 = OpTypeFunction %void %S3
-        %308 = OpTypeFunction %void %S4
-        %314 = OpTypeFunction %void %_arr_S_uint_1
+        %269 = OpTypeFunction %void %_arr_uint_uint_1 %_arr_mat3v3float_uint_1
+        %305 = OpTypeFunction %void %S3
+        %310 = OpTypeFunction %void %S4
+        %316 = OpTypeFunction %void %_arr_S_uint_1
 %_ptr_Function__arr_S_uint_1 = OpTypePointer Function %_arr_S_uint_1
 %_ptr_Function_S = OpTypePointer Function %S
-        %351 = OpTypeFunction %void %_arr_S2_uint_1
+        %353 = OpTypeFunction %void %_arr_S2_uint_1
 %_ptr_Function__arr_S2_uint_1 = OpTypePointer Function %_arr_S2_uint_1
 %_ptr_Function_S2 = OpTypePointer Function %S2
        %main = OpFunction %void None %39
@@ -239,427 +240,428 @@
                OpBranch %48
          %56 = OpLabel
          %58 = OpLoad %uint %c None
-         %59 = OpAccessChain %_ptr_Function_v3float %m %58
-         %61 = OpLoad %uint %c None
-         %62 = OpIMul %uint %61 %uint_3
-         %63 = OpIAdd %uint %62 %uint_1
-         %64 = OpConvertUToF %float %63
-         %65 = OpLoad %uint %c None
-         %66 = OpIMul %uint %65 %uint_3
-         %67 = OpIAdd %uint %66 %uint_2
-         %69 = OpConvertUToF %float %67
-         %70 = OpLoad %uint %c None
-         %71 = OpIMul %uint %70 %uint_3
-         %72 = OpIAdd %uint %71 %uint_3
-         %73 = OpConvertUToF %float %72
-         %74 = OpCompositeConstruct %v3float %64 %69 %73
-               OpStore %59 %74 None
+         %59 = OpExtInst %uint %60 UMin %58 %uint_2
+         %62 = OpAccessChain %_ptr_Function_v3float %m %59
+         %64 = OpLoad %uint %c None
+         %65 = OpIMul %uint %64 %uint_3
+         %66 = OpIAdd %uint %65 %uint_1
+         %67 = OpConvertUToF %float %66
+         %68 = OpLoad %uint %c None
+         %69 = OpIMul %uint %68 %uint_3
+         %70 = OpIAdd %uint %69 %uint_2
+         %71 = OpConvertUToF %float %70
+         %72 = OpLoad %uint %c None
+         %73 = OpIMul %uint %72 %uint_3
+         %74 = OpIAdd %uint %73 %uint_3
+         %75 = OpConvertUToF %float %74
+         %76 = OpCompositeConstruct %v3float %67 %71 %75
+               OpStore %62 %76 None
                OpBranch %46
          %46 = OpLabel
-         %75 = OpLoad %uint %c None
-         %76 = OpIAdd %uint %75 %uint_1
-               OpStore %c %76 None
+         %77 = OpLoad %uint %c None
+         %78 = OpIAdd %uint %77 %uint_1
+               OpStore %c %78 None
                OpBranch %47
          %48 = OpLabel
           %a = OpLoad %mat3v3float %m None
-         %78 = OpFunctionCall %void %tint_store_and_preserve_padding %a
-         %80 = OpLoad %mat3v3float %m None
-        %a_0 = OpCompositeConstruct %S %80
-         %82 = OpFunctionCall %void %tint_store_and_preserve_padding_7 %a_0
-         %84 = OpLoad %mat3v3float %m None
-         %85 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %84
-        %a_1 = OpCompositeConstruct %S2 %85
-         %87 = OpFunctionCall %void %tint_store_and_preserve_padding_11 %a_1
-         %89 = OpLoad %mat3v3float %m None
-         %90 = OpCompositeConstruct %S %89
-        %a_2 = OpCompositeConstruct %S3 %90
-         %92 = OpFunctionCall %void %tint_store_and_preserve_padding_16 %a_2
-         %94 = OpLoad %mat3v3float %m None
-         %95 = OpCompositeConstruct %S %94
-         %96 = OpCompositeConstruct %_arr_S_uint_1 %95
-        %a_3 = OpCompositeConstruct %S4 %96
-         %98 = OpFunctionCall %void %tint_store_and_preserve_padding_17 %a_3
-        %100 = OpLoad %mat3v3float %m None
-        %a_4 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %100
-        %102 = OpFunctionCall %void %tint_store_and_preserve_padding_13 %a_4
-        %104 = OpLoad %mat3v3float %m None
-        %105 = OpCompositeConstruct %S %104
-        %a_5 = OpCompositeConstruct %_arr_S_uint_1 %105
-        %107 = OpFunctionCall %void %tint_store_and_preserve_padding_18 %a_5
-        %109 = OpLoad %mat3v3float %m None
-        %110 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %109
-        %111 = OpCompositeConstruct %S2 %110
-        %a_6 = OpCompositeConstruct %_arr_S2_uint_1 %111
-        %113 = OpFunctionCall %void %tint_store_and_preserve_padding_20 %a_6
+         %80 = OpFunctionCall %void %tint_store_and_preserve_padding %a
+         %82 = OpLoad %mat3v3float %m None
+        %a_0 = OpCompositeConstruct %S %82
+         %84 = OpFunctionCall %void %tint_store_and_preserve_padding_7 %a_0
+         %86 = OpLoad %mat3v3float %m None
+         %87 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %86
+        %a_1 = OpCompositeConstruct %S2 %87
+         %89 = OpFunctionCall %void %tint_store_and_preserve_padding_11 %a_1
+         %91 = OpLoad %mat3v3float %m None
+         %92 = OpCompositeConstruct %S %91
+        %a_2 = OpCompositeConstruct %S3 %92
+         %94 = OpFunctionCall %void %tint_store_and_preserve_padding_16 %a_2
+         %96 = OpLoad %mat3v3float %m None
+         %97 = OpCompositeConstruct %S %96
+         %98 = OpCompositeConstruct %_arr_S_uint_1 %97
+        %a_3 = OpCompositeConstruct %S4 %98
+        %100 = OpFunctionCall %void %tint_store_and_preserve_padding_17 %a_3
+        %102 = OpLoad %mat3v3float %m None
+        %a_4 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %102
+        %104 = OpFunctionCall %void %tint_store_and_preserve_padding_13 %a_4
+        %106 = OpLoad %mat3v3float %m None
+        %107 = OpCompositeConstruct %S %106
+        %a_5 = OpCompositeConstruct %_arr_S_uint_1 %107
+        %109 = OpFunctionCall %void %tint_store_and_preserve_padding_18 %a_5
+        %111 = OpLoad %mat3v3float %m None
+        %112 = OpCompositeConstruct %_arr_mat3v3float_uint_1 %111
+        %113 = OpCompositeConstruct %S2 %112
+        %a_6 = OpCompositeConstruct %_arr_S2_uint_1 %113
+        %115 = OpFunctionCall %void %tint_store_and_preserve_padding_20 %a_6
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding = OpFunction %void None %116
+%tint_store_and_preserve_padding = OpFunction %void None %118
 %value_param = OpFunctionParameter %mat3v3float
-        %117 = OpLabel
-        %118 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
-        %120 = OpCompositeExtract %v3float %value_param 0
-               OpStore %118 %120 None
-        %121 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_1
-        %122 = OpCompositeExtract %v3float %value_param 1
-               OpStore %121 %122 None
-        %123 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_2
-        %124 = OpCompositeExtract %v3float %value_param 2
+        %119 = OpLabel
+        %120 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
+        %122 = OpCompositeExtract %v3float %value_param 0
+               OpStore %120 %122 None
+        %123 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_1
+        %124 = OpCompositeExtract %v3float %value_param 1
                OpStore %123 %124 None
+        %125 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_2
+        %126 = OpCompositeExtract %v3float %value_param 2
+               OpStore %125 %126 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_0 = OpFunction %void None %129
+%tint_store_and_preserve_padding_0 = OpFunction %void None %131
 %target_indices = OpFunctionParameter %_arr_uint_uint_2
 %value_param_0 = OpFunctionParameter %mat3v3float
-        %130 = OpLabel
-        %131 = OpCompositeExtract %uint %target_indices 0
-        %132 = OpCompositeExtract %uint %target_indices 1
-        %133 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %131 %uint_0 %132 %uint_0
-        %134 = OpCompositeExtract %v3float %value_param_0 0
-               OpStore %133 %134 None
-        %135 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %131 %uint_0 %132 %uint_1
-        %136 = OpCompositeExtract %v3float %value_param_0 1
+        %132 = OpLabel
+        %133 = OpCompositeExtract %uint %target_indices 0
+        %134 = OpCompositeExtract %uint %target_indices 1
+        %135 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %133 %uint_0 %134 %uint_0
+        %136 = OpCompositeExtract %v3float %value_param_0 0
                OpStore %135 %136 None
-        %137 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %131 %uint_0 %132 %uint_2
-        %138 = OpCompositeExtract %v3float %value_param_0 2
+        %137 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %133 %uint_0 %134 %uint_1
+        %138 = OpCompositeExtract %v3float %value_param_0 1
                OpStore %137 %138 None
+        %139 = OpAccessChain %_ptr_StorageBuffer_v3float %33 %uint_0 %133 %uint_0 %134 %uint_2
+        %140 = OpCompositeExtract %v3float %value_param_0 2
+               OpStore %139 %140 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_1 = OpFunction %void None %143
+%tint_store_and_preserve_padding_1 = OpFunction %void None %145
 %target_indices_0 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_1 = OpFunctionParameter %mat3v3float
-        %144 = OpLabel
-        %145 = OpCompositeExtract %uint %target_indices_0 0
-        %146 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %145 %uint_0 %uint_0
-        %147 = OpCompositeExtract %v3float %value_param_1 0
-               OpStore %146 %147 None
-        %148 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %145 %uint_0 %uint_1
-        %149 = OpCompositeExtract %v3float %value_param_1 1
+        %146 = OpLabel
+        %147 = OpCompositeExtract %uint %target_indices_0 0
+        %148 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %147 %uint_0 %uint_0
+        %149 = OpCompositeExtract %v3float %value_param_1 0
                OpStore %148 %149 None
-        %150 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %145 %uint_0 %uint_2
-        %151 = OpCompositeExtract %v3float %value_param_1 2
+        %150 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %147 %uint_0 %uint_1
+        %151 = OpCompositeExtract %v3float %value_param_1 1
                OpStore %150 %151 None
+        %152 = OpAccessChain %_ptr_StorageBuffer_v3float %30 %uint_0 %147 %uint_0 %uint_2
+        %153 = OpCompositeExtract %v3float %value_param_1 2
+               OpStore %152 %153 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_2 = OpFunction %void None %143
+%tint_store_and_preserve_padding_2 = OpFunction %void None %145
 %target_indices_1 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_2 = OpFunctionParameter %mat3v3float
-        %155 = OpLabel
-        %156 = OpCompositeExtract %uint %target_indices_1 0
-        %157 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %156 %uint_0
-        %158 = OpCompositeExtract %v3float %value_param_2 0
-               OpStore %157 %158 None
-        %159 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %156 %uint_1
-        %160 = OpCompositeExtract %v3float %value_param_2 1
+        %157 = OpLabel
+        %158 = OpCompositeExtract %uint %target_indices_1 0
+        %159 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %158 %uint_0
+        %160 = OpCompositeExtract %v3float %value_param_2 0
                OpStore %159 %160 None
-        %161 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %156 %uint_2
-        %162 = OpCompositeExtract %v3float %value_param_2 2
+        %161 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %158 %uint_1
+        %162 = OpCompositeExtract %v3float %value_param_2 1
                OpStore %161 %162 None
+        %163 = OpAccessChain %_ptr_StorageBuffer_v3float %27 %uint_0 %158 %uint_2
+        %164 = OpCompositeExtract %v3float %value_param_2 2
+               OpStore %163 %164 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_3 = OpFunction %void None %143
+%tint_store_and_preserve_padding_3 = OpFunction %void None %145
 %target_indices_2 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_3 = OpFunctionParameter %mat3v3float
-        %166 = OpLabel
-        %167 = OpCompositeExtract %uint %target_indices_2 0
-        %168 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %167 %uint_0 %uint_0
-        %169 = OpCompositeExtract %v3float %value_param_3 0
-               OpStore %168 %169 None
-        %170 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %167 %uint_0 %uint_1
-        %171 = OpCompositeExtract %v3float %value_param_3 1
+        %168 = OpLabel
+        %169 = OpCompositeExtract %uint %target_indices_2 0
+        %170 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %169 %uint_0 %uint_0
+        %171 = OpCompositeExtract %v3float %value_param_3 0
                OpStore %170 %171 None
-        %172 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %167 %uint_0 %uint_2
-        %173 = OpCompositeExtract %v3float %value_param_3 2
+        %172 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %169 %uint_0 %uint_1
+        %173 = OpCompositeExtract %v3float %value_param_3 1
                OpStore %172 %173 None
+        %174 = OpAccessChain %_ptr_StorageBuffer_v3float %22 %uint_0 %uint_0 %169 %uint_0 %uint_2
+        %175 = OpCompositeExtract %v3float %value_param_3 2
+               OpStore %174 %175 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_4 = OpFunction %void None %116
+%tint_store_and_preserve_padding_4 = OpFunction %void None %118
 %value_param_4 = OpFunctionParameter %mat3v3float
-        %176 = OpLabel
-        %177 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_0
-        %178 = OpCompositeExtract %v3float %value_param_4 0
-               OpStore %177 %178 None
-        %179 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_1
-        %180 = OpCompositeExtract %v3float %value_param_4 1
+        %178 = OpLabel
+        %179 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_0
+        %180 = OpCompositeExtract %v3float %value_param_4 0
                OpStore %179 %180 None
-        %181 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_2
-        %182 = OpCompositeExtract %v3float %value_param_4 2
+        %181 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_1
+        %182 = OpCompositeExtract %v3float %value_param_4 1
                OpStore %181 %182 None
+        %183 = OpAccessChain %_ptr_StorageBuffer_v3float %18 %uint_0 %uint_0 %uint_0 %uint_2
+        %184 = OpCompositeExtract %v3float %value_param_4 2
+               OpStore %183 %184 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_5 = OpFunction %void None %143
+%tint_store_and_preserve_padding_5 = OpFunction %void None %145
 %target_indices_3 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_5 = OpFunctionParameter %mat3v3float
-        %186 = OpLabel
-        %187 = OpCompositeExtract %uint %target_indices_3 0
-        %188 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %187 %uint_0
-        %189 = OpCompositeExtract %v3float %value_param_5 0
-               OpStore %188 %189 None
-        %190 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %187 %uint_1
-        %191 = OpCompositeExtract %v3float %value_param_5 1
+        %188 = OpLabel
+        %189 = OpCompositeExtract %uint %target_indices_3 0
+        %190 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %189 %uint_0
+        %191 = OpCompositeExtract %v3float %value_param_5 0
                OpStore %190 %191 None
-        %192 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %187 %uint_2
-        %193 = OpCompositeExtract %v3float %value_param_5 2
+        %192 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %189 %uint_1
+        %193 = OpCompositeExtract %v3float %value_param_5 1
                OpStore %192 %193 None
+        %194 = OpAccessChain %_ptr_StorageBuffer_v3float %11 %uint_0 %uint_0 %189 %uint_2
+        %195 = OpCompositeExtract %v3float %value_param_5 2
+               OpStore %194 %195 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_6 = OpFunction %void None %116
+%tint_store_and_preserve_padding_6 = OpFunction %void None %118
 %value_param_6 = OpFunctionParameter %mat3v3float
-        %196 = OpLabel
-        %197 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_0
-        %198 = OpCompositeExtract %v3float %value_param_6 0
-               OpStore %197 %198 None
-        %199 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_1
-        %200 = OpCompositeExtract %v3float %value_param_6 1
+        %198 = OpLabel
+        %199 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_0
+        %200 = OpCompositeExtract %v3float %value_param_6 0
                OpStore %199 %200 None
-        %201 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_2
-        %202 = OpCompositeExtract %v3float %value_param_6 2
+        %201 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_1
+        %202 = OpCompositeExtract %v3float %value_param_6 1
                OpStore %201 %202 None
+        %203 = OpAccessChain %_ptr_StorageBuffer_v3float %7 %uint_0 %uint_0 %uint_2
+        %204 = OpCompositeExtract %v3float %value_param_6 2
+               OpStore %203 %204 None
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_7 = OpFunction %void None %204
+%tint_store_and_preserve_padding_7 = OpFunction %void None %206
 %value_param_7 = OpFunctionParameter %S
-        %205 = OpLabel
-        %206 = OpCompositeExtract %mat3v3float %value_param_7 0
-        %207 = OpFunctionCall %void %tint_store_and_preserve_padding_6 %206
+        %207 = OpLabel
+        %208 = OpCompositeExtract %mat3v3float %value_param_7 0
+        %209 = OpFunctionCall %void %tint_store_and_preserve_padding_6 %208
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_8 = OpFunction %void None %211
+%tint_store_and_preserve_padding_8 = OpFunction %void None %213
 %target_indices_4 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_8 = OpFunctionParameter %S
-        %212 = OpLabel
-        %213 = OpCompositeExtract %uint %target_indices_4 0
-        %214 = OpCompositeExtract %mat3v3float %value_param_8 0
-        %215 = OpCompositeConstruct %_arr_uint_uint_1 %213
-        %216 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %215 %214
+        %214 = OpLabel
+        %215 = OpCompositeExtract %uint %target_indices_4 0
+        %216 = OpCompositeExtract %mat3v3float %value_param_8 0
+        %217 = OpCompositeConstruct %_arr_uint_uint_1 %215
+        %218 = OpFunctionCall %void %tint_store_and_preserve_padding_1 %217 %216
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_9 = OpFunction %void None %211
+%tint_store_and_preserve_padding_9 = OpFunction %void None %213
 %target_indices_5 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_9 = OpFunctionParameter %S
-        %220 = OpLabel
-        %221 = OpCompositeExtract %uint %target_indices_5 0
-        %222 = OpCompositeExtract %mat3v3float %value_param_9 0
-        %223 = OpCompositeConstruct %_arr_uint_uint_1 %221
-        %224 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %223 %222
+        %222 = OpLabel
+        %223 = OpCompositeExtract %uint %target_indices_5 0
+        %224 = OpCompositeExtract %mat3v3float %value_param_9 0
+        %225 = OpCompositeConstruct %_arr_uint_uint_1 %223
+        %226 = OpFunctionCall %void %tint_store_and_preserve_padding_3 %225 %224
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_10 = OpFunction %void None %204
+%tint_store_and_preserve_padding_10 = OpFunction %void None %206
 %value_param_10 = OpFunctionParameter %S
-        %227 = OpLabel
-        %228 = OpCompositeExtract %mat3v3float %value_param_10 0
-        %229 = OpFunctionCall %void %tint_store_and_preserve_padding_4 %228
+        %229 = OpLabel
+        %230 = OpCompositeExtract %mat3v3float %value_param_10 0
+        %231 = OpFunctionCall %void %tint_store_and_preserve_padding_4 %230
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_11 = OpFunction %void None %231
+%tint_store_and_preserve_padding_11 = OpFunction %void None %233
 %value_param_11 = OpFunctionParameter %S2
-        %232 = OpLabel
-        %233 = OpCompositeExtract %_arr_mat3v3float_uint_1 %value_param_11 0
-        %234 = OpFunctionCall %void %tint_store_and_preserve_padding_15 %233
+        %234 = OpLabel
+        %235 = OpCompositeExtract %_arr_mat3v3float_uint_1 %value_param_11 0
+        %236 = OpFunctionCall %void %tint_store_and_preserve_padding_15 %235
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_12 = OpFunction %void None %239
+%tint_store_and_preserve_padding_12 = OpFunction %void None %241
 %target_indices_6 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_12 = OpFunctionParameter %S2
-        %240 = OpLabel
-        %241 = OpCompositeExtract %uint %target_indices_6 0
-        %242 = OpCompositeExtract %_arr_mat3v3float_uint_1 %value_param_12 0
-        %243 = OpCompositeConstruct %_arr_uint_uint_1 %241
-        %244 = OpFunctionCall %void %tint_store_and_preserve_padding_14 %243 %242
+        %242 = OpLabel
+        %243 = OpCompositeExtract %uint %target_indices_6 0
+        %244 = OpCompositeExtract %_arr_mat3v3float_uint_1 %value_param_12 0
+        %245 = OpCompositeConstruct %_arr_uint_uint_1 %243
+        %246 = OpFunctionCall %void %tint_store_and_preserve_padding_14 %245 %244
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_13 = OpFunction %void None %247
+%tint_store_and_preserve_padding_13 = OpFunction %void None %249
 %value_param_13 = OpFunctionParameter %_arr_mat3v3float_uint_1
-        %248 = OpLabel
-        %249 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
-               OpStore %249 %value_param_13
-               OpBranch %251
-        %251 = OpLabel
-               OpBranch %254
-        %254 = OpLabel
-        %256 = OpPhi %uint %uint_0 %251 %257 %253
-               OpLoopMerge %255 %253 None
-               OpBranch %252
-        %252 = OpLabel
-        %258 = OpUGreaterThanEqual %bool %256 %uint_1
-               OpSelectionMerge %259 None
-               OpBranchConditional %258 %260 %259
-        %260 = OpLabel
-               OpBranch %255
-        %259 = OpLabel
-        %261 = OpAccessChain %_ptr_Function_mat3v3float %249 %256
-        %262 = OpLoad %mat3v3float %261 None
-        %263 = OpCompositeConstruct %_arr_uint_uint_1 %256
-        %264 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %263 %262
+        %250 = OpLabel
+        %251 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
+               OpStore %251 %value_param_13
                OpBranch %253
         %253 = OpLabel
-        %257 = OpIAdd %uint %256 %uint_1
+               OpBranch %256
+        %256 = OpLabel
+        %258 = OpPhi %uint %uint_0 %253 %259 %255
+               OpLoopMerge %257 %255 None
                OpBranch %254
+        %254 = OpLabel
+        %260 = OpUGreaterThanEqual %bool %258 %uint_1
+               OpSelectionMerge %261 None
+               OpBranchConditional %260 %262 %261
+        %262 = OpLabel
+               OpBranch %257
+        %261 = OpLabel
+        %263 = OpAccessChain %_ptr_Function_mat3v3float %251 %258
+        %264 = OpLoad %mat3v3float %263 None
+        %265 = OpCompositeConstruct %_arr_uint_uint_1 %258
+        %266 = OpFunctionCall %void %tint_store_and_preserve_padding_2 %265 %264
+               OpBranch %255
         %255 = OpLabel
+        %259 = OpIAdd %uint %258 %uint_1
+               OpBranch %256
+        %257 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_14 = OpFunction %void None %267
+%tint_store_and_preserve_padding_14 = OpFunction %void None %269
 %target_indices_7 = OpFunctionParameter %_arr_uint_uint_1
 %value_param_14 = OpFunctionParameter %_arr_mat3v3float_uint_1
-        %268 = OpLabel
-        %269 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
-               OpStore %269 %value_param_14
-        %270 = OpCompositeExtract %uint %target_indices_7 0
-               OpBranch %271
-        %271 = OpLabel
-               OpBranch %274
-        %274 = OpLabel
-        %276 = OpPhi %uint %uint_0 %271 %277 %273
-               OpLoopMerge %275 %273 None
-               OpBranch %272
-        %272 = OpLabel
-        %278 = OpUGreaterThanEqual %bool %276 %uint_1
-               OpSelectionMerge %279 None
-               OpBranchConditional %278 %280 %279
-        %280 = OpLabel
-               OpBranch %275
-        %279 = OpLabel
-        %281 = OpAccessChain %_ptr_Function_mat3v3float %269 %276
-        %282 = OpLoad %mat3v3float %281 None
-        %283 = OpCompositeConstruct %_arr_uint_uint_2 %270 %276
-        %284 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %283 %282
+        %270 = OpLabel
+        %271 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
+               OpStore %271 %value_param_14
+        %272 = OpCompositeExtract %uint %target_indices_7 0
                OpBranch %273
         %273 = OpLabel
-        %277 = OpIAdd %uint %276 %uint_1
+               OpBranch %276
+        %276 = OpLabel
+        %278 = OpPhi %uint %uint_0 %273 %279 %275
+               OpLoopMerge %277 %275 None
                OpBranch %274
+        %274 = OpLabel
+        %280 = OpUGreaterThanEqual %bool %278 %uint_1
+               OpSelectionMerge %281 None
+               OpBranchConditional %280 %282 %281
+        %282 = OpLabel
+               OpBranch %277
+        %281 = OpLabel
+        %283 = OpAccessChain %_ptr_Function_mat3v3float %271 %278
+        %284 = OpLoad %mat3v3float %283 None
+        %285 = OpCompositeConstruct %_arr_uint_uint_2 %272 %278
+        %286 = OpFunctionCall %void %tint_store_and_preserve_padding_0 %285 %284
+               OpBranch %275
         %275 = OpLabel
+        %279 = OpIAdd %uint %278 %uint_1
+               OpBranch %276
+        %277 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_15 = OpFunction %void None %247
+%tint_store_and_preserve_padding_15 = OpFunction %void None %249
 %value_param_15 = OpFunctionParameter %_arr_mat3v3float_uint_1
-        %286 = OpLabel
-        %287 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
-               OpStore %287 %value_param_15
-               OpBranch %288
         %288 = OpLabel
-               OpBranch %291
-        %291 = OpLabel
-        %293 = OpPhi %uint %uint_0 %288 %294 %290
-               OpLoopMerge %292 %290 None
-               OpBranch %289
-        %289 = OpLabel
-        %295 = OpUGreaterThanEqual %bool %293 %uint_1
-               OpSelectionMerge %296 None
-               OpBranchConditional %295 %297 %296
-        %297 = OpLabel
-               OpBranch %292
-        %296 = OpLabel
-        %298 = OpAccessChain %_ptr_Function_mat3v3float %287 %293
-        %299 = OpLoad %mat3v3float %298 None
-        %300 = OpCompositeConstruct %_arr_uint_uint_1 %293
-        %301 = OpFunctionCall %void %tint_store_and_preserve_padding_5 %300 %299
+        %289 = OpVariable %_ptr_Function__arr_mat3v3float_uint_1 Function
+               OpStore %289 %value_param_15
                OpBranch %290
         %290 = OpLabel
-        %294 = OpIAdd %uint %293 %uint_1
+               OpBranch %293
+        %293 = OpLabel
+        %295 = OpPhi %uint %uint_0 %290 %296 %292
+               OpLoopMerge %294 %292 None
                OpBranch %291
+        %291 = OpLabel
+        %297 = OpUGreaterThanEqual %bool %295 %uint_1
+               OpSelectionMerge %298 None
+               OpBranchConditional %297 %299 %298
+        %299 = OpLabel
+               OpBranch %294
+        %298 = OpLabel
+        %300 = OpAccessChain %_ptr_Function_mat3v3float %289 %295
+        %301 = OpLoad %mat3v3float %300 None
+        %302 = OpCompositeConstruct %_arr_uint_uint_1 %295
+        %303 = OpFunctionCall %void %tint_store_and_preserve_padding_5 %302 %301
+               OpBranch %292
         %292 = OpLabel
+        %296 = OpIAdd %uint %295 %uint_1
+               OpBranch %293
+        %294 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_16 = OpFunction %void None %303
+%tint_store_and_preserve_padding_16 = OpFunction %void None %305
 %value_param_16 = OpFunctionParameter %S3
-        %304 = OpLabel
-        %305 = OpCompositeExtract %S %value_param_16 0
-        %306 = OpFunctionCall %void %tint_store_and_preserve_padding_10 %305
+        %306 = OpLabel
+        %307 = OpCompositeExtract %S %value_param_16 0
+        %308 = OpFunctionCall %void %tint_store_and_preserve_padding_10 %307
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_17 = OpFunction %void None %308
+%tint_store_and_preserve_padding_17 = OpFunction %void None %310
 %value_param_17 = OpFunctionParameter %S4
-        %309 = OpLabel
-        %310 = OpCompositeExtract %_arr_S_uint_1 %value_param_17 0
-        %311 = OpFunctionCall %void %tint_store_and_preserve_padding_19 %310
+        %311 = OpLabel
+        %312 = OpCompositeExtract %_arr_S_uint_1 %value_param_17 0
+        %313 = OpFunctionCall %void %tint_store_and_preserve_padding_19 %312
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_18 = OpFunction %void None %314
+%tint_store_and_preserve_padding_18 = OpFunction %void None %316
 %value_param_18 = OpFunctionParameter %_arr_S_uint_1
-        %315 = OpLabel
-        %316 = OpVariable %_ptr_Function__arr_S_uint_1 Function
-               OpStore %316 %value_param_18
-               OpBranch %318
-        %318 = OpLabel
-               OpBranch %321
-        %321 = OpLabel
-        %323 = OpPhi %uint %uint_0 %318 %324 %320
-               OpLoopMerge %322 %320 None
-               OpBranch %319
-        %319 = OpLabel
-        %325 = OpUGreaterThanEqual %bool %323 %uint_1
-               OpSelectionMerge %326 None
-               OpBranchConditional %325 %327 %326
-        %327 = OpLabel
-               OpBranch %322
-        %326 = OpLabel
-        %328 = OpAccessChain %_ptr_Function_S %316 %323
-        %330 = OpLoad %S %328 None
-        %331 = OpCompositeConstruct %_arr_uint_uint_1 %323
-        %332 = OpFunctionCall %void %tint_store_and_preserve_padding_8 %331 %330
+        %317 = OpLabel
+        %318 = OpVariable %_ptr_Function__arr_S_uint_1 Function
+               OpStore %318 %value_param_18
                OpBranch %320
         %320 = OpLabel
-        %324 = OpIAdd %uint %323 %uint_1
+               OpBranch %323
+        %323 = OpLabel
+        %325 = OpPhi %uint %uint_0 %320 %326 %322
+               OpLoopMerge %324 %322 None
                OpBranch %321
+        %321 = OpLabel
+        %327 = OpUGreaterThanEqual %bool %325 %uint_1
+               OpSelectionMerge %328 None
+               OpBranchConditional %327 %329 %328
+        %329 = OpLabel
+               OpBranch %324
+        %328 = OpLabel
+        %330 = OpAccessChain %_ptr_Function_S %318 %325
+        %332 = OpLoad %S %330 None
+        %333 = OpCompositeConstruct %_arr_uint_uint_1 %325
+        %334 = OpFunctionCall %void %tint_store_and_preserve_padding_8 %333 %332
+               OpBranch %322
         %322 = OpLabel
+        %326 = OpIAdd %uint %325 %uint_1
+               OpBranch %323
+        %324 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_19 = OpFunction %void None %314
+%tint_store_and_preserve_padding_19 = OpFunction %void None %316
 %value_param_19 = OpFunctionParameter %_arr_S_uint_1
-        %334 = OpLabel
-        %335 = OpVariable %_ptr_Function__arr_S_uint_1 Function
-               OpStore %335 %value_param_19
-               OpBranch %336
         %336 = OpLabel
-               OpBranch %339
-        %339 = OpLabel
-        %341 = OpPhi %uint %uint_0 %336 %342 %338
-               OpLoopMerge %340 %338 None
-               OpBranch %337
-        %337 = OpLabel
-        %343 = OpUGreaterThanEqual %bool %341 %uint_1
-               OpSelectionMerge %344 None
-               OpBranchConditional %343 %345 %344
-        %345 = OpLabel
-               OpBranch %340
-        %344 = OpLabel
-        %346 = OpAccessChain %_ptr_Function_S %335 %341
-        %347 = OpLoad %S %346 None
-        %348 = OpCompositeConstruct %_arr_uint_uint_1 %341
-        %349 = OpFunctionCall %void %tint_store_and_preserve_padding_9 %348 %347
+        %337 = OpVariable %_ptr_Function__arr_S_uint_1 Function
+               OpStore %337 %value_param_19
                OpBranch %338
         %338 = OpLabel
-        %342 = OpIAdd %uint %341 %uint_1
+               OpBranch %341
+        %341 = OpLabel
+        %343 = OpPhi %uint %uint_0 %338 %344 %340
+               OpLoopMerge %342 %340 None
                OpBranch %339
+        %339 = OpLabel
+        %345 = OpUGreaterThanEqual %bool %343 %uint_1
+               OpSelectionMerge %346 None
+               OpBranchConditional %345 %347 %346
+        %347 = OpLabel
+               OpBranch %342
+        %346 = OpLabel
+        %348 = OpAccessChain %_ptr_Function_S %337 %343
+        %349 = OpLoad %S %348 None
+        %350 = OpCompositeConstruct %_arr_uint_uint_1 %343
+        %351 = OpFunctionCall %void %tint_store_and_preserve_padding_9 %350 %349
+               OpBranch %340
         %340 = OpLabel
+        %344 = OpIAdd %uint %343 %uint_1
+               OpBranch %341
+        %342 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_store_and_preserve_padding_20 = OpFunction %void None %351
+%tint_store_and_preserve_padding_20 = OpFunction %void None %353
 %value_param_20 = OpFunctionParameter %_arr_S2_uint_1
-        %352 = OpLabel
-        %353 = OpVariable %_ptr_Function__arr_S2_uint_1 Function
-               OpStore %353 %value_param_20
-               OpBranch %355
-        %355 = OpLabel
-               OpBranch %358
-        %358 = OpLabel
-        %360 = OpPhi %uint %uint_0 %355 %361 %357
-               OpLoopMerge %359 %357 None
-               OpBranch %356
-        %356 = OpLabel
-        %362 = OpUGreaterThanEqual %bool %360 %uint_1
-               OpSelectionMerge %363 None
-               OpBranchConditional %362 %364 %363
-        %364 = OpLabel
-               OpBranch %359
-        %363 = OpLabel
-        %365 = OpAccessChain %_ptr_Function_S2 %353 %360
-        %367 = OpLoad %S2 %365 None
-        %368 = OpCompositeConstruct %_arr_uint_uint_1 %360
-        %369 = OpFunctionCall %void %tint_store_and_preserve_padding_12 %368 %367
+        %354 = OpLabel
+        %355 = OpVariable %_ptr_Function__arr_S2_uint_1 Function
+               OpStore %355 %value_param_20
                OpBranch %357
         %357 = OpLabel
-        %361 = OpIAdd %uint %360 %uint_1
+               OpBranch %360
+        %360 = OpLabel
+        %362 = OpPhi %uint %uint_0 %357 %363 %359
+               OpLoopMerge %361 %359 None
                OpBranch %358
+        %358 = OpLabel
+        %364 = OpUGreaterThanEqual %bool %362 %uint_1
+               OpSelectionMerge %365 None
+               OpBranchConditional %364 %366 %365
+        %366 = OpLabel
+               OpBranch %361
+        %365 = OpLabel
+        %367 = OpAccessChain %_ptr_Function_S2 %355 %362
+        %369 = OpLoad %S2 %367 None
+        %370 = OpCompositeConstruct %_arr_uint_uint_1 %362
+        %371 = OpFunctionCall %void %tint_store_and_preserve_padding_12 %370 %369
+               OpBranch %359
         %359 = OpLabel
+        %363 = OpIAdd %uint %362 %uint_1
+               OpBranch %360
+        %361 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2100.wgsl.expected.glsl b/test/tint/bug/tint/2100.wgsl.expected.glsl
index cc282f3..a6ee26c 100644
--- a/test/tint/bug/tint/2100.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2100.wgsl.expected.glsl
@@ -16,7 +16,7 @@
   S_std140 inner;
 } v;
 vec4 tint_symbol_1_inner() {
-  float x = v.inner.matrix_view[0].z;
+  float x = v.inner.matrix_view[0u].z;
   return vec4(x, 0.0f, 0.0f, 1.0f);
 }
 void main() {
diff --git a/test/tint/bug/tint/2100.wgsl.expected.ir.msl b/test/tint/bug/tint/2100.wgsl.expected.ir.msl
index a56ae86..445ec49 100644
--- a/test/tint/bug/tint/2100.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2100.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
 };
 
 float4 tint_symbol_1_inner(tint_module_vars_struct tint_module_vars) {
-  float const x = (*tint_module_vars.tint_symbol).matrix_view[0][2u];
+  float const x = (*tint_module_vars.tint_symbol).matrix_view[0u][2u];
   return float4(x, 0.0f, 0.0f, 1.0f);
 }
 
diff --git a/test/tint/bug/tint/2100.wgsl.expected.spvasm b/test/tint/bug/tint/2100.wgsl.expected.spvasm
index 2b15361..dab686d 100644
--- a/test/tint/bug/tint/2100.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2100.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -47,26 +47,24 @@
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
      %uint_2 = OpConstant %uint 2
     %float_0 = OpConstant %float 0
     %float_1 = OpConstant %float 1
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
  %main_inner = OpFunction %v4float None %14
          %15 = OpLabel
-         %16 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %int_0
-         %22 = OpAccessChain %_ptr_Uniform_float %16 %uint_2
-          %x = OpLoad %float %22 None
-         %26 = OpCompositeConstruct %v4float %x %float_0 %float_0 %float_1
-               OpReturnValue %26
+         %16 = OpAccessChain %_ptr_Uniform_v4float %1 %uint_0 %uint_0 %uint_0
+         %20 = OpAccessChain %_ptr_Uniform_float %16 %uint_2
+          %x = OpLoad %float %20 None
+         %24 = OpCompositeConstruct %v4float %x %float_0 %float_0 %float_1
+               OpReturnValue %24
                OpFunctionEnd
-       %main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %main_inner
-               OpStore %main_position_Output %33 None
+       %main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4float %main_inner
+               OpStore %main_position_Output %31 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2146.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/2146.wgsl.expected.dxc.hlsl
index cae1694..250bffe 100644
--- a/test/tint/bug/tint/2146.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/2146.wgsl.expected.dxc.hlsl
@@ -17,6 +17,6 @@
   vector<float16_t, 4> a = (float16_t(0.0h)).xxxx;
   float16_t b = float16_t(1.0h);
   int tint_symbol_1 = 0;
-  set_vector_element(a, tint_symbol_1, (a[tint_symbol_1] + b));
+  set_vector_element(a, min(uint(tint_symbol_1), 3u), (a[min(uint(tint_symbol_1), 3u)] + b));
   return;
 }
diff --git a/test/tint/bug/tint/2146.wgsl.expected.glsl b/test/tint/bug/tint/2146.wgsl.expected.glsl
index c04e49b..56fbd04 100644
--- a/test/tint/bug/tint/2146.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2146.wgsl.expected.glsl
@@ -5,5 +5,5 @@
 void main() {
   f16vec4 a = f16vec4(0.0hf);
   float16_t b = 1.0hf;
-  a[0] = (a.x + b);
+  a[0u] = (a.x + b);
 }
diff --git a/test/tint/bug/tint/2146.wgsl.expected.ir.msl b/test/tint/bug/tint/2146.wgsl.expected.ir.msl
index 1ed120c..58faffb 100644
--- a/test/tint/bug/tint/2146.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2146.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 kernel void tint_symbol() {
   half4 a = half4(0.0h);
   half const b = 1.0h;
-  a[0] = (a[0] + b);
+  a[0u] = (a[0u] + b);
 }
diff --git a/test/tint/bug/tint/2146.wgsl.expected.msl b/test/tint/bug/tint/2146.wgsl.expected.msl
index cbbabcb..345a945 100644
--- a/test/tint/bug/tint/2146.wgsl.expected.msl
+++ b/test/tint/bug/tint/2146.wgsl.expected.msl
@@ -17,7 +17,7 @@
   half4 a = half4(0.0h);
   half const b = 1.0h;
   int const tint_symbol_2 = 0;
-  a[tint_symbol_2] = (a[tint_symbol_2] + b);
+  a[min(uint(tint_symbol_2), 3u)] = (a[min(uint(tint_symbol_2), 3u)] + b);
   return;
 }
 
diff --git a/test/tint/bug/tint/2146.wgsl.expected.spvasm b/test/tint/bug/tint/2146.wgsl.expected.spvasm
index b761569..8e3575c 100644
--- a/test/tint/bug/tint/2146.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2146.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
                OpCapability Float16
@@ -40,8 +40,6 @@
          %26 = OpConstantNull %v4half
           %b = OpConstant %half 0x1p+0
 %_ptr_Function_half = OpTypePointer Function %half
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
 %globalId2Index = OpFunction %uint None %13
          %14 = OpLabel
          %15 = OpAccessChain %_ptr_Private_uint %globalId %uint_0
@@ -52,10 +50,10 @@
          %21 = OpLabel
           %a = OpVariable %_ptr_Function_v4half Function
                OpStore %a %26
-         %28 = OpAccessChain %_ptr_Function_half %a %int_0
-         %32 = OpLoad %half %28 None
-         %33 = OpFAdd %half %32 %b
-         %34 = OpAccessChain %_ptr_Function_half %a %int_0
-               OpStore %34 %33 None
+         %28 = OpAccessChain %_ptr_Function_half %a %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFAdd %half %30 %b
+         %32 = OpAccessChain %_ptr_Function_half %a %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2177.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/2177.wgsl.expected.dxc.hlsl
index 79d5ea6..17c77d8 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/2177.wgsl.expected.dxc.hlsl
@@ -17,6 +17,9 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  arr.Store(0u, asuint(f0_arr()));
+  uint tint_symbol_3 = 0u;
+  arr.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
+  arr.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(f0_arr()));
   return;
 }
diff --git a/test/tint/bug/tint/2177.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/2177.wgsl.expected.fxc.hlsl
index 79d5ea6..17c77d8 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/2177.wgsl.expected.fxc.hlsl
@@ -17,6 +17,9 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  arr.Store(0u, asuint(f0_arr()));
+  uint tint_symbol_3 = 0u;
+  arr.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
+  arr.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(f0_arr()));
   return;
 }
diff --git a/test/tint/bug/tint/2177.wgsl.expected.glsl b/test/tint/bug/tint/2177.wgsl.expected.glsl
index ac98cda..03b8559 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2177.wgsl.expected.glsl
@@ -15,5 +15,7 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  v.inner[0] = f0();
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(0), v_1);
+  v.inner[v_2] = f0();
 }
diff --git a/test/tint/bug/tint/2177.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/2177.wgsl.expected.ir.dxc.hlsl
index af525b9..7bf7a33 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/2177.wgsl.expected.ir.dxc.hlsl
@@ -16,6 +16,10 @@
 void main() {
   uint v = 0u;
   arr.GetDimensions(v);
-  arr.Store(0u, f0((v / 4u)));
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  uint v_3 = 0u;
+  arr.GetDimensions(v_3);
+  arr.Store((0u + v_2), f0((v_3 / 4u)));
 }
 
diff --git a/test/tint/bug/tint/2177.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/2177.wgsl.expected.ir.fxc.hlsl
index af525b9..7bf7a33 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/2177.wgsl.expected.ir.fxc.hlsl
@@ -16,6 +16,10 @@
 void main() {
   uint v = 0u;
   arr.GetDimensions(v);
-  arr.Store(0u, f0((v / 4u)));
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  uint v_3 = 0u;
+  arr.GetDimensions(v_3);
+  arr.Store((0u + v_2), f0((v_3 / 4u)));
 }
 
diff --git a/test/tint/bug/tint/2177.wgsl.expected.ir.msl b/test/tint/bug/tint/2177.wgsl.expected.ir.msl
index e73ec84..8d5d560 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2177.wgsl.expected.ir.msl
@@ -32,5 +32,7 @@
 
 kernel void tint_symbol(device tint_array<uint, 1>* arr [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arr=arr, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
-  (*tint_module_vars.arr)[0] = f0(tint_module_vars.arr, ((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u));
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  device uint* const v_1 = (&(*tint_module_vars.arr)[min(uint(0), v)]);
+  (*v_1) = f0(tint_module_vars.arr, ((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u));
 }
diff --git a/test/tint/bug/tint/2177.wgsl.expected.msl b/test/tint/bug/tint/2177.wgsl.expected.msl
index 16bd3f5..5632f07 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.msl
+++ b/test/tint/bug/tint/2177.wgsl.expected.msl
@@ -35,7 +35,7 @@
 }
 
 kernel void tint_symbol(device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]]) {
-  (*(tint_symbol_1)).arr[0] = f0(&((*(tint_symbol_1)).arr), ((*(tint_symbol_3)).array_lengths[0u][0u] / 4u));
+  (*(tint_symbol_1)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][0u] / 4u) - 1u))] = f0(&((*(tint_symbol_1)).arr), ((*(tint_symbol_3)).array_lengths[0u][0u] / 4u));
   return;
 }
 
diff --git a/test/tint/bug/tint/2177.wgsl.expected.spvasm b/test/tint/bug/tint/2177.wgsl.expected.spvasm
index db83b36..70bbbad 100644
--- a/test/tint/bug/tint/2177.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2177.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -29,9 +30,10 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %21 = OpTypeFunction %void
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
          %f2 = OpFunction %uint None %7
           %8 = OpLabel
           %9 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
@@ -50,8 +52,13 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_0
-         %27 = OpFunctionCall %uint %f0
-               OpStore %23 %27 None
+         %23 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %24 = OpArrayLength %uint %1 0
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_0
+         %30 = OpExtInst %uint %31 UMin %27 %25
+         %32 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %30
+         %34 = OpFunctionCall %uint %f0
+               OpStore %32 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2201.wgsl.expected.ir.msl b/test/tint/bug/tint/2201.wgsl.expected.ir.msl
index 9e9e983..2cc5558 100644
--- a/test/tint/bug/tint/2201.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2201.wgsl.expected.ir.msl
@@ -5,9 +5,13 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (true) {
         break;
       } else {
diff --git a/test/tint/bug/tint/2201.wgsl.expected.msl b/test/tint/bug/tint/2201.wgsl.expected.msl
index ee4baec..2aba54c 100644
--- a/test/tint/bug/tint/2201.wgsl.expected.msl
+++ b/test/tint/bug/tint/2201.wgsl.expected.msl
@@ -5,8 +5,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if (true) {
       break;
     } else {
diff --git a/test/tint/bug/tint/2202.wgsl.expected.ir.msl b/test/tint/bug/tint/2202.wgsl.expected.ir.msl
index 8217706..b7f4c947 100644
--- a/test/tint/bug/tint/2202.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2202.wgsl.expected.ir.msl
@@ -5,11 +5,16 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       {
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false_1)
           return;
         }
       }
diff --git a/test/tint/bug/tint/2202.wgsl.expected.msl b/test/tint/bug/tint/2202.wgsl.expected.msl
index d948a34..767e10c 100644
--- a/test/tint/bug/tint/2202.wgsl.expected.msl
+++ b/test/tint/bug/tint/2202.wgsl.expected.msl
@@ -5,9 +5,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       return;
     }
     bool const _e9 = true;
diff --git a/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl
index d42eb6e..016f552 100644
--- a/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/221.wgsl.expected.dxc.hlsl
@@ -14,14 +14,14 @@
     uint p_save = i;
     if ((tint_mod(i, 2u) == 0u)) {
       {
-        b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
+        b.Store((4u + (4u * min(p_save, 49u))), asuint((b.Load((4u + (4u * min(p_save, 49u)))) * 2u)));
         i = (i + 1u);
       }
       continue;
     }
-    b.Store((4u + (4u * p_save)), asuint(0u));
+    b.Store((4u + (4u * min(p_save, 49u))), asuint(0u));
     {
-      b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
+      b.Store((4u + (4u * min(p_save, 49u))), asuint((b.Load((4u + (4u * min(p_save, 49u)))) * 2u)));
       i = (i + 1u);
     }
   }
diff --git a/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl
index d42eb6e..016f552 100644
--- a/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/221.wgsl.expected.fxc.hlsl
@@ -14,14 +14,14 @@
     uint p_save = i;
     if ((tint_mod(i, 2u) == 0u)) {
       {
-        b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
+        b.Store((4u + (4u * min(p_save, 49u))), asuint((b.Load((4u + (4u * min(p_save, 49u)))) * 2u)));
         i = (i + 1u);
       }
       continue;
     }
-    b.Store((4u + (4u * p_save)), asuint(0u));
+    b.Store((4u + (4u * min(p_save, 49u))), asuint(0u));
     {
-      b.Store((4u + (4u * p_save)), asuint((b.Load((4u + (4u * p_save))) * 2u)));
+      b.Store((4u + (4u * min(p_save, 49u))), asuint((b.Load((4u + (4u * min(p_save, 49u)))) * 2u)));
       i = (i + 1u);
     }
   }
diff --git a/test/tint/bug/tint/221.wgsl.expected.glsl b/test/tint/bug/tint/221.wgsl.expected.glsl
index c8a8fc2..c02ebbd 100644
--- a/test/tint/bug/tint/221.wgsl.expected.glsl
+++ b/test/tint/bug/tint/221.wgsl.expected.glsl
@@ -21,7 +21,7 @@
       if ((i >= v.inner.count)) {
         break;
       }
-      uint v_1 = i;
+      uint v_1 = min(i, 49u);
       if ((tint_mod_u32(i, 2u) == 0u)) {
         {
           v.inner.data[v_1] = (v.inner.data[v_1] * 2u);
diff --git a/test/tint/bug/tint/221.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.ir.dxc.hlsl
index 67ffddd..9588e5e 100644
--- a/test/tint/bug/tint/221.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/221.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
       if ((i >= b.Load(0u))) {
         break;
       }
-      uint v_1 = (i * 4u);
+      uint v_1 = (min(i, 49u) * 4u);
       if ((tint_mod_u32(i, 2u) == 0u)) {
         {
           b.Store((4u + v_1), (b.Load((4u + v_1)) * 2u));
diff --git a/test/tint/bug/tint/221.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/221.wgsl.expected.ir.fxc.hlsl
index 67ffddd..9588e5e 100644
--- a/test/tint/bug/tint/221.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/221.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
       if ((i >= b.Load(0u))) {
         break;
       }
-      uint v_1 = (i * 4u);
+      uint v_1 = (min(i, 49u) * 4u);
       if ((tint_mod_u32(i, 2u) == 0u)) {
         {
           b.Store((4u + v_1), (b.Load((4u + v_1)) * 2u));
diff --git a/test/tint/bug/tint/221.wgsl.expected.ir.msl b/test/tint/bug/tint/221.wgsl.expected.ir.msl
index 0f683ac..0492a2d 100644
--- a/test/tint/bug/tint/221.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/221.wgsl.expected.ir.msl
@@ -22,6 +22,9 @@
   device Buf* b;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 uint tint_mod_u32(uint lhs, uint rhs) {
   return (lhs - ((lhs / select(rhs, 1u, (rhs == 0u))) * select(rhs, 1u, (rhs == 0u))));
 }
@@ -31,10 +34,11 @@
   uint i = 0u;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i >= (*tint_module_vars.b).count)) {
         break;
       }
-      device uint* const p = (&(*tint_module_vars.b).data[i]);
+      device uint* const p = (&(*tint_module_vars.b).data[min(i, 49u)]);
       if ((tint_mod_u32(i, 2u) == 0u)) {
         {
           (*p) = ((*p) * 2u);
diff --git a/test/tint/bug/tint/221.wgsl.expected.msl b/test/tint/bug/tint/221.wgsl.expected.msl
index 9c7f193..6fb4d6c 100644
--- a/test/tint/bug/tint/221.wgsl.expected.msl
+++ b/test/tint/bug/tint/221.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Buf {
   /* 0x0000 */ uint count;
   /* 0x0004 */ tint_array<uint, 50> data;
@@ -26,10 +29,11 @@
 kernel void tint_symbol(device Buf* tint_symbol_1 [[buffer(0)]]) {
   uint i = 0u;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i >= (*(tint_symbol_1)).count)) {
       break;
     }
-    uint const p_save = i;
+    uint const p_save = min(i, 49u);
     if ((tint_mod(i, 2u) == 0u)) {
       {
         (*(tint_symbol_1)).data[p_save] = ((*(tint_symbol_1)).data[p_save] * 2u);
diff --git a/test/tint/bug/tint/221.wgsl.expected.spvasm b/test/tint/bug/tint/221.wgsl.expected.spvasm
index 104ab44..dd13dd8 100644
--- a/test/tint/bug/tint/221.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/221.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 50
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -39,9 +40,10 @@
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
        %bool = OpTypeBool
+    %uint_49 = OpConstant %uint 49
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
-         %43 = OpTypeFunction %uint %uint %uint
+         %46 = OpTypeFunction %uint %uint %uint
        %main = OpFunction %void None %10
          %11 = OpLabel
           %i = OpVariable %_ptr_Function_uint Function
@@ -61,36 +63,37 @@
                OpBranch %18
          %25 = OpLabel
          %27 = OpLoad %uint %i None
-          %p = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_1 %27
-         %30 = OpLoad %uint %i None
-         %31 = OpFunctionCall %uint %tint_mod_u32 %30 %uint_2
-         %34 = OpIEqual %bool %31 %uint_0
-               OpSelectionMerge %35 None
-               OpBranchConditional %34 %36 %35
-         %36 = OpLabel
+         %28 = OpExtInst %uint %29 UMin %27 %uint_49
+          %p = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_1 %28
+         %33 = OpLoad %uint %i None
+         %34 = OpFunctionCall %uint %tint_mod_u32 %33 %uint_2
+         %37 = OpIEqual %bool %34 %uint_0
+               OpSelectionMerge %38 None
+               OpBranchConditional %37 %39 %38
+         %39 = OpLabel
                OpBranch %16
-         %35 = OpLabel
+         %38 = OpLabel
                OpStore %p %uint_0 None
                OpBranch %16
          %16 = OpLabel
-         %37 = OpLoad %uint %p None
-         %38 = OpIMul %uint %37 %uint_2
-               OpStore %p %38 None
-         %39 = OpLoad %uint %i None
-         %40 = OpIAdd %uint %39 %uint_1
-               OpStore %i %40 None
+         %40 = OpLoad %uint %p None
+         %41 = OpIMul %uint %40 %uint_2
+               OpStore %p %41 None
+         %42 = OpLoad %uint %i None
+         %43 = OpIAdd %uint %42 %uint_1
+               OpStore %i %43 None
                OpBranch %17
          %18 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_mod_u32 = OpFunction %uint None %43
+%tint_mod_u32 = OpFunction %uint None %46
         %lhs = OpFunctionParameter %uint
         %rhs = OpFunctionParameter %uint
-         %44 = OpLabel
-         %45 = OpIEqual %bool %rhs %uint_0
-         %46 = OpSelect %uint %45 %uint_1 %rhs
-         %47 = OpUDiv %uint %lhs %46
-         %48 = OpIMul %uint %47 %46
-         %49 = OpISub %uint %lhs %48
-               OpReturnValue %49
+         %47 = OpLabel
+         %48 = OpIEqual %bool %rhs %uint_0
+         %49 = OpSelect %uint %48 %uint_1 %rhs
+         %50 = OpUDiv %uint %lhs %49
+         %51 = OpIMul %uint %50 %49
+         %52 = OpISub %uint %lhs %51
+               OpReturnValue %52
                OpFunctionEnd
diff --git a/test/tint/bug/tint/2237.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/2237.wgsl.expected.dxc.hlsl
index e7d539c..ca9c483 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/2237.wgsl.expected.dxc.hlsl
@@ -2,13 +2,13 @@
 
 uint foo() {
   uint tint_symbol_2[4] = {0u, 1u, 2u, 4u};
-  return tint_symbol_2[buffer.Load(0u)];
+  return tint_symbol_2[min(buffer.Load(0u), 3u)];
 }
 
 [numthreads(1, 1, 1)]
 void main() {
   uint tint_symbol_3[4] = {0u, 1u, 2u, 4u};
-  uint v = tint_symbol_3[buffer.Load(0u)];
+  uint v = tint_symbol_3[min(buffer.Load(0u), 3u)];
   uint tint_symbol = v;
   uint tint_symbol_1 = foo();
   buffer.Store(0u, asuint((tint_symbol + tint_symbol_1)));
diff --git a/test/tint/bug/tint/2237.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/2237.wgsl.expected.fxc.hlsl
index e7d539c..ca9c483 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/2237.wgsl.expected.fxc.hlsl
@@ -2,13 +2,13 @@
 
 uint foo() {
   uint tint_symbol_2[4] = {0u, 1u, 2u, 4u};
-  return tint_symbol_2[buffer.Load(0u)];
+  return tint_symbol_2[min(buffer.Load(0u), 3u)];
 }
 
 [numthreads(1, 1, 1)]
 void main() {
   uint tint_symbol_3[4] = {0u, 1u, 2u, 4u};
-  uint v = tint_symbol_3[buffer.Load(0u)];
+  uint v = tint_symbol_3[min(buffer.Load(0u), 3u)];
   uint tint_symbol = v;
   uint tint_symbol_1 = foo();
   buffer.Store(0u, asuint((tint_symbol + tint_symbol_1)));
diff --git a/test/tint/bug/tint/2237.wgsl.expected.glsl b/test/tint/bug/tint/2237.wgsl.expected.glsl
index 2fa37f9..666ec25 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.glsl
+++ b/test/tint/bug/tint/2237.wgsl.expected.glsl
@@ -5,10 +5,10 @@
   uint inner;
 } v_1;
 uint foo() {
-  return uint[4](0u, 1u, 2u, 4u)[v_1.inner];
+  return uint[4](0u, 1u, 2u, 4u)[min(v_1.inner, 3u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint v = uint[4](0u, 1u, 2u, 4u)[v_1.inner];
+  uint v = uint[4](0u, 1u, 2u, 4u)[min(v_1.inner, 3u)];
   v_1.inner = (v + foo());
 }
diff --git a/test/tint/bug/tint/2237.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/2237.wgsl.expected.ir.dxc.hlsl
index 16afd12..86215c6 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/2237.wgsl.expected.ir.dxc.hlsl
@@ -2,13 +2,13 @@
 RWByteAddressBuffer buffer : register(u0);
 uint foo() {
   uint v_1[4] = {0u, 1u, 2u, 4u};
-  return v_1[buffer.Load(0u)];
+  return v_1[min(buffer.Load(0u), 3u)];
 }
 
 [numthreads(1, 1, 1)]
 void main() {
   uint v_2[4] = {0u, 1u, 2u, 4u};
-  uint v = v_2[buffer.Load(0u)];
+  uint v = v_2[min(buffer.Load(0u), 3u)];
   buffer.Store(0u, (v + foo()));
 }
 
diff --git a/test/tint/bug/tint/2237.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/2237.wgsl.expected.ir.fxc.hlsl
index 16afd12..86215c6 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/2237.wgsl.expected.ir.fxc.hlsl
@@ -2,13 +2,13 @@
 RWByteAddressBuffer buffer : register(u0);
 uint foo() {
   uint v_1[4] = {0u, 1u, 2u, 4u};
-  return v_1[buffer.Load(0u)];
+  return v_1[min(buffer.Load(0u), 3u)];
 }
 
 [numthreads(1, 1, 1)]
 void main() {
   uint v_2[4] = {0u, 1u, 2u, 4u};
-  uint v = v_2[buffer.Load(0u)];
+  uint v = v_2[min(buffer.Load(0u), 3u)];
   buffer.Store(0u, (v + foo()));
 }
 
diff --git a/test/tint/bug/tint/2237.wgsl.expected.ir.msl b/test/tint/bug/tint/2237.wgsl.expected.ir.msl
index 476ad77..7f7906c 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/2237.wgsl.expected.ir.msl
@@ -18,11 +18,11 @@
 };
 
 uint foo(tint_module_vars_struct tint_module_vars) {
-  return tint_array<uint, 4>{0u, 1u, 2u, 4u}[(*tint_module_vars.tint_symbol)];
+  return tint_array<uint, 4>{0u, 1u, 2u, 4u}[min((*tint_module_vars.tint_symbol), 3u)];
 }
 
 kernel void tint_symbol_1(device uint* tint_symbol [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.tint_symbol=tint_symbol};
-  uint const v = tint_array<uint, 4>{0u, 1u, 2u, 4u}[(*tint_module_vars.tint_symbol)];
+  uint const v = tint_array<uint, 4>{0u, 1u, 2u, 4u}[min((*tint_module_vars.tint_symbol), 3u)];
   (*tint_module_vars.tint_symbol) = (v + foo(tint_module_vars));
 }
diff --git a/test/tint/bug/tint/2237.wgsl.expected.msl b/test/tint/bug/tint/2237.wgsl.expected.msl
index b3a137b..927b25a 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.msl
+++ b/test/tint/bug/tint/2237.wgsl.expected.msl
@@ -16,12 +16,12 @@
 
 uint foo(device uint* const tint_symbol_6) {
   tint_array<uint, 4> const tint_symbol_4 = tint_array<uint, 4>{0u, 1u, 2u, 4u};
-  return tint_symbol_4[*(tint_symbol_6)];
+  return tint_symbol_4[min(*(tint_symbol_6), 3u)];
 }
 
 kernel void tint_symbol_1(device uint* tint_symbol_7 [[buffer(0)]]) {
   tint_array<uint, 4> const tint_symbol_5 = tint_array<uint, 4>{0u, 1u, 2u, 4u};
-  uint const v = tint_symbol_5[*(tint_symbol_7)];
+  uint const v = tint_symbol_5[min(*(tint_symbol_7), 3u)];
   uint const tint_symbol_2 = v;
   uint const tint_symbol_3 = foo(tint_symbol_7);
   *(tint_symbol_7) = (tint_symbol_2 + tint_symbol_3);
diff --git a/test/tint/bug/tint/2237.wgsl.expected.spvasm b/test/tint/bug/tint/2237.wgsl.expected.spvasm
index ad3488b..67ef7b2 100644
--- a/test/tint/bug/tint/2237.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/2237.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -32,26 +33,29 @@
           %5 = OpVariable %_ptr_Private__arr_uint_uint_4 Private %9
          %14 = OpTypeFunction %uint
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+     %uint_3 = OpConstant %uint 3
 %_ptr_Private_uint = OpTypePointer Private %uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
         %foo = OpFunction %uint None %14
          %15 = OpLabel
          %16 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
          %18 = OpLoad %uint %16 None
-         %19 = OpAccessChain %_ptr_Private_uint %5 %18
-         %21 = OpLoad %uint %19 None
-               OpReturnValue %21
+         %19 = OpExtInst %uint %20 UMin %18 %uint_3
+         %22 = OpAccessChain %_ptr_Private_uint %5 %19
+         %24 = OpLoad %uint %22 None
+               OpReturnValue %24
                OpFunctionEnd
-       %main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-         %27 = OpLoad %uint %26 None
-         %28 = OpAccessChain %_ptr_Private_uint %5 %27
-          %v = OpLoad %uint %28 None
-         %30 = OpFunctionCall %uint %foo
-         %31 = OpIAdd %uint %v %30
-         %32 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %32 %31 None
+       %main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+         %30 = OpLoad %uint %29 None
+         %31 = OpExtInst %uint %20 UMin %30 %uint_3
+         %32 = OpAccessChain %_ptr_Private_uint %5 %31
+          %v = OpLoad %uint %32 None
+         %34 = OpFunctionCall %uint %foo
+         %35 = OpIAdd %uint %v %34
+         %36 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/349291130.wgsl.expected.ir.msl b/test/tint/bug/tint/349291130.wgsl.expected.ir.msl
index e8798fc..57661c0 100644
--- a/test/tint/bug/tint/349291130.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/349291130.wgsl.expected.ir.msl
@@ -5,11 +5,15 @@
   texture2d<float, access::sample> tint_symbol;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void e(texture2d<float, access::sample> tint_symbol [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.tint_symbol=tint_symbol};
   {
     uint level = tint_module_vars.tint_symbol.get_num_mip_levels();
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((level > 0u)) {
       } else {
         break;
diff --git a/test/tint/bug/tint/349291130.wgsl.expected.msl b/test/tint/bug/tint/349291130.wgsl.expected.msl
index c656394..83fff02 100644
--- a/test/tint/bug/tint/349291130.wgsl.expected.msl
+++ b/test/tint/bug/tint/349291130.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void e(texture2d<float, access::sample> tint_symbol_1 [[texture(0)]]) {
   {
     for(uint level = tint_symbol_1.get_num_mip_levels(); (level > 0u); ) {
+      TINT_ISOLATE_UB(tint_volatile_false);
     }
   }
   return;
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.glsl b/test/tint/bug/tint/349310442.wgsl.expected.glsl
index 0216bd0..17cf5eb 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.glsl
+++ b/test/tint/bug/tint/349310442.wgsl.expected.glsl
@@ -101,5 +101,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   tint_ExternalTextureParams v_16 = tint_convert_tint_ExternalTextureParams(v_1.inner);
-  vec4 r = tint_TextureLoadExternal(v_16, uvec2(ivec2(0)));
+  vec4 r = tint_TextureLoadExternal(v_16, min(uvec2(ivec2(0)), ((v_16.apparentSize + uvec2(1u)) - uvec2(1u))));
 }
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/349310442.wgsl.expected.ir.dxc.hlsl
index c1ace6d..eeec54e 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/349310442.wgsl.expected.ir.dxc.hlsl
@@ -49,78 +49,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = t_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = t_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = t_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = t_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = t_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = t_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(t_params[(start_byte_offset / 16u)].xyz), asfloat(t_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(t_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), t_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), t_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(t_params[(start_byte_offset / 16u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)]), asfloat(t_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = t_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = t_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = t_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = t_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = t_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = t_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = t_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = t_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = t_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = t_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = t_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = t_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 [numthreads(1, 1, 1)]
 void i() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 r = tint_TextureLoadExternal(t_plane0, t_plane1, v_48, uint2((int(0)).xx));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 r = tint_TextureLoadExternal(t_plane0, t_plane1, v_55, uint2((int(0)).xx));
 }
 
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/349310442.wgsl.expected.ir.fxc.hlsl
index c1ace6d..eeec54e 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/349310442.wgsl.expected.ir.fxc.hlsl
@@ -49,78 +49,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = t_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = t_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = t_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = t_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = t_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = t_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(t_params[(start_byte_offset / 16u)].xyz), asfloat(t_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(t_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), t_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(t_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), t_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(t_params[(start_byte_offset / 16u)]), asfloat(t_params[((16u + start_byte_offset) / 16u)]), asfloat(t_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = t_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = t_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = t_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = t_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = t_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = t_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = t_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = t_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = t_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = t_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = t_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = t_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = t_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = t_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 [numthreads(1, 1, 1)]
 void i() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 r = tint_TextureLoadExternal(t_plane0, t_plane1, v_48, uint2((int(0)).xx));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 r = tint_TextureLoadExternal(t_plane0, t_plane1, v_55, uint2((int(0)).xx));
 }
 
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.ir.msl b/test/tint/bug/tint/349310442.wgsl.expected.ir.msl
index aa7cfeb..df96959 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/349310442.wgsl.expected.ir.msl
@@ -115,5 +115,5 @@
 kernel void i(texture2d<float, access::sample> t_plane0 [[texture(0)]], texture2d<float, access::sample> t_plane1 [[texture(1)]], const constant tint_ExternalTextureParams_packed_vec3* t_params [[buffer(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_plane0=t_plane0, .t_plane1=t_plane1, .t_params=t_params};
   tint_ExternalTextureParams const v_19 = tint_load_struct_packed_vec3(tint_module_vars.t_params);
-  float4 r = tint_TextureLoadExternal(tint_module_vars.t_plane0, tint_module_vars.t_plane1, v_19, uint2(int2(0)));
+  float4 r = tint_TextureLoadExternal(tint_module_vars.t_plane0, tint_module_vars.t_plane1, v_19, min(uint2(int2(0)), ((v_19.apparentSize + uint2(1u)) - uint2(1u))));
 }
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.msl b/test/tint/bug/tint/349310442.wgsl.expected.msl
index 3bddf7d..43117cd 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.msl
+++ b/test/tint/bug/tint/349310442.wgsl.expected.msl
@@ -93,6 +93,10 @@
   return select(uint2(4294967295u), select(uint2(v), uint2(0u), (v < float2(0.0f))), (v <= float2(4294967040.0f)));
 }
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float3 gammaCorrection(float3 v, GammaTransferParams params) {
   bool3 const cond = (fabs(v) < float3(params.D));
   float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F));
@@ -119,7 +123,7 @@
 }
 
 kernel void i(texture2d<float, access::sample> tint_symbol [[texture(0)]], texture2d<float, access::sample> tint_symbol_1 [[texture(1)]], const constant ExternalTextureParams_tint_packed_vec3* tint_symbol_2 [[buffer(2)]]) {
-  float4 r = textureLoadExternal(tint_symbol, tint_symbol_1, int2(0), tint_unpack_vec3_in_composite_1(*(tint_symbol_2)));
+  float4 r = textureLoadExternal(tint_symbol, tint_symbol_1, tint_clamp(int2(0), int2(0), int2((((*(tint_symbol_2)).apparentSize + uint2(1u)) - uint2(1u)))), tint_unpack_vec3_in_composite_1(*(tint_symbol_2)));
   return;
 }
 
diff --git a/test/tint/bug/tint/349310442.wgsl.expected.spvasm b/test/tint/bug/tint/349310442.wgsl.expected.spvasm
index 9014748..8755a13 100644
--- a/test/tint/bug/tint/349310442.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/349310442.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 148
+; Bound: 153
 ; Schema: 0
                OpCapability Shader
-         %52 = OpExtInstImport "GLSL.std.450"
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %i "i"
                OpExecutionMode %i LocalSize 1 1 1
@@ -153,17 +153,18 @@
 %mat3v3float = OpTypeMatrix %v3float 3
 %mat3v2float = OpTypeMatrix %v2float 3
 %tint_ExternalTextureParams = OpTypeStruct %uint %uint %mat3v4float %tint_GammaTransferParams %tint_GammaTransferParams %mat3v3float %mat3v2float %mat3v2float %v2float %v2float %v2float %v2float %v2uint %v2float
+     %uint_1 = OpConstant %uint 1
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
-         %33 = OpConstantNull %v2int
+         %38 = OpConstantNull %v2int
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %44 = OpTypeFunction %v4float %3 %3 %tint_ExternalTextureParams %v2uint
+         %51 = OpTypeFunction %v4float %3 %3 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
-     %uint_1 = OpConstant %uint 1
        %bool = OpTypeBool
-         %94 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+         %99 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %122 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %127 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
           %i = OpFunction %void None %19
          %20 = OpLabel
           %r = OpVariable %_ptr_Function_v4float Function
@@ -172,124 +173,128 @@
          %23 = OpAccessChain %_ptr_Uniform_tint_ExternalTextureParams_std140 %6 %uint_0
          %26 = OpLoad %tint_ExternalTextureParams_std140 %23 None
          %27 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %26
-         %32 = OpBitcast %v2uint %33
-         %36 = OpFunctionCall %v4float %tint_TextureLoadExternal %21 %22 %27 %32
-               OpStore %r %36
+         %32 = OpCompositeExtract %v2uint %27 12
+         %33 = OpIAdd %v2uint %32 %34
+         %36 = OpISub %v2uint %33 %34
+         %37 = OpBitcast %v2uint %38
+         %41 = OpExtInst %v2uint %42 UMin %37 %36
+         %43 = OpFunctionCall %v4float %tint_TextureLoadExternal %21 %22 %27 %41
+               OpStore %r %43
                OpReturn
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %44
+%tint_TextureLoadExternal = OpFunction %v4float None %51
     %plane_0 = OpFunctionParameter %3
     %plane_1 = OpFunctionParameter %3
      %params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2uint
-         %45 = OpLabel
-         %46 = OpCompositeExtract %uint %params 1
-         %47 = OpCompositeExtract %mat3v4float %params 2
-         %48 = OpCompositeExtract %mat3v2float %params 7
-         %49 = OpCompositeExtract %v2uint %params 12
-         %50 = OpCompositeExtract %v2float %params 13
-         %51 = OpExtInst %v2uint %52 UMin %coords %49
-         %53 = OpConvertUToF %v2float %51
-         %54 = OpCompositeConstruct %v3float %53 %float_1
-         %56 = OpMatrixTimesVector %v2float %48 %54
-         %57 = OpExtInst %v2float %52 RoundEven %56
-         %58 = OpConvertFToU %v2uint %57
-         %59 = OpCompositeExtract %uint %params 0
-         %60 = OpIEqual %bool %59 %uint_1
-               OpSelectionMerge %63 None
-               OpBranchConditional %60 %64 %65
-         %64 = OpLabel
-         %66 = OpImageFetch %v4float %plane_0 %58 Lod %uint_0
-         %67 = OpVectorShuffle %v3float %66 %66 0 1 2
-         %68 = OpCompositeExtract %float %66 3
-               OpBranch %63
-         %65 = OpLabel
-         %69 = OpImageFetch %v4float %plane_0 %58 Lod %uint_0
-         %70 = OpCompositeExtract %float %69 0
-         %71 = OpFMul %v2float %57 %50
-         %72 = OpConvertFToU %v2uint %71
-         %73 = OpImageFetch %v4float %plane_1 %72 Lod %uint_0
-         %74 = OpVectorShuffle %v2float %73 %73 0 1
-         %75 = OpCompositeConstruct %v4float %70 %74 %float_1
-         %76 = OpVectorTimesMatrix %v3float %75 %47
-               OpBranch %63
-         %63 = OpLabel
-         %77 = OpPhi %v3float %67 %64 %76 %65
-         %78 = OpPhi %float %68 %64 %float_1 %65
-         %79 = OpIEqual %bool %46 %uint_0
-               OpSelectionMerge %80 None
-               OpBranchConditional %79 %81 %82
-         %81 = OpLabel
-         %83 = OpCompositeExtract %tint_GammaTransferParams %params 3
-         %84 = OpCompositeExtract %tint_GammaTransferParams %params 4
-         %85 = OpCompositeExtract %mat3v3float %params 5
-         %86 = OpFunctionCall %v3float %tint_GammaCorrection %77 %83
-         %88 = OpMatrixTimesVector %v3float %85 %86
-         %89 = OpFunctionCall %v3float %tint_GammaCorrection %88 %84
-               OpBranch %80
-         %82 = OpLabel
-               OpBranch %80
-         %80 = OpLabel
-         %90 = OpPhi %v3float %89 %81 %77 %82
-         %91 = OpCompositeConstruct %v4float %90 %78
-               OpReturnValue %91
+         %52 = OpLabel
+         %53 = OpCompositeExtract %uint %params 1
+         %54 = OpCompositeExtract %mat3v4float %params 2
+         %55 = OpCompositeExtract %mat3v2float %params 7
+         %56 = OpCompositeExtract %v2uint %params 12
+         %57 = OpCompositeExtract %v2float %params 13
+         %58 = OpExtInst %v2uint %42 UMin %coords %56
+         %59 = OpConvertUToF %v2float %58
+         %60 = OpCompositeConstruct %v3float %59 %float_1
+         %62 = OpMatrixTimesVector %v2float %55 %60
+         %63 = OpExtInst %v2float %42 RoundEven %62
+         %64 = OpConvertFToU %v2uint %63
+         %65 = OpCompositeExtract %uint %params 0
+         %66 = OpIEqual %bool %65 %uint_1
+               OpSelectionMerge %68 None
+               OpBranchConditional %66 %69 %70
+         %69 = OpLabel
+         %71 = OpImageFetch %v4float %plane_0 %64 Lod %uint_0
+         %72 = OpVectorShuffle %v3float %71 %71 0 1 2
+         %73 = OpCompositeExtract %float %71 3
+               OpBranch %68
+         %70 = OpLabel
+         %74 = OpImageFetch %v4float %plane_0 %64 Lod %uint_0
+         %75 = OpCompositeExtract %float %74 0
+         %76 = OpFMul %v2float %63 %57
+         %77 = OpConvertFToU %v2uint %76
+         %78 = OpImageFetch %v4float %plane_1 %77 Lod %uint_0
+         %79 = OpVectorShuffle %v2float %78 %78 0 1
+         %80 = OpCompositeConstruct %v4float %75 %79 %float_1
+         %81 = OpVectorTimesMatrix %v3float %80 %54
+               OpBranch %68
+         %68 = OpLabel
+         %82 = OpPhi %v3float %72 %69 %81 %70
+         %83 = OpPhi %float %73 %69 %float_1 %70
+         %84 = OpIEqual %bool %53 %uint_0
+               OpSelectionMerge %85 None
+               OpBranchConditional %84 %86 %87
+         %86 = OpLabel
+         %88 = OpCompositeExtract %tint_GammaTransferParams %params 3
+         %89 = OpCompositeExtract %tint_GammaTransferParams %params 4
+         %90 = OpCompositeExtract %mat3v3float %params 5
+         %91 = OpFunctionCall %v3float %tint_GammaCorrection %82 %88
+         %93 = OpMatrixTimesVector %v3float %90 %91
+         %94 = OpFunctionCall %v3float %tint_GammaCorrection %93 %89
+               OpBranch %85
+         %87 = OpLabel
+               OpBranch %85
+         %85 = OpLabel
+         %95 = OpPhi %v3float %94 %86 %82 %87
+         %96 = OpCompositeConstruct %v4float %95 %83
+               OpReturnValue %96
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %94
+%tint_GammaCorrection = OpFunction %v3float None %99
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-         %95 = OpLabel
-         %96 = OpCompositeExtract %float %params_0 0
-         %97 = OpCompositeExtract %float %params_0 1
-         %98 = OpCompositeExtract %float %params_0 2
-         %99 = OpCompositeExtract %float %params_0 3
-        %100 = OpCompositeExtract %float %params_0 4
-        %101 = OpCompositeExtract %float %params_0 5
-        %102 = OpCompositeExtract %float %params_0 6
-        %103 = OpCompositeConstruct %v3float %96 %96 %96
-        %104 = OpCompositeConstruct %v3float %100 %100 %100
-        %105 = OpExtInst %v3float %52 FAbs %v
-        %106 = OpExtInst %v3float %52 FSign %v
-        %107 = OpFOrdLessThan %v3bool %105 %104
-        %109 = OpVectorTimesScalar %v3float %105 %99
-        %110 = OpCompositeConstruct %v3float %102 %102 %102
-        %111 = OpFAdd %v3float %109 %110
-        %112 = OpFMul %v3float %106 %111
-        %113 = OpVectorTimesScalar %v3float %105 %97
-        %114 = OpCompositeConstruct %v3float %98 %98 %98
-        %115 = OpFAdd %v3float %113 %114
-        %116 = OpExtInst %v3float %52 Pow %115 %103
-        %117 = OpCompositeConstruct %v3float %101 %101 %101
-        %118 = OpFAdd %v3float %116 %117
-        %119 = OpFMul %v3float %106 %118
-        %120 = OpSelect %v3float %107 %112 %119
-               OpReturnValue %120
+        %100 = OpLabel
+        %101 = OpCompositeExtract %float %params_0 0
+        %102 = OpCompositeExtract %float %params_0 1
+        %103 = OpCompositeExtract %float %params_0 2
+        %104 = OpCompositeExtract %float %params_0 3
+        %105 = OpCompositeExtract %float %params_0 4
+        %106 = OpCompositeExtract %float %params_0 5
+        %107 = OpCompositeExtract %float %params_0 6
+        %108 = OpCompositeConstruct %v3float %101 %101 %101
+        %109 = OpCompositeConstruct %v3float %105 %105 %105
+        %110 = OpExtInst %v3float %42 FAbs %v
+        %111 = OpExtInst %v3float %42 FSign %v
+        %112 = OpFOrdLessThan %v3bool %110 %109
+        %114 = OpVectorTimesScalar %v3float %110 %104
+        %115 = OpCompositeConstruct %v3float %107 %107 %107
+        %116 = OpFAdd %v3float %114 %115
+        %117 = OpFMul %v3float %111 %116
+        %118 = OpVectorTimesScalar %v3float %110 %102
+        %119 = OpCompositeConstruct %v3float %103 %103 %103
+        %120 = OpFAdd %v3float %118 %119
+        %121 = OpExtInst %v3float %42 Pow %120 %108
+        %122 = OpCompositeConstruct %v3float %106 %106 %106
+        %123 = OpFAdd %v3float %121 %122
+        %124 = OpFMul %v3float %111 %123
+        %125 = OpSelect %v3float %112 %117 %124
+               OpReturnValue %125
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %122
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %127
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %123 = OpLabel
-        %124 = OpCompositeExtract %uint %tint_input 0
-        %125 = OpCompositeExtract %uint %tint_input 1
-        %126 = OpCompositeExtract %mat3v4float %tint_input 2
-        %127 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %128 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %129 = OpCompositeExtract %v3float %tint_input 5
-        %130 = OpCompositeExtract %v3float %tint_input 6
-        %131 = OpCompositeExtract %v3float %tint_input 7
-        %132 = OpCompositeConstruct %mat3v3float %129 %130 %131
-        %133 = OpCompositeExtract %v2float %tint_input 8
-        %134 = OpCompositeExtract %v2float %tint_input 9
-        %135 = OpCompositeExtract %v2float %tint_input 10
-        %136 = OpCompositeConstruct %mat3v2float %133 %134 %135
-        %137 = OpCompositeExtract %v2float %tint_input 11
-        %138 = OpCompositeExtract %v2float %tint_input 12
-        %139 = OpCompositeExtract %v2float %tint_input 13
-        %140 = OpCompositeConstruct %mat3v2float %137 %138 %139
-        %141 = OpCompositeExtract %v2float %tint_input 14
-        %142 = OpCompositeExtract %v2float %tint_input 15
-        %143 = OpCompositeExtract %v2float %tint_input 16
-        %144 = OpCompositeExtract %v2float %tint_input 17
-        %145 = OpCompositeExtract %v2uint %tint_input 18
-        %146 = OpCompositeExtract %v2float %tint_input 19
-        %147 = OpCompositeConstruct %tint_ExternalTextureParams %124 %125 %126 %127 %128 %132 %136 %140 %141 %142 %143 %144 %145 %146
-               OpReturnValue %147
+        %128 = OpLabel
+        %129 = OpCompositeExtract %uint %tint_input 0
+        %130 = OpCompositeExtract %uint %tint_input 1
+        %131 = OpCompositeExtract %mat3v4float %tint_input 2
+        %132 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %133 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %134 = OpCompositeExtract %v3float %tint_input 5
+        %135 = OpCompositeExtract %v3float %tint_input 6
+        %136 = OpCompositeExtract %v3float %tint_input 7
+        %137 = OpCompositeConstruct %mat3v3float %134 %135 %136
+        %138 = OpCompositeExtract %v2float %tint_input 8
+        %139 = OpCompositeExtract %v2float %tint_input 9
+        %140 = OpCompositeExtract %v2float %tint_input 10
+        %141 = OpCompositeConstruct %mat3v2float %138 %139 %140
+        %142 = OpCompositeExtract %v2float %tint_input 11
+        %143 = OpCompositeExtract %v2float %tint_input 12
+        %144 = OpCompositeExtract %v2float %tint_input 13
+        %145 = OpCompositeConstruct %mat3v2float %142 %143 %144
+        %146 = OpCompositeExtract %v2float %tint_input 14
+        %147 = OpCompositeExtract %v2float %tint_input 15
+        %148 = OpCompositeExtract %v2float %tint_input 16
+        %149 = OpCompositeExtract %v2float %tint_input 17
+        %150 = OpCompositeExtract %v2uint %tint_input 18
+        %151 = OpCompositeExtract %v2float %tint_input 19
+        %152 = OpCompositeConstruct %tint_ExternalTextureParams %129 %130 %131 %132 %133 %137 %141 %145 %146 %147 %148 %149 %150 %151
+               OpReturnValue %152
                OpFunctionEnd
diff --git a/test/tint/bug/tint/354627692.wgsl.expected.ir.msl b/test/tint/bug/tint/354627692.wgsl.expected.ir.msl
index 08f909d..fb5f664 100644
--- a/test/tint/bug/tint/354627692.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/354627692.wgsl.expected.ir.msl
@@ -5,14 +5,19 @@
   device int* tint_symbol;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol_1(device int* tint_symbol [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.tint_symbol=tint_symbol};
   int i = (*tint_module_vars.tint_symbol);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       {
         {
           while(true) {
+            TINT_ISOLATE_UB(tint_volatile_false_1)
             if ((i > 5)) {
               i = as_type<int>((as_type<uint>(i) * as_type<uint>(2)));
               break;
diff --git a/test/tint/bug/tint/354627692.wgsl.expected.msl b/test/tint/bug/tint/354627692.wgsl.expected.msl
index 729e262..87e2356 100644
--- a/test/tint/bug/tint/354627692.wgsl.expected.msl
+++ b/test/tint/bug/tint/354627692.wgsl.expected.msl
@@ -1,11 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol_1(device int* tint_symbol_2 [[buffer(0)]]) {
   int i = *(tint_symbol_2);
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     {
       while(true) {
+        TINT_ISOLATE_UB(tint_volatile_false_1);
         if ((i > 5)) {
           i = as_type<int>((as_type<uint>(i) * as_type<uint>(2)));
           break;
diff --git a/test/tint/bug/tint/366037039.wgsl.expected.ir.msl b/test/tint/bug/tint/366037039.wgsl.expected.ir.msl
index 5830e23..85977d4 100644
--- a/test/tint/bug/tint/366037039.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/366037039.wgsl.expected.ir.msl
@@ -29,6 +29,9 @@
   tint_array<uint3, 4> c;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_module_vars_struct {
   const constant S_packed_vec3* ubuffer;
   device S_packed_vec3* sbuffer;
@@ -53,6 +56,7 @@
     uint v = 0u;
     v = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/bug/tint/366037039.wgsl.expected.msl b/test/tint/bug/tint/366037039.wgsl.expected.msl
index 6fa7fb0..66e4bf2 100644
--- a/test/tint/bug/tint/366037039.wgsl.expected.msl
+++ b/test/tint/bug/tint/366037039.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_u32_array_element {
   /* 0x0000 */ packed_uint3 elements;
   /* 0x000c */ tint_array<int8_t, 4> tint_pad;
@@ -59,7 +62,8 @@
 
 void assign_and_preserve_padding_1(device tint_array<tint_packed_vec3_u32_array_element, 4>* const dest, tint_array<uint3, 4> value) {
   for(uint i = 0u; (i < 4u); i = (i + 1u)) {
-    (*(dest))[i].elements = packed_uint3(value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(dest))[min(i, 3u)].elements = packed_uint3(value[min(i, 3u)]);
   }
 }
 
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/379127084.wgsl.expected.dxc.hlsl
index a8d1a1b..8b481de 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.dxc.hlsl
@@ -13,7 +13,6 @@
 cbuffer cbuffer__uniform0 : register(b0) {
   uint4 _uniform0[2];
 };
-
 ByteAddressBuffer _storage1 : register(t2);
 static uint shadingSsboIndex = 0u;
 SamplerState permutationsSampler_1_Sampler : register(s0, space1);
@@ -27,22 +26,31 @@
 
 void _skslMain(FSIn _stageIn, inout FSOut _stageOut) {
   {
+    uint tint_symbol_6 = 0u;
+    _storage1.GetDimensions(tint_symbol_6);
+    uint tint_symbol_7 = ((tint_symbol_6 - 0u) / 128u);
     shadingSsboIndex = _stageIn.ssboIndicesVar.y;
-    int _56_d = asint(_storage1.Load(((128u * shadingSsboIndex) + 16u)));
-    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((128u * shadingSsboIndex)))));
+    int _56_d = asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 16u)));
+    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u)))))));
     float4 _58_l = (0.0f).xxxx;
-    float2 _59_m = float2(asfloat(_storage1.Load2(((128u * shadingSsboIndex) + 8u))));
+    float2 _59_m = float2(asfloat(_storage1.Load2(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 8u))));
     float _60_n = 1.0f;
     {
       int _61_o = 0;
       while (true) {
-        if ((_61_o < asint(_storage1.Load(((128u * shadingSsboIndex) + 20u))))) {
+        uint tint_symbol_8 = 0u;
+        _storage1.GetDimensions(tint_symbol_8);
+        uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 128u);
+        if ((_61_o < asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_9 - 1u))) + 20u))))) {
           {
+            uint tint_symbol_10 = 0u;
+            _storage1.GetDimensions(tint_symbol_10);
+            uint tint_symbol_11 = ((tint_symbol_10 - 0u) / 128u);
             float4 _62_f = float4(0.0f, 0.0f, 0.0f, 0.0f);
             float2 _skTemp2 = floor(_57_k);
             _62_f = float4(_skTemp2, _62_f.zw);
             _62_f = float4(_62_f.xy, (_62_f.xy + (1.0f).xx));
-            if (bool(asint(_storage1.Load(((128u * shadingSsboIndex) + 24u))))) {
+            if (bool(asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_11 - 1u))) + 24u))))) {
               float4 _skTemp3 = step(_59_m.xyxy, _62_f);
               _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
             }
@@ -89,7 +97,7 @@
                   float _skTemp12 = lerp(_79_o, _80_p, _69_e.x);
                   float _82_r = _skTemp12;
                   float _skTemp13 = lerp(_81_q, _82_r, _69_e.y);
-                  set_vector_element(_71_g, _72_h, _skTemp13);
+                  set_vector_element(_71_g, min(uint(_72_h), 3u), _skTemp13);
                 }
                 {
                   _72_h = (_72_h + 1);
@@ -123,7 +131,7 @@
     float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(float3((float3(_58_l.xyz) * float(_58_l.w))), float(float(_58_l.w))).xyz);
     float _skTemp17 = saturate(_skTemp16);
     float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-    int _85_d = asint(_storage1.Load(((128u * shadingSsboIndex) + 112u)));
+    int _85_d = asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 112u)));
     if (bool(_85_d)) {
       {
         float4 _skTemp18 = float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -157,7 +165,7 @@
         _84_a = float4((_84_a.xyz / _skTemp23), _84_a.w);
       }
     }
-    float4 _94_f = float4((mul(float4(_84_a), _storage1_load_2(((128u * shadingSsboIndex) + 32u))) + asfloat(_storage1.Load4(((128u * shadingSsboIndex) + 96u)))));
+    float4 _94_f = float4((mul(float4(_84_a), _storage1_load_2(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 32u))) + asfloat(_storage1.Load4(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 96u)))));
     if (bool(_85_d)) {
       {
         float _skTemp24 = abs(((2.0f * _94_f.z) - 1.0f));
@@ -172,7 +180,10 @@
       }
     } else {
       {
-        if (bool(asint(_storage1.Load(((128u * shadingSsboIndex) + 116u))))) {
+        uint tint_symbol_12 = 0u;
+        _storage1.GetDimensions(tint_symbol_12);
+        uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 128u);
+        if (bool(asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_13 - 1u))) + 116u))))) {
           float4 _skTemp29 = saturate(_94_f);
           _94_f = _skTemp29;
         } else {
@@ -202,8 +213,8 @@
 }
 
 tint_symbol_4 main(tint_symbol_3 tint_symbol_2) {
-  FSIn tint_symbol_5 = {tint_symbol_2.ssboIndicesVar, tint_symbol_2.localCoordsVar};
-  FSOut inner_result = main_inner(tint_symbol_5);
+  FSIn tint_symbol_14 = {tint_symbol_2.ssboIndicesVar, tint_symbol_2.localCoordsVar};
+  FSOut inner_result = main_inner(tint_symbol_14);
   tint_symbol_4 wrapper_result = (tint_symbol_4)0;
   wrapper_result.sk_FragColor = inner_result.sk_FragColor;
   return wrapper_result;
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/379127084.wgsl.expected.fxc.hlsl
index a8d1a1b..8b481de 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.fxc.hlsl
@@ -13,7 +13,6 @@
 cbuffer cbuffer__uniform0 : register(b0) {
   uint4 _uniform0[2];
 };
-
 ByteAddressBuffer _storage1 : register(t2);
 static uint shadingSsboIndex = 0u;
 SamplerState permutationsSampler_1_Sampler : register(s0, space1);
@@ -27,22 +26,31 @@
 
 void _skslMain(FSIn _stageIn, inout FSOut _stageOut) {
   {
+    uint tint_symbol_6 = 0u;
+    _storage1.GetDimensions(tint_symbol_6);
+    uint tint_symbol_7 = ((tint_symbol_6 - 0u) / 128u);
     shadingSsboIndex = _stageIn.ssboIndicesVar.y;
-    int _56_d = asint(_storage1.Load(((128u * shadingSsboIndex) + 16u)));
-    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((128u * shadingSsboIndex)))));
+    int _56_d = asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 16u)));
+    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u)))))));
     float4 _58_l = (0.0f).xxxx;
-    float2 _59_m = float2(asfloat(_storage1.Load2(((128u * shadingSsboIndex) + 8u))));
+    float2 _59_m = float2(asfloat(_storage1.Load2(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 8u))));
     float _60_n = 1.0f;
     {
       int _61_o = 0;
       while (true) {
-        if ((_61_o < asint(_storage1.Load(((128u * shadingSsboIndex) + 20u))))) {
+        uint tint_symbol_8 = 0u;
+        _storage1.GetDimensions(tint_symbol_8);
+        uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 128u);
+        if ((_61_o < asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_9 - 1u))) + 20u))))) {
           {
+            uint tint_symbol_10 = 0u;
+            _storage1.GetDimensions(tint_symbol_10);
+            uint tint_symbol_11 = ((tint_symbol_10 - 0u) / 128u);
             float4 _62_f = float4(0.0f, 0.0f, 0.0f, 0.0f);
             float2 _skTemp2 = floor(_57_k);
             _62_f = float4(_skTemp2, _62_f.zw);
             _62_f = float4(_62_f.xy, (_62_f.xy + (1.0f).xx));
-            if (bool(asint(_storage1.Load(((128u * shadingSsboIndex) + 24u))))) {
+            if (bool(asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_11 - 1u))) + 24u))))) {
               float4 _skTemp3 = step(_59_m.xyxy, _62_f);
               _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
             }
@@ -89,7 +97,7 @@
                   float _skTemp12 = lerp(_79_o, _80_p, _69_e.x);
                   float _82_r = _skTemp12;
                   float _skTemp13 = lerp(_81_q, _82_r, _69_e.y);
-                  set_vector_element(_71_g, _72_h, _skTemp13);
+                  set_vector_element(_71_g, min(uint(_72_h), 3u), _skTemp13);
                 }
                 {
                   _72_h = (_72_h + 1);
@@ -123,7 +131,7 @@
     float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(float3((float3(_58_l.xyz) * float(_58_l.w))), float(float(_58_l.w))).xyz);
     float _skTemp17 = saturate(_skTemp16);
     float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-    int _85_d = asint(_storage1.Load(((128u * shadingSsboIndex) + 112u)));
+    int _85_d = asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 112u)));
     if (bool(_85_d)) {
       {
         float4 _skTemp18 = float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -157,7 +165,7 @@
         _84_a = float4((_84_a.xyz / _skTemp23), _84_a.w);
       }
     }
-    float4 _94_f = float4((mul(float4(_84_a), _storage1_load_2(((128u * shadingSsboIndex) + 32u))) + asfloat(_storage1.Load4(((128u * shadingSsboIndex) + 96u)))));
+    float4 _94_f = float4((mul(float4(_84_a), _storage1_load_2(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 32u))) + asfloat(_storage1.Load4(((128u * min(shadingSsboIndex, (tint_symbol_7 - 1u))) + 96u)))));
     if (bool(_85_d)) {
       {
         float _skTemp24 = abs(((2.0f * _94_f.z) - 1.0f));
@@ -172,7 +180,10 @@
       }
     } else {
       {
-        if (bool(asint(_storage1.Load(((128u * shadingSsboIndex) + 116u))))) {
+        uint tint_symbol_12 = 0u;
+        _storage1.GetDimensions(tint_symbol_12);
+        uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 128u);
+        if (bool(asint(_storage1.Load(((128u * min(shadingSsboIndex, (tint_symbol_13 - 1u))) + 116u))))) {
           float4 _skTemp29 = saturate(_94_f);
           _94_f = _skTemp29;
         } else {
@@ -202,8 +213,8 @@
 }
 
 tint_symbol_4 main(tint_symbol_3 tint_symbol_2) {
-  FSIn tint_symbol_5 = {tint_symbol_2.ssboIndicesVar, tint_symbol_2.localCoordsVar};
-  FSOut inner_result = main_inner(tint_symbol_5);
+  FSIn tint_symbol_14 = {tint_symbol_2.ssboIndicesVar, tint_symbol_2.localCoordsVar};
+  FSOut inner_result = main_inner(tint_symbol_14);
   tint_symbol_4 wrapper_result = (tint_symbol_4)0;
   wrapper_result.sk_FragColor = inner_result.sk_FragColor;
   return wrapper_result;
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.glsl b/test/tint/bug/tint/379127084.wgsl.expected.glsl
index 5edc0b3..18f1c17 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.glsl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.glsl
@@ -40,25 +40,30 @@
 void _skslMain(FSIn _stageIn, inout FSOut _stageOut) {
   shadingSsboIndex = _stageIn.ssboIndicesVar[1u];
   uint v = shadingSsboIndex;
-  int _56_d = _storage1.fsUniformData[v].noiseType_1;
-  uint v_1 = shadingSsboIndex;
-  vec2 _57_k = vec2(((_stageIn.localCoordsVar + 0.5f) * _storage1.fsUniformData[v_1].baseFrequency_1));
-  vec4 _58_l = vec4(0.0f);
+  uint v_1 = min(v, (uint(_storage1.fsUniformData.length()) - 1u));
+  int _56_d = _storage1.fsUniformData[v_1].noiseType_1;
   uint v_2 = shadingSsboIndex;
-  vec2 _59_m = vec2(_storage1.fsUniformData[v_2].stitchData_1);
+  uint v_3 = min(v_2, (uint(_storage1.fsUniformData.length()) - 1u));
+  vec2 _57_k = vec2(((_stageIn.localCoordsVar + 0.5f) * _storage1.fsUniformData[v_3].baseFrequency_1));
+  vec4 _58_l = vec4(0.0f);
+  uint v_4 = shadingSsboIndex;
+  uint v_5 = min(v_4, (uint(_storage1.fsUniformData.length()) - 1u));
+  vec2 _59_m = vec2(_storage1.fsUniformData[v_5].stitchData_1);
   float _60_n = 1.0f;
   int _61_o = 0;
   {
     while(true) {
-      int v_3 = _61_o;
-      uint v_4 = shadingSsboIndex;
-      if ((v_3 < _storage1.fsUniformData[v_4].numOctaves_1)) {
+      int v_6 = _61_o;
+      uint v_7 = shadingSsboIndex;
+      uint v_8 = min(v_7, (uint(_storage1.fsUniformData.length()) - 1u));
+      if ((v_6 < _storage1.fsUniformData[v_8].numOctaves_1)) {
         vec4 _62_f = vec4(0.0f);
         vec2 _skTemp2 = floor(_57_k);
         _62_f = vec4(_skTemp2, _62_f.zw);
         _62_f = vec4(_62_f.xy, (_62_f.xy + vec2(1.0f)));
-        uint v_5 = shadingSsboIndex;
-        if (bool(_storage1.fsUniformData[v_5].stitching_1)) {
+        uint v_9 = shadingSsboIndex;
+        uint v_10 = min(v_9, (uint(_storage1.fsUniformData.length()) - 1u));
+        if (bool(_storage1.fsUniformData[v_10].stitching_1)) {
           vec4 _skTemp3 = step(_59_m.xyxy, _62_f);
           _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
         }
@@ -81,14 +86,14 @@
         {
           while(true) {
             float _73_i = ((float(_72_h) + 0.5f) * 0.25f);
-            float v_6 = float(_67_p[0u]);
-            vec4 _74_j = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_6, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_7 = float(_67_p[1u]);
-            vec4 _75_k = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_7, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_8 = float(_67_p[3u]);
-            vec4 _76_l = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_8, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_9 = float(_67_p[2u]);
-            vec4 _77_m = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_9, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_11 = float(_67_p[0u]);
+            vec4 _74_j = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_11, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_12 = float(_67_p[1u]);
+            vec4 _75_k = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_12, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_13 = float(_67_p[3u]);
+            vec4 _76_l = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_13, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_14 = float(_67_p[2u]);
+            vec4 _77_m = texture(noiseSampler_1_Texture_noiseSampler_1_Sampler, vec2(v_14, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
             vec2 _78_n = _68_d;
             float _skTemp7 = dot((((_74_j.yw + (_74_j.xz * 0.00390625f)) * 2.0f) - 1.0f), _78_n);
             float _79_o = _skTemp7;
@@ -106,7 +111,7 @@
             float _skTemp12 = mix(_79_o, _80_p, _69_e[0u]);
             float _82_r = _skTemp12;
             float _skTemp13 = mix(_81_q, _82_r, _69_e[1u]);
-            _71_g[_72_h] = _skTemp13;
+            _71_g[min(uint(_72_h), 3u)] = _skTemp13;
             {
               _72_h = (_72_h + 1);
               if ((_72_h >= 4)) { break; }
@@ -137,13 +142,14 @@
   }
   vec4 _skTemp15 = clamp(_58_l, vec4(0.0f), vec4(1.0f));
   _58_l = _skTemp15;
-  vec3 v_10 = vec3(_58_l.xyz);
-  vec3 v_11 = vec3((v_10 * float(_58_l.w)));
-  float _skTemp16 = dot(vec3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), vec4(v_11, float(float(_58_l.w))).xyz);
+  vec3 v_15 = vec3(_58_l.xyz);
+  vec3 v_16 = vec3((v_15 * float(_58_l.w)));
+  float _skTemp16 = dot(vec3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), vec4(v_16, float(float(_58_l.w))).xyz);
   float _skTemp17 = clamp(_skTemp16, 0.0f, 1.0f);
   vec4 _84_a = vec4(0.0f, 0.0f, 0.0f, _skTemp17);
-  uint v_12 = shadingSsboIndex;
-  int _85_d = _storage1.fsUniformData[v_12].inHSL_4;
+  uint v_17 = shadingSsboIndex;
+  uint v_18 = min(v_17, (uint(_storage1.fsUniformData.length()) - 1u));
+  int _85_d = _storage1.fsUniformData[v_18].inHSL_4;
   if (bool(_85_d)) {
     vec4 _skTemp18 = vec4(0.0f);
     if ((_84_a.y < _84_a.z)) {
@@ -173,11 +179,13 @@
     float _skTemp23 = max(_84_a.w, 0.00009999999747378752f);
     _84_a = vec4((_84_a.xyz / _skTemp23), _84_a.w);
   }
-  uint v_13 = shadingSsboIndex;
-  mat4 v_14 = _storage1.fsUniformData[v_13].matrix_4;
-  vec4 v_15 = (v_14 * vec4(_84_a));
-  uint v_16 = shadingSsboIndex;
-  vec4 _94_f = vec4((v_15 + _storage1.fsUniformData[v_16].translate_4));
+  uint v_19 = shadingSsboIndex;
+  uint v_20 = min(v_19, (uint(_storage1.fsUniformData.length()) - 1u));
+  mat4 v_21 = _storage1.fsUniformData[v_20].matrix_4;
+  vec4 v_22 = (v_21 * vec4(_84_a));
+  uint v_23 = shadingSsboIndex;
+  uint v_24 = min(v_23, (uint(_storage1.fsUniformData.length()) - 1u));
+  vec4 _94_f = vec4((v_22 + _storage1.fsUniformData[v_24].translate_4));
   if (bool(_85_d)) {
     float _skTemp24 = abs(((2.0f * _94_f.z) - 1.0f));
     float _95_b = ((1.0f - _skTemp24) * _94_f.y);
@@ -189,8 +197,9 @@
     vec4 _skTemp28 = clamp(vec4(((((_97_d - 0.5f) * _95_b) + _94_f.z) * _94_f.w), _94_f.w), vec4(0.0f), vec4(1.0f));
     _94_f = _skTemp28;
   } else {
-    uint v_17 = shadingSsboIndex;
-    if (bool(_storage1.fsUniformData[v_17].clampRGB_4)) {
+    uint v_25 = shadingSsboIndex;
+    uint v_26 = min(v_25, (uint(_storage1.fsUniformData.length()) - 1u));
+    if (bool(_storage1.fsUniformData[v_26].clampRGB_4)) {
       vec4 _skTemp29 = clamp(_94_f, vec4(0.0f), vec4(1.0f));
       _94_f = _skTemp29;
     } else {
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/379127084.wgsl.expected.ir.dxc.hlsl
index df6121e..f0f1970 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.ir.dxc.hlsl
@@ -32,20 +32,30 @@
 
 void _skslMain(FSIn _stageIn, inout FSOut _stageOut) {
   shadingSsboIndex = _stageIn.ssboIndicesVar.y;
-  int _56_d = asint(_storage1.Load((16u + (shadingSsboIndex * 128u))));
-  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((0u + (shadingSsboIndex * 128u))))));
+  uint v_1 = 0u;
+  _storage1.GetDimensions(v_1);
+  int _56_d = asint(_storage1.Load((16u + (min(shadingSsboIndex, ((v_1 / 128u) - 1u)) * 128u))));
+  uint v_2 = 0u;
+  _storage1.GetDimensions(v_2);
+  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((0u + (min(shadingSsboIndex, ((v_2 / 128u) - 1u)) * 128u))))));
   float4 _58_l = (0.0f).xxxx;
-  float2 _59_m = float2(asfloat(_storage1.Load2((8u + (shadingSsboIndex * 128u)))));
+  uint v_3 = 0u;
+  _storage1.GetDimensions(v_3);
+  float2 _59_m = float2(asfloat(_storage1.Load2((8u + (min(shadingSsboIndex, ((v_3 / 128u) - 1u)) * 128u)))));
   float _60_n = 1.0f;
   int _61_o = int(0);
   {
     while(true) {
-      if ((_61_o < asint(_storage1.Load((20u + (shadingSsboIndex * 128u)))))) {
+      uint v_4 = 0u;
+      _storage1.GetDimensions(v_4);
+      if ((_61_o < asint(_storage1.Load((20u + (min(shadingSsboIndex, ((v_4 / 128u) - 1u)) * 128u)))))) {
         float4 _62_f = (0.0f).xxxx;
         float2 _skTemp2 = floor(_57_k);
         _62_f = float4(_skTemp2, _62_f.zw);
         _62_f = float4(_62_f.xy, (_62_f.xy + (1.0f).xx));
-        if (bool(asint(_storage1.Load((24u + (shadingSsboIndex * 128u)))))) {
+        uint v_5 = 0u;
+        _storage1.GetDimensions(v_5);
+        if (bool(asint(_storage1.Load((24u + (min(shadingSsboIndex, ((v_5 / 128u) - 1u)) * 128u)))))) {
           float4 _skTemp3 = step(_59_m.xyxy, _62_f);
           _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
         }
@@ -68,14 +78,14 @@
         {
           while(true) {
             float _73_i = ((float(_72_h) + 0.5f) * 0.25f);
-            float v_1 = float(_67_p.x);
-            float4 _74_j = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_1, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_2 = float(_67_p.y);
-            float4 _75_k = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_2, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_3 = float(_67_p.w);
-            float4 _76_l = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_3, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_4 = float(_67_p.z);
-            float4 _77_m = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_4, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_6 = float(_67_p.x);
+            float4 _74_j = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_6, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_7 = float(_67_p.y);
+            float4 _75_k = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_7, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_8 = float(_67_p.w);
+            float4 _76_l = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_8, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_9 = float(_67_p.z);
+            float4 _77_m = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_9, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
             float2 _78_n = _68_d;
             float _skTemp7 = dot((((_74_j.yw + (_74_j.xz * 0.00390625f)) * 2.0f) - 1.0f), _78_n);
             float _79_o = _skTemp7;
@@ -93,7 +103,7 @@
             float _skTemp12 = lerp(_79_o, _80_p, _69_e.x);
             float _82_r = _skTemp12;
             float _skTemp13 = lerp(_81_q, _82_r, _69_e.y);
-            _71_g[_72_h] = _skTemp13;
+            _71_g[min(uint(_72_h), 3u)] = _skTemp13;
             {
               _72_h = (_72_h + int(1));
               if ((_72_h >= int(4))) { break; }
@@ -124,12 +134,14 @@
   }
   float4 _skTemp15 = saturate(_58_l);
   _58_l = _skTemp15;
-  float3 v_5 = float3(_58_l.xyz);
-  float3 v_6 = float3((v_5 * float(_58_l.w)));
-  float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(v_6, float(float(_58_l.w))).xyz);
+  float3 v_10 = float3(_58_l.xyz);
+  float3 v_11 = float3((v_10 * float(_58_l.w)));
+  float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(v_11, float(float(_58_l.w))).xyz);
   float _skTemp17 = saturate(_skTemp16);
   float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-  int _85_d = asint(_storage1.Load((112u + (shadingSsboIndex * 128u))));
+  uint v_12 = 0u;
+  _storage1.GetDimensions(v_12);
+  int _85_d = asint(_storage1.Load((112u + (min(shadingSsboIndex, ((v_12 / 128u) - 1u)) * 128u))));
   if (bool(_85_d)) {
     float4 _skTemp18 = (0.0f).xxxx;
     if ((_84_a.y < _84_a.z)) {
@@ -159,9 +171,13 @@
     float _skTemp23 = max(_84_a.w, 0.00009999999747378752f);
     _84_a = float4((_84_a.xyz / _skTemp23), _84_a.w);
   }
-  float4x4 v_7 = v((32u + (shadingSsboIndex * 128u)));
-  float4 v_8 = mul(float4(_84_a), v_7);
-  float4 _94_f = float4((v_8 + asfloat(_storage1.Load4((96u + (shadingSsboIndex * 128u))))));
+  uint v_13 = 0u;
+  _storage1.GetDimensions(v_13);
+  float4x4 v_14 = v((32u + (min(shadingSsboIndex, ((v_13 / 128u) - 1u)) * 128u)));
+  float4 v_15 = mul(float4(_84_a), v_14);
+  uint v_16 = 0u;
+  _storage1.GetDimensions(v_16);
+  float4 _94_f = float4((v_15 + asfloat(_storage1.Load4((96u + (min(shadingSsboIndex, ((v_16 / 128u) - 1u)) * 128u))))));
   if (bool(_85_d)) {
     float _skTemp24 = abs(((2.0f * _94_f.z) - 1.0f));
     float _95_b = ((1.0f - _skTemp24) * _94_f.y);
@@ -173,7 +189,9 @@
     float4 _skTemp28 = saturate(float4(((((_97_d - 0.5f) * _95_b) + _94_f.z) * _94_f.w), _94_f.w));
     _94_f = _skTemp28;
   } else {
-    if (bool(asint(_storage1.Load((116u + (shadingSsboIndex * 128u)))))) {
+    uint v_17 = 0u;
+    _storage1.GetDimensions(v_17);
+    if (bool(asint(_storage1.Load((116u + (min(shadingSsboIndex, ((v_17 / 128u) - 1u)) * 128u)))))) {
       float4 _skTemp29 = saturate(_94_f);
       _94_f = _skTemp29;
     } else {
@@ -189,14 +207,14 @@
 FSOut main_inner(FSIn _stageIn) {
   FSOut _stageOut = (FSOut)0;
   _skslMain(_stageIn, _stageOut);
-  FSOut v_9 = _stageOut;
-  return v_9;
+  FSOut v_18 = _stageOut;
+  return v_18;
 }
 
 main_outputs main(main_inputs inputs) {
-  FSIn v_10 = {inputs.FSIn_ssboIndicesVar, inputs.FSIn_localCoordsVar};
-  FSOut v_11 = main_inner(v_10);
-  main_outputs v_12 = {v_11.sk_FragColor};
-  return v_12;
+  FSIn v_19 = {inputs.FSIn_ssboIndicesVar, inputs.FSIn_localCoordsVar};
+  FSOut v_20 = main_inner(v_19);
+  main_outputs v_21 = {v_20.sk_FragColor};
+  return v_21;
 }
 
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/379127084.wgsl.expected.ir.fxc.hlsl
index 4453347..f4209da 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.ir.fxc.hlsl
@@ -32,20 +32,30 @@
 
 void _skslMain(FSIn _stageIn, inout FSOut _stageOut) {
   shadingSsboIndex = _stageIn.ssboIndicesVar.y;
-  int _56_d = asint(_storage1.Load((16u + (shadingSsboIndex * 128u))));
-  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((0u + (shadingSsboIndex * 128u))))));
+  uint v_1 = 0u;
+  _storage1.GetDimensions(v_1);
+  int _56_d = asint(_storage1.Load((16u + (min(shadingSsboIndex, ((v_1 / 128u) - 1u)) * 128u))));
+  uint v_2 = 0u;
+  _storage1.GetDimensions(v_2);
+  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * asfloat(_storage1.Load2((0u + (min(shadingSsboIndex, ((v_2 / 128u) - 1u)) * 128u))))));
   float4 _58_l = (0.0f).xxxx;
-  float2 _59_m = float2(asfloat(_storage1.Load2((8u + (shadingSsboIndex * 128u)))));
+  uint v_3 = 0u;
+  _storage1.GetDimensions(v_3);
+  float2 _59_m = float2(asfloat(_storage1.Load2((8u + (min(shadingSsboIndex, ((v_3 / 128u) - 1u)) * 128u)))));
   float _60_n = 1.0f;
   int _61_o = int(0);
   {
     while(true) {
-      if ((_61_o < asint(_storage1.Load((20u + (shadingSsboIndex * 128u)))))) {
+      uint v_4 = 0u;
+      _storage1.GetDimensions(v_4);
+      if ((_61_o < asint(_storage1.Load((20u + (min(shadingSsboIndex, ((v_4 / 128u) - 1u)) * 128u)))))) {
         float4 _62_f = (0.0f).xxxx;
         float2 _skTemp2 = floor(_57_k);
         _62_f = float4(_skTemp2, _62_f.zw);
         _62_f = float4(_62_f.xy, (_62_f.xy + (1.0f).xx));
-        if (bool(asint(_storage1.Load((24u + (shadingSsboIndex * 128u)))))) {
+        uint v_5 = 0u;
+        _storage1.GetDimensions(v_5);
+        if (bool(asint(_storage1.Load((24u + (min(shadingSsboIndex, ((v_5 / 128u) - 1u)) * 128u)))))) {
           float4 _skTemp3 = step(_59_m.xyxy, _62_f);
           _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
         }
@@ -68,14 +78,14 @@
         {
           while(true) {
             float _73_i = ((float(_72_h) + 0.5f) * 0.25f);
-            float v_1 = float(_67_p.x);
-            float4 _74_j = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_1, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_2 = float(_67_p.y);
-            float4 _75_k = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_2, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_3 = float(_67_p.w);
-            float4 _76_l = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_3, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
-            float v_4 = float(_67_p.z);
-            float4 _77_m = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_4, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_6 = float(_67_p.x);
+            float4 _74_j = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_6, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_7 = float(_67_p.y);
+            float4 _75_k = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_7, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_8 = float(_67_p.w);
+            float4 _76_l = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_8, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
+            float v_9 = float(_67_p.z);
+            float4 _77_m = noiseSampler_1_Texture.SampleBias(noiseSampler_1_Sampler, float2(v_9, float(_73_i)), clamp(-0.47499999403953552246f, -16.0f, 15.9899997711181640625f));
             float2 _78_n = _68_d;
             float _skTemp7 = dot((((_74_j.yw + (_74_j.xz * 0.00390625f)) * 2.0f) - 1.0f), _78_n);
             float _79_o = _skTemp7;
@@ -93,9 +103,9 @@
             float _skTemp12 = lerp(_79_o, _80_p, _69_e.x);
             float _82_r = _skTemp12;
             float _skTemp13 = lerp(_81_q, _82_r, _69_e.y);
-            float4 v_5 = _71_g;
-            float4 v_6 = _72_h.xxxx;
-            _71_g = (((v_6 == float4(int(0), int(1), int(2), int(3)))) ? (_skTemp13.xxxx) : (v_5));
+            float4 v_10 = _71_g;
+            float4 v_11 = _72_h.xxxx;
+            _71_g = (((v_11 == float4(int(0), int(1), int(2), int(3)))) ? (_skTemp13.xxxx) : (v_10));
             {
               _72_h = (_72_h + int(1));
               if ((_72_h >= int(4))) { break; }
@@ -126,12 +136,14 @@
   }
   float4 _skTemp15 = saturate(_58_l);
   _58_l = _skTemp15;
-  float3 v_7 = float3(_58_l.xyz);
-  float3 v_8 = float3((v_7 * float(_58_l.w)));
-  float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(v_8, float(float(_58_l.w))).xyz);
+  float3 v_12 = float3(_58_l.xyz);
+  float3 v_13 = float3((v_12 * float(_58_l.w)));
+  float _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(v_13, float(float(_58_l.w))).xyz);
   float _skTemp17 = saturate(_skTemp16);
   float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-  int _85_d = asint(_storage1.Load((112u + (shadingSsboIndex * 128u))));
+  uint v_14 = 0u;
+  _storage1.GetDimensions(v_14);
+  int _85_d = asint(_storage1.Load((112u + (min(shadingSsboIndex, ((v_14 / 128u) - 1u)) * 128u))));
   if (bool(_85_d)) {
     float4 _skTemp18 = (0.0f).xxxx;
     if ((_84_a.y < _84_a.z)) {
@@ -161,9 +173,13 @@
     float _skTemp23 = max(_84_a.w, 0.00009999999747378752f);
     _84_a = float4((_84_a.xyz / _skTemp23), _84_a.w);
   }
-  float4x4 v_9 = v((32u + (shadingSsboIndex * 128u)));
-  float4 v_10 = mul(float4(_84_a), v_9);
-  float4 _94_f = float4((v_10 + asfloat(_storage1.Load4((96u + (shadingSsboIndex * 128u))))));
+  uint v_15 = 0u;
+  _storage1.GetDimensions(v_15);
+  float4x4 v_16 = v((32u + (min(shadingSsboIndex, ((v_15 / 128u) - 1u)) * 128u)));
+  float4 v_17 = mul(float4(_84_a), v_16);
+  uint v_18 = 0u;
+  _storage1.GetDimensions(v_18);
+  float4 _94_f = float4((v_17 + asfloat(_storage1.Load4((96u + (min(shadingSsboIndex, ((v_18 / 128u) - 1u)) * 128u))))));
   if (bool(_85_d)) {
     float _skTemp24 = abs(((2.0f * _94_f.z) - 1.0f));
     float _95_b = ((1.0f - _skTemp24) * _94_f.y);
@@ -175,7 +191,9 @@
     float4 _skTemp28 = saturate(float4(((((_97_d - 0.5f) * _95_b) + _94_f.z) * _94_f.w), _94_f.w));
     _94_f = _skTemp28;
   } else {
-    if (bool(asint(_storage1.Load((116u + (shadingSsboIndex * 128u)))))) {
+    uint v_19 = 0u;
+    _storage1.GetDimensions(v_19);
+    if (bool(asint(_storage1.Load((116u + (min(shadingSsboIndex, ((v_19 / 128u) - 1u)) * 128u)))))) {
       float4 _skTemp29 = saturate(_94_f);
       _94_f = _skTemp29;
     } else {
@@ -191,14 +209,14 @@
 FSOut main_inner(FSIn _stageIn) {
   FSOut _stageOut = (FSOut)0;
   _skslMain(_stageIn, _stageOut);
-  FSOut v_11 = _stageOut;
-  return v_11;
+  FSOut v_20 = _stageOut;
+  return v_20;
 }
 
 main_outputs main(main_inputs inputs) {
-  FSIn v_12 = {inputs.FSIn_ssboIndicesVar, inputs.FSIn_localCoordsVar};
-  FSOut v_13 = main_inner(v_12);
-  main_outputs v_14 = {v_13.sk_FragColor};
-  return v_14;
+  FSIn v_21 = {inputs.FSIn_ssboIndicesVar, inputs.FSIn_localCoordsVar};
+  FSOut v_22 = main_inner(v_21);
+  main_outputs v_23 = {v_22.sk_FragColor};
+  return v_23;
 }
 
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.ir.msl b/test/tint/bug/tint/379127084.wgsl.expected.ir.msl
index 6d4ad17..d51431e 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.ir.msl
@@ -53,8 +53,12 @@
   texture2d<float, access::sample> permutationsSampler_1_Texture;
   sampler noiseSampler_1_Sampler;
   texture2d<float, access::sample> noiseSampler_1_Texture;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_outputs {
   float4 FSOut_sk_FragColor [[color(0)]];
 };
@@ -66,20 +70,21 @@
 
 void _skslMain(FSIn _stageIn, thread FSOut* const _stageOut, tint_module_vars_struct tint_module_vars) {
   (*tint_module_vars.shadingSsboIndex) = _stageIn.ssboIndicesVar[1u];
-  int const _56_d = (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].noiseType_1;
-  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].baseFrequency_1));
+  int const _56_d = (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].noiseType_1;
+  float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].baseFrequency_1));
   float4 _58_l = float4(0.0f);
-  float2 _59_m = float2((*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].stitchData_1);
+  float2 _59_m = float2((*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].stitchData_1);
   float _60_n = 1.0f;
   int _61_o = 0;
   {
     while(true) {
-      if ((_61_o < (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].numOctaves_1)) {
+      TINT_ISOLATE_UB(tint_volatile_false)
+      if ((_61_o < (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].numOctaves_1)) {
         float4 _62_f = 0.0f;
         float2 const _skTemp2 = floor(_57_k);
         _62_f = float4(_skTemp2, _62_f.zw);
         _62_f = float4(_62_f.xy, (_62_f.xy + float2(1.0f)));
-        if (bool((*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].stitching_1)) {
+        if (bool((*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].stitching_1)) {
           float4 const _skTemp3 = step(_59_m.xyxy, _62_f);
           _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
         }
@@ -103,6 +108,7 @@
         int _72_h = 0;
         {
           while(true) {
+            TINT_ISOLATE_UB(tint_volatile_false_1)
             float const _73_i = ((float(_72_h) + 0.5f) * 0.25f);
             float const v_2 = float(_67_p[0u]);
             float2 const v_3 = float2(v_2, float(_73_i));
@@ -133,7 +139,7 @@
             float const _skTemp12 = mix(_79_o, _80_p, _69_e[0u]);
             float const _82_r = _skTemp12;
             float const _skTemp13 = mix(_81_q, _82_r, _69_e[1u]);
-            _71_g[_72_h] = _skTemp13;
+            _71_g[min(uint(_72_h), 3u)] = _skTemp13;
             {
               _72_h = as_type<int>((as_type<uint>(_72_h) + as_type<uint>(1)));
               if ((_72_h >= 4)) { break; }
@@ -169,7 +175,7 @@
   float const _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(v_11, float(float(_58_l[3u]))).xyz);
   float const _skTemp17 = saturate(_skTemp16);
   float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-  int const _85_d = (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].inHSL_4;
+  int const _85_d = (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].inHSL_4;
   if (bool(_85_d)) {
     float4 _skTemp18 = 0.0f;
     if ((_84_a[1u] < _84_a[2u])) {
@@ -199,9 +205,9 @@
     float const _skTemp23 = max(_84_a[3u], 0.00009999999747378752f);
     _84_a = float4((_84_a.xyz / _skTemp23), _84_a[3u]);
   }
-  float4x4 const v_12 = (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].matrix_4;
+  float4x4 const v_12 = (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].matrix_4;
   float4 const v_13 = (v_12 * float4(_84_a));
-  float4 _94_f = float4((v_13 + (*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].translate_4));
+  float4 _94_f = float4((v_13 + (*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].translate_4));
   if (bool(_85_d)) {
     float const _skTemp24 = abs(((2.0f * _94_f[2u]) - 1.0f));
     float const _95_b = ((1.0f - _skTemp24) * _94_f[1u]);
@@ -213,7 +219,7 @@
     float4 const _skTemp28 = saturate(float4(((((_97_d - 0.5f) * _95_b) + _94_f[2u]) * _94_f[3u]), _94_f[3u]));
     _94_f = _skTemp28;
   } else {
-    if (bool((*tint_module_vars._storage1).fsUniformData[(*tint_module_vars.shadingSsboIndex)].clampRGB_4)) {
+    if (bool((*tint_module_vars._storage1).fsUniformData[min((*tint_module_vars.shadingSsboIndex), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].clampRGB_4)) {
       float4 const _skTemp29 = saturate(_94_f);
       _94_f = _skTemp29;
     } else {
@@ -232,9 +238,9 @@
   return _stageOut;
 }
 
-fragment tint_symbol_outputs tint_symbol(tint_symbol_inputs inputs [[stage_in]], const device FSUniforms* _storage1 [[buffer(0)]], sampler permutationsSampler_1_Sampler [[sampler(0)]], texture2d<float, access::sample> permutationsSampler_1_Texture [[texture(0)]], sampler noiseSampler_1_Sampler [[sampler(1)]], texture2d<float, access::sample> noiseSampler_1_Texture [[texture(1)]]) {
+fragment tint_symbol_outputs tint_symbol(tint_symbol_inputs inputs [[stage_in]], const device FSUniforms* _storage1 [[buffer(0)]], sampler permutationsSampler_1_Sampler [[sampler(0)]], texture2d<float, access::sample> permutationsSampler_1_Texture [[texture(0)]], sampler noiseSampler_1_Sampler [[sampler(1)]], texture2d<float, access::sample> noiseSampler_1_Texture [[texture(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread uint shadingSsboIndex = 0u;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{._storage1=_storage1, .shadingSsboIndex=(&shadingSsboIndex), .permutationsSampler_1_Sampler=permutationsSampler_1_Sampler, .permutationsSampler_1_Texture=permutationsSampler_1_Texture, .noiseSampler_1_Sampler=noiseSampler_1_Sampler, .noiseSampler_1_Texture=noiseSampler_1_Texture};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{._storage1=_storage1, .shadingSsboIndex=(&shadingSsboIndex), .permutationsSampler_1_Sampler=permutationsSampler_1_Sampler, .permutationsSampler_1_Texture=permutationsSampler_1_Texture, .noiseSampler_1_Sampler=noiseSampler_1_Sampler, .noiseSampler_1_Texture=noiseSampler_1_Texture, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_outputs tint_wrapper_result = {};
   tint_wrapper_result.FSOut_sk_FragColor = tint_symbol_inner(FSIn{.ssboIndicesVar=inputs.FSIn_ssboIndicesVar, .localCoordsVar=inputs.FSIn_localCoordsVar}, tint_module_vars).sk_FragColor;
   return tint_wrapper_result;
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.msl b/test/tint/bug/tint/379127084.wgsl.expected.msl
index 19a4712..c1337b3 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.msl
+++ b/test/tint/bug/tint/379127084.wgsl.expected.msl
@@ -14,10 +14,17 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint shadingSsboIndex;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct FSIn {
   uint2 ssboIndicesVar;
   float2 localCoordsVar;
@@ -50,30 +57,31 @@
   /* 0x0000 */ tint_array<FSUniformData, 1> fsUniformData;
 };
 
-void _skslMain(FSIn _stageIn, thread FSOut* const _stageOut, thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_7, texture2d<float, access::sample> tint_symbol_8, sampler tint_symbol_9, texture2d<float, access::sample> tint_symbol_10, sampler tint_symbol_11) {
+void _skslMain(FSIn _stageIn, thread FSOut* const _stageOut, thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_7, const constant TintArrayLengths* const tint_symbol_8, texture2d<float, access::sample> tint_symbol_9, sampler tint_symbol_10, texture2d<float, access::sample> tint_symbol_11, sampler tint_symbol_12) {
   {
     (*(tint_private_vars)).shadingSsboIndex = _stageIn.ssboIndicesVar[1];
-    int const _56_d = (*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].noiseType_1;
-    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * (*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].baseFrequency_1));
+    int const _56_d = (*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].noiseType_1;
+    float2 _57_k = float2(((_stageIn.localCoordsVar + 0.5f) * (*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].baseFrequency_1));
     float4 _58_l = float4(0.0f);
-    float2 _59_m = float2((*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].stitchData_1);
+    float2 _59_m = float2((*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].stitchData_1);
     float _60_n = 1.0f;
     {
       int _61_o = 0;
       while(true) {
-        if ((_61_o < (*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].numOctaves_1)) {
+        TINT_ISOLATE_UB(tint_volatile_false);
+        if ((_61_o < (*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].numOctaves_1)) {
           {
             float4 _62_f = 0.0f;
             float2 const _skTemp2 = floor(_57_k);
             _62_f = float4(_skTemp2, _62_f.zw);
             _62_f = float4(_62_f.xy, (_62_f.xy + float2(1.0f)));
-            if (bool((*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].stitching_1)) {
+            if (bool((*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].stitching_1)) {
               float4 const _skTemp3 = step(_59_m.xyxy, _62_f);
               _62_f = (_62_f - (_skTemp3 * _59_m.xyxy));
             }
-            float4 const tint_symbol_1 = tint_symbol_8.sample(tint_symbol_9, float2(float2(((_62_f[0] + 0.5f) * 0.00390625f), 0.5f)), bias(-0.47499999403953552246f));
+            float4 const tint_symbol_1 = tint_symbol_9.sample(tint_symbol_10, float2(float2(((_62_f[0] + 0.5f) * 0.00390625f), 0.5f)), bias(-0.47499999403953552246f));
             float const _63_g = tint_symbol_1[0];
-            float4 const tint_symbol_2 = tint_symbol_8.sample(tint_symbol_9, float2(float2(((_62_f[2] + 0.5f) * 0.00390625f), 0.5f)), bias(-0.47499999403953552246f));
+            float4 const tint_symbol_2 = tint_symbol_9.sample(tint_symbol_10, float2(float2(((_62_f[2] + 0.5f) * 0.00390625f), 0.5f)), bias(-0.47499999403953552246f));
             float const _64_h = tint_symbol_2[0];
             float2 _65_i = float2(_63_g, _64_h);
             if (false) {
@@ -91,12 +99,13 @@
             {
               int _72_h = 0;
               while(true) {
+                TINT_ISOLATE_UB(tint_volatile_false_1);
                 {
                   float const _73_i = ((float(_72_h) + 0.5f) * 0.25f);
-                  float4 const _74_j = tint_symbol_10.sample(tint_symbol_11, float2(float(_67_p[0]), float(_73_i)), bias(-0.47499999403953552246f));
-                  float4 const _75_k = tint_symbol_10.sample(tint_symbol_11, float2(float(_67_p[1]), float(_73_i)), bias(-0.47499999403953552246f));
-                  float4 const _76_l = tint_symbol_10.sample(tint_symbol_11, float2(float(_67_p[3]), float(_73_i)), bias(-0.47499999403953552246f));
-                  float4 const _77_m = tint_symbol_10.sample(tint_symbol_11, float2(float(_67_p[2]), float(_73_i)), bias(-0.47499999403953552246f));
+                  float4 const _74_j = tint_symbol_11.sample(tint_symbol_12, float2(float(_67_p[0]), float(_73_i)), bias(-0.47499999403953552246f));
+                  float4 const _75_k = tint_symbol_11.sample(tint_symbol_12, float2(float(_67_p[1]), float(_73_i)), bias(-0.47499999403953552246f));
+                  float4 const _76_l = tint_symbol_11.sample(tint_symbol_12, float2(float(_67_p[3]), float(_73_i)), bias(-0.47499999403953552246f));
+                  float4 const _77_m = tint_symbol_11.sample(tint_symbol_12, float2(float(_67_p[2]), float(_73_i)), bias(-0.47499999403953552246f));
                   float2 _78_n = _68_d;
                   float const _skTemp7 = dot((((_74_j.yw + (_74_j.xz * 0.00390625f)) * 2.0f) - 1.0f), _78_n);
                   float _79_o = _skTemp7;
@@ -114,7 +123,7 @@
                   float const _skTemp12 = mix(_79_o, _80_p, _69_e[0]);
                   float const _82_r = _skTemp12;
                   float const _skTemp13 = mix(_81_q, _82_r, _69_e[1]);
-                  _71_g[_72_h] = _skTemp13;
+                  _71_g[min(uint(_72_h), 3u)] = _skTemp13;
                 }
                 {
                   _72_h = as_type<int>((as_type<uint>(_72_h) + as_type<uint>(1)));
@@ -148,7 +157,7 @@
     float const _skTemp16 = dot(float3(0.21259999275207519531f, 0.71520000696182250977f, 0.07220000028610229492f), float4(float3((float3(_58_l.xyz) * float(_58_l[3]))), float(float(_58_l[3]))).xyz);
     float const _skTemp17 = saturate(_skTemp16);
     float4 _84_a = float4(0.0f, 0.0f, 0.0f, _skTemp17);
-    int const _85_d = (*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].inHSL_4;
+    int const _85_d = (*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].inHSL_4;
     if (bool(_85_d)) {
       {
         float4 _skTemp18 = 0.0f;
@@ -182,7 +191,7 @@
         _84_a = float4((_84_a.xyz / _skTemp23), _84_a[3]);
       }
     }
-    float4 _94_f = float4((((*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].matrix_4 * float4(_84_a)) + (*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].translate_4));
+    float4 _94_f = float4((((*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].matrix_4 * float4(_84_a)) + (*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].translate_4));
     if (bool(_85_d)) {
       {
         float const _skTemp24 = fabs(((2.0f * _94_f[2]) - 1.0f));
@@ -197,7 +206,7 @@
       }
     } else {
       {
-        if (bool((*(tint_symbol_7)).fsUniformData[(*(tint_private_vars)).shadingSsboIndex].clampRGB_4)) {
+        if (bool((*(tint_symbol_7)).fsUniformData[min((*(tint_private_vars)).shadingSsboIndex, ((((*(tint_symbol_8)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].clampRGB_4)) {
           float4 const _skTemp29 = saturate(_94_f);
           _94_f = _skTemp29;
         } else {
@@ -221,16 +230,16 @@
   float4 sk_FragColor [[color(0)]];
 };
 
-FSOut tint_symbol_inner(FSIn _stageIn, thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_12, texture2d<float, access::sample> tint_symbol_13, sampler tint_symbol_14, texture2d<float, access::sample> tint_symbol_15, sampler tint_symbol_16) {
+FSOut tint_symbol_inner(FSIn _stageIn, thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_13, const constant TintArrayLengths* const tint_symbol_14, texture2d<float, access::sample> tint_symbol_15, sampler tint_symbol_16, texture2d<float, access::sample> tint_symbol_17, sampler tint_symbol_18) {
   FSOut _stageOut = {};
-  _skslMain(_stageIn, &(_stageOut), tint_private_vars, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16);
+  _skslMain(_stageIn, &(_stageOut), tint_private_vars, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16, tint_symbol_17, tint_symbol_18);
   return _stageOut;
 }
 
-fragment tint_symbol_5 tint_symbol(const device FSUniforms* tint_symbol_17 [[buffer(0)]], texture2d<float, access::sample> tint_symbol_18 [[texture(0)]], sampler tint_symbol_19 [[sampler(0)]], texture2d<float, access::sample> tint_symbol_20 [[texture(1)]], sampler tint_symbol_21 [[sampler(1)]], tint_symbol_4 tint_symbol_3 [[stage_in]]) {
+fragment tint_symbol_5 tint_symbol(const device FSUniforms* tint_symbol_19 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_20 [[buffer(30)]], texture2d<float, access::sample> tint_symbol_21 [[texture(0)]], sampler tint_symbol_22 [[sampler(0)]], texture2d<float, access::sample> tint_symbol_23 [[texture(1)]], sampler tint_symbol_24 [[sampler(1)]], tint_symbol_4 tint_symbol_3 [[stage_in]]) {
   thread tint_private_vars_struct tint_private_vars = {};
   FSIn const tint_symbol_6 = FSIn{.ssboIndicesVar=tint_symbol_3.ssboIndicesVar, .localCoordsVar=tint_symbol_3.localCoordsVar};
-  FSOut const inner_result = tint_symbol_inner(tint_symbol_6, &(tint_private_vars), tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20, tint_symbol_21);
+  FSOut const inner_result = tint_symbol_inner(tint_symbol_6, &(tint_private_vars), tint_symbol_19, tint_symbol_20, tint_symbol_21, tint_symbol_22, tint_symbol_23, tint_symbol_24);
   tint_symbol_5 wrapper_result = {};
   wrapper_result.sk_FragColor = inner_result.sk_FragColor;
   return wrapper_result;
diff --git a/test/tint/bug/tint/379127084.wgsl.expected.spvasm b/test/tint/bug/tint/379127084.wgsl.expected.spvasm
index 8b5262f..c1ba1c7 100644
--- a/test/tint/bug/tint/379127084.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/379127084.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 525
+; Bound: 564
 ; Schema: 0
                OpCapability Shader
-         %92 = OpExtInstImport "GLSL.std.450"
+         %52 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main" %main_loc0_Input %main_loc1_Input %main_loc0_Output
                OpExecutionMode %main OriginUpperLeft
@@ -194,50 +194,51 @@
       %FSOut = OpTypeStruct %v4float
 %_ptr_Function_FSOut = OpTypePointer Function %FSOut
          %41 = OpTypeFunction %void %FSIn %_ptr_Function_FSOut
-%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
+%_ptr_StorageBuffer__runtimearr_FSUniformData = OpTypePointer StorageBuffer %_runtimearr_FSUniformData
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_2 = OpConstant %uint 2
   %float_0_5 = OpConstant %float 0.5
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %63 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %74 = OpConstantNull %v4float
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
      %uint_3 = OpConstant %uint 3
        %bool = OpTypeBool
-        %101 = OpConstantComposite %v2float %float_1 %float_1
+        %118 = OpConstantComposite %v2float %float_1 %float_1
      %uint_4 = OpConstant %uint 4
-        %108 = OpConstantNull %int
+        %129 = OpConstantNull %int
 %float_0_00390625 = OpConstant %float 0.00390625
 %float_n0_474999994 = OpConstant %float -0.474999994
   %float_n16 = OpConstant %float -16
 %float_15_9899998 = OpConstant %float 15.9899998
-        %133 = OpTypeSampledImage %24
+        %154 = OpTypeSampledImage %24
       %false = OpConstantFalse %bool
   %float_255 = OpConstant %float 255
-        %154 = OpConstantComposite %v2float %float_255 %float_255
-        %157 = OpConstantComposite %v2float %float_0_5 %float_0_5
+        %175 = OpConstantComposite %v2float %float_255 %float_255
+        %178 = OpConstantComposite %v2float %float_0_5 %float_0_5
 %float_0_00392156886 = OpConstant %float 0.00392156886
-        %160 = OpConstantComposite %v2float %float_0_00392156886 %float_0_00392156886
+        %181 = OpConstantComposite %v2float %float_0_00392156886 %float_0_00392156886
   %float_256 = OpConstant %float 256
-        %172 = OpConstantComposite %v4float %float_0_00390625 %float_0_00390625 %float_0_00390625 %float_0_00390625
-        %177 = OpConstantNull %v2float
+        %193 = OpConstantComposite %v4float %float_0_00390625 %float_0_00390625 %float_0_00390625 %float_0_00390625
+        %198 = OpConstantNull %v2float
  %float_0_25 = OpConstant %float 0.25
     %float_2 = OpConstant %float 2
       %int_1 = OpConstant %int 1
       %int_4 = OpConstant %int 4
-        %301 = OpConstantComposite %v2float %float_2 %float_2
-        %313 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5
-        %317 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+        %324 = OpConstantComposite %v2float %float_2 %float_2
+        %336 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5
+        %340 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
     %v3float = OpTypeVector %float 3
 %float_0_212599993 = OpConstant %float 0.212599993
 %float_0_715200007 = OpConstant %float 0.715200007
 %float_0_0722000003 = OpConstant %float 0.0722000003
-        %329 = OpConstantComposite %v3float %float_0_212599993 %float_0_715200007 %float_0_0722000003
+        %352 = OpConstantComposite %v3float %float_0_212599993 %float_0_715200007 %float_0_0722000003
     %float_0 = OpConstant %float 0
      %uint_7 = OpConstant %uint 7
    %float_n1 = OpConstant %float -1
@@ -250,14 +251,14 @@
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_6 = OpConstant %uint 6
 %float_0_333333343 = OpConstant %float 0.333333343
-        %458 = OpConstantComposite %v3float %float_0 %float_0_666666687 %float_0_333333343
+        %493 = OpConstantComposite %v3float %float_0 %float_0_666666687 %float_0_333333343
     %float_3 = OpConstant %float 3
-        %469 = OpConstantNull %v3float
-        %470 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+        %504 = OpConstantNull %v3float
+        %505 = OpConstantComposite %v3float %float_1 %float_1 %float_1
      %uint_8 = OpConstant %uint 8
-        %511 = OpTypeFunction %FSOut %FSIn
-        %514 = OpConstantNull %FSOut
-        %518 = OpTypeFunction %void
+        %550 = OpTypeFunction %FSOut %FSIn
+        %553 = OpConstantNull %FSOut
+        %557 = OpTypeFunction %void
   %_skslMain = OpFunction %void None %41
    %_stageIn = OpFunctionParameter %FSIn
 %_stageOut_root = OpFunctionParameter %_ptr_Function_FSOut
@@ -267,514 +268,552 @@
       %_59_m = OpVariable %_ptr_Function_v2float Function
       %_60_n = OpVariable %_ptr_Function_float Function
       %_61_o = OpVariable %_ptr_Function_int Function
-      %_62_f = OpVariable %_ptr_Function_v4float Function %63
+      %_62_f = OpVariable %_ptr_Function_v4float Function %74
       %_65_i = OpVariable %_ptr_Function_v2float Function
       %_66_j = OpVariable %_ptr_Function_v4float Function
-      %_71_g = OpVariable %_ptr_Function_v4float Function %63
+      %_71_g = OpVariable %_ptr_Function_v4float Function %74
       %_72_h = OpVariable %_ptr_Function_int Function
       %_78_n = OpVariable %_ptr_Function_v2float Function
       %_79_o = OpVariable %_ptr_Function_float Function
       %_80_p = OpVariable %_ptr_Function_float Function
       %_83_q = OpVariable %_ptr_Function_v4float Function
       %_84_a = OpVariable %_ptr_Function_v4float Function
-  %_skTemp18 = OpVariable %_ptr_Function_v4float Function %63
-  %_skTemp19 = OpVariable %_ptr_Function_v4float Function %63
+  %_skTemp18 = OpVariable %_ptr_Function_v4float Function %74
+  %_skTemp19 = OpVariable %_ptr_Function_v4float Function %74
       %_94_f = OpVariable %_ptr_Function_v4float Function
          %43 = OpCompositeExtract %uint %_stageIn 0 1
                OpStore %shadingSsboIndex %43 None
          %44 = OpLoad %uint %shadingSsboIndex None
-         %45 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %44 %uint_2
-      %_56_d = OpLoad %int %45 None
-         %50 = OpCompositeExtract %v2float %_stageIn 1
-         %51 = OpCompositeConstruct %v2float %float_0_5 %float_0_5
-         %53 = OpFAdd %v2float %50 %51
-         %54 = OpLoad %uint %shadingSsboIndex None
-         %55 = OpAccessChain %_ptr_StorageBuffer_v2float %_storage1 %uint_0 %54 %uint_0
-         %57 = OpLoad %v2float %55 None
-         %58 = OpFMul %v2float %53 %57
-               OpStore %_57_k %58
-               OpStore %_58_l %63
-         %64 = OpLoad %uint %shadingSsboIndex None
-         %65 = OpAccessChain %_ptr_StorageBuffer_v2float %_storage1 %uint_0 %64 %uint_1
-         %67 = OpLoad %v2float %65 None
-               OpStore %_59_m %67
+         %45 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+         %48 = OpArrayLength %uint %_storage1 0
+         %49 = OpISub %uint %48 %uint_1
+         %51 = OpExtInst %uint %52 UMin %44 %49
+         %53 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %51 %uint_2
+      %_56_d = OpLoad %int %53 None
+         %57 = OpCompositeExtract %v2float %_stageIn 1
+         %58 = OpCompositeConstruct %v2float %float_0_5 %float_0_5
+         %60 = OpFAdd %v2float %57 %58
+         %61 = OpLoad %uint %shadingSsboIndex None
+         %62 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+         %63 = OpArrayLength %uint %_storage1 0
+         %64 = OpISub %uint %63 %uint_1
+         %65 = OpExtInst %uint %52 UMin %61 %64
+         %66 = OpAccessChain %_ptr_StorageBuffer_v2float %_storage1 %uint_0 %65 %uint_0
+         %68 = OpLoad %v2float %66 None
+         %69 = OpFMul %v2float %60 %68
+               OpStore %_57_k %69
+               OpStore %_58_l %74
+         %75 = OpLoad %uint %shadingSsboIndex None
+         %76 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+         %77 = OpArrayLength %uint %_storage1 0
+         %78 = OpISub %uint %77 %uint_1
+         %79 = OpExtInst %uint %52 UMin %75 %78
+         %80 = OpAccessChain %_ptr_StorageBuffer_v2float %_storage1 %uint_0 %79 %uint_1
+         %81 = OpLoad %v2float %80 None
+               OpStore %_59_m %81
                OpStore %_60_n %float_1
                OpStore %_61_o %int_0
-               OpBranch %77
-         %77 = OpLabel
-               OpLoopMerge %78 %76 None
-               OpBranch %75
-         %75 = OpLabel
-         %79 = OpLoad %int %_61_o None
-         %80 = OpLoad %uint %shadingSsboIndex None
-         %81 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %80 %uint_3
-         %83 = OpLoad %int %81 None
-         %84 = OpSLessThan %bool %79 %83
-               OpSelectionMerge %86 None
-               OpBranchConditional %84 %87 %88
-         %87 = OpLabel
-         %90 = OpLoad %v2float %_57_k None
-   %_skTemp2 = OpExtInst %v2float %92 Floor %90
-         %93 = OpLoad %v4float %_62_f None
-         %94 = OpVectorShuffle %v2float %93 %93 2 3
-         %95 = OpCompositeConstruct %v4float %_skTemp2 %94
-               OpStore %_62_f %95 None
-         %96 = OpLoad %v4float %_62_f None
-         %97 = OpVectorShuffle %v2float %96 %96 0 1
-         %98 = OpLoad %v4float %_62_f None
-         %99 = OpVectorShuffle %v2float %98 %98 0 1
-        %100 = OpFAdd %v2float %99 %101
-        %102 = OpCompositeConstruct %v4float %97 %100
-               OpStore %_62_f %102 None
-        %103 = OpLoad %uint %shadingSsboIndex None
-        %104 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %103 %uint_4
-        %106 = OpLoad %int %104 None
-        %107 = OpINotEqual %bool %106 %108
-               OpSelectionMerge %109 None
-               OpBranchConditional %107 %110 %109
-        %110 = OpLabel
-        %111 = OpLoad %v2float %_59_m None
-        %112 = OpVectorShuffle %v4float %111 %111 0 1 0 1
+               OpBranch %91
+         %91 = OpLabel
+               OpLoopMerge %92 %90 None
+               OpBranch %89
+         %89 = OpLabel
+         %93 = OpLoad %int %_61_o None
+         %94 = OpLoad %uint %shadingSsboIndex None
+         %95 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+         %96 = OpArrayLength %uint %_storage1 0
+         %97 = OpISub %uint %96 %uint_1
+         %98 = OpExtInst %uint %52 UMin %94 %97
+         %99 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %98 %uint_3
+        %101 = OpLoad %int %99 None
+        %102 = OpSLessThan %bool %93 %101
+               OpSelectionMerge %104 None
+               OpBranchConditional %102 %105 %106
+        %105 = OpLabel
+        %108 = OpLoad %v2float %_57_k None
+   %_skTemp2 = OpExtInst %v2float %52 Floor %108
+        %110 = OpLoad %v4float %_62_f None
+        %111 = OpVectorShuffle %v2float %110 %110 2 3
+        %112 = OpCompositeConstruct %v4float %_skTemp2 %111
+               OpStore %_62_f %112 None
         %113 = OpLoad %v4float %_62_f None
-   %_skTemp3 = OpExtInst %v4float %92 Step %112 %113
+        %114 = OpVectorShuffle %v2float %113 %113 0 1
         %115 = OpLoad %v4float %_62_f None
-        %116 = OpLoad %v2float %_59_m None
-        %117 = OpVectorShuffle %v4float %116 %116 0 1 0 1
-        %118 = OpFMul %v4float %_skTemp3 %117
-        %119 = OpFSub %v4float %115 %118
+        %116 = OpVectorShuffle %v2float %115 %115 0 1
+        %117 = OpFAdd %v2float %116 %118
+        %119 = OpCompositeConstruct %v4float %114 %117
                OpStore %_62_f %119 None
-               OpBranch %109
-        %109 = OpLabel
-        %120 = OpLoad %24 %permutationsSampler_1_Texture None
-        %121 = OpLoad %21 %permutationsSampler_1_Sampler None
-        %122 = OpAccessChain %_ptr_Function_float %_62_f %uint_0
-        %123 = OpLoad %float %122 None
-        %124 = OpFAdd %float %123 %float_0_5
-        %125 = OpFMul %float %124 %float_0_00390625
-        %127 = OpCompositeConstruct %v2float %125 %float_0_5
-        %128 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %132 = OpSampledImage %133 %120 %121
-        %134 = OpImageSampleImplicitLod %v4float %132 %127 Bias %128
-      %_63_g = OpCompositeExtract %float %134 0
-        %136 = OpLoad %24 %permutationsSampler_1_Texture None
-        %137 = OpLoad %21 %permutationsSampler_1_Sampler None
-        %138 = OpAccessChain %_ptr_Function_float %_62_f %uint_2
-        %139 = OpLoad %float %138 None
-        %140 = OpFAdd %float %139 %float_0_5
-        %141 = OpFMul %float %140 %float_0_00390625
-        %142 = OpCompositeConstruct %v2float %141 %float_0_5
-        %143 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %144 = OpSampledImage %133 %136 %137
-        %145 = OpImageSampleImplicitLod %v4float %144 %142 Bias %143
-      %_64_h = OpCompositeExtract %float %145 0
-        %147 = OpCompositeConstruct %v2float %_63_g %_64_h
-               OpStore %_65_i %147
-               OpSelectionMerge %149 None
-               OpBranchConditional %false %150 %149
-        %150 = OpLabel
-        %152 = OpLoad %v2float %_65_i None
-        %153 = OpFMul %v2float %152 %154
-        %156 = OpFAdd %v2float %153 %157
-   %_skTemp4 = OpExtInst %v2float %92 Floor %156
-        %159 = OpFMul %v2float %_skTemp4 %160
-               OpStore %_65_i %159 None
-               OpBranch %149
-        %149 = OpLabel
-        %162 = OpLoad %v2float %_65_i None
-        %163 = OpVectorShuffle %v4float %162 %162 0 1 0 1
-        %164 = OpVectorTimesScalar %v4float %163 %float_256
-        %166 = OpLoad %v4float %_62_f None
-        %167 = OpVectorShuffle %v4float %166 %166 1 1 3 3
-        %168 = OpFAdd %v4float %164 %167
-               OpStore %_66_j %168
-        %170 = OpLoad %v4float %_66_j None
-        %171 = OpFMul %v4float %170 %172
-               OpStore %_66_j %171 None
+        %120 = OpLoad %uint %shadingSsboIndex None
+        %121 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+        %122 = OpArrayLength %uint %_storage1 0
+        %123 = OpISub %uint %122 %uint_1
+        %124 = OpExtInst %uint %52 UMin %120 %123
+        %125 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %124 %uint_4
+        %127 = OpLoad %int %125 None
+        %128 = OpINotEqual %bool %127 %129
+               OpSelectionMerge %130 None
+               OpBranchConditional %128 %131 %130
+        %131 = OpLabel
+        %132 = OpLoad %v2float %_59_m None
+        %133 = OpVectorShuffle %v4float %132 %132 0 1 0 1
+        %134 = OpLoad %v4float %_62_f None
+   %_skTemp3 = OpExtInst %v4float %52 Step %133 %134
+        %136 = OpLoad %v4float %_62_f None
+        %137 = OpLoad %v2float %_59_m None
+        %138 = OpVectorShuffle %v4float %137 %137 0 1 0 1
+        %139 = OpFMul %v4float %_skTemp3 %138
+        %140 = OpFSub %v4float %136 %139
+               OpStore %_62_f %140 None
+               OpBranch %130
+        %130 = OpLabel
+        %141 = OpLoad %24 %permutationsSampler_1_Texture None
+        %142 = OpLoad %21 %permutationsSampler_1_Sampler None
+        %143 = OpAccessChain %_ptr_Function_float %_62_f %uint_0
+        %144 = OpLoad %float %143 None
+        %145 = OpFAdd %float %144 %float_0_5
+        %146 = OpFMul %float %145 %float_0_00390625
+        %148 = OpCompositeConstruct %v2float %146 %float_0_5
+        %149 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %153 = OpSampledImage %154 %141 %142
+        %155 = OpImageSampleImplicitLod %v4float %153 %148 Bias %149
+      %_63_g = OpCompositeExtract %float %155 0
+        %157 = OpLoad %24 %permutationsSampler_1_Texture None
+        %158 = OpLoad %21 %permutationsSampler_1_Sampler None
+        %159 = OpAccessChain %_ptr_Function_float %_62_f %uint_2
+        %160 = OpLoad %float %159 None
+        %161 = OpFAdd %float %160 %float_0_5
+        %162 = OpFMul %float %161 %float_0_00390625
+        %163 = OpCompositeConstruct %v2float %162 %float_0_5
+        %164 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %165 = OpSampledImage %154 %157 %158
+        %166 = OpImageSampleImplicitLod %v4float %165 %163 Bias %164
+      %_64_h = OpCompositeExtract %float %166 0
+        %168 = OpCompositeConstruct %v2float %_63_g %_64_h
+               OpStore %_65_i %168
+               OpSelectionMerge %170 None
+               OpBranchConditional %false %171 %170
+        %171 = OpLabel
+        %173 = OpLoad %v2float %_65_i None
+        %174 = OpFMul %v2float %173 %175
+        %177 = OpFAdd %v2float %174 %178
+   %_skTemp4 = OpExtInst %v2float %52 Floor %177
+        %180 = OpFMul %v2float %_skTemp4 %181
+               OpStore %_65_i %180 None
+               OpBranch %170
+        %170 = OpLabel
+        %183 = OpLoad %v2float %_65_i None
+        %184 = OpVectorShuffle %v4float %183 %183 0 1 0 1
+        %185 = OpVectorTimesScalar %v4float %184 %float_256
+        %187 = OpLoad %v4float %_62_f None
+        %188 = OpVectorShuffle %v4float %187 %187 1 1 3 3
+        %189 = OpFAdd %v4float %185 %188
+               OpStore %_66_j %189
+        %191 = OpLoad %v4float %_66_j None
+        %192 = OpFMul %v4float %191 %193
+               OpStore %_66_j %192 None
       %_67_p = OpLoad %v4float %_66_j None
-        %174 = OpLoad %v2float %_57_k None
-   %_skTemp5 = OpExtInst %v2float %92 Fract %174
-   %_skTemp6 = OpExtInst %v2float %92 SmoothStep %177 %101 %_skTemp5
+        %195 = OpLoad %v2float %_57_k None
+   %_skTemp5 = OpExtInst %v2float %52 Fract %195
+   %_skTemp6 = OpExtInst %v2float %52 SmoothStep %198 %118 %_skTemp5
                OpStore %_72_h %int_0
-               OpBranch %182
-        %182 = OpLabel
-               OpLoopMerge %183 %181 None
-               OpBranch %180
-        %180 = OpLabel
-        %184 = OpLoad %int %_72_h None
-        %185 = OpConvertSToF %float %184
-        %186 = OpFAdd %float %185 %float_0_5
-      %_73_i = OpFMul %float %186 %float_0_25
-        %189 = OpLoad %24 %noiseSampler_1_Texture None
-        %190 = OpLoad %21 %noiseSampler_1_Sampler None
-        %191 = OpCompositeExtract %float %_67_p 0
-        %192 = OpCompositeConstruct %v2float %191 %_73_i
-        %193 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %194 = OpSampledImage %133 %189 %190
-      %_74_j = OpImageSampleImplicitLod %v4float %194 %192 Bias %193
-        %196 = OpLoad %24 %noiseSampler_1_Texture None
-        %197 = OpLoad %21 %noiseSampler_1_Sampler None
-        %198 = OpCompositeExtract %float %_67_p 1
-        %199 = OpCompositeConstruct %v2float %198 %_73_i
-        %200 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %201 = OpSampledImage %133 %196 %197
-      %_75_k = OpImageSampleImplicitLod %v4float %201 %199 Bias %200
-        %203 = OpLoad %24 %noiseSampler_1_Texture None
-        %204 = OpLoad %21 %noiseSampler_1_Sampler None
-        %205 = OpCompositeExtract %float %_67_p 3
-        %206 = OpCompositeConstruct %v2float %205 %_73_i
-        %207 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %208 = OpSampledImage %133 %203 %204
-      %_76_l = OpImageSampleImplicitLod %v4float %208 %206 Bias %207
+               OpBranch %203
+        %203 = OpLabel
+               OpLoopMerge %204 %202 None
+               OpBranch %201
+        %201 = OpLabel
+        %205 = OpLoad %int %_72_h None
+        %206 = OpConvertSToF %float %205
+        %207 = OpFAdd %float %206 %float_0_5
+      %_73_i = OpFMul %float %207 %float_0_25
         %210 = OpLoad %24 %noiseSampler_1_Texture None
         %211 = OpLoad %21 %noiseSampler_1_Sampler None
-        %212 = OpCompositeExtract %float %_67_p 2
+        %212 = OpCompositeExtract %float %_67_p 0
         %213 = OpCompositeConstruct %v2float %212 %_73_i
-        %214 = OpExtInst %float %92 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
-        %215 = OpSampledImage %133 %210 %211
-      %_77_m = OpImageSampleImplicitLod %v4float %215 %213 Bias %214
+        %214 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %215 = OpSampledImage %154 %210 %211
+      %_74_j = OpImageSampleImplicitLod %v4float %215 %213 Bias %214
+        %217 = OpLoad %24 %noiseSampler_1_Texture None
+        %218 = OpLoad %21 %noiseSampler_1_Sampler None
+        %219 = OpCompositeExtract %float %_67_p 1
+        %220 = OpCompositeConstruct %v2float %219 %_73_i
+        %221 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %222 = OpSampledImage %154 %217 %218
+      %_75_k = OpImageSampleImplicitLod %v4float %222 %220 Bias %221
+        %224 = OpLoad %24 %noiseSampler_1_Texture None
+        %225 = OpLoad %21 %noiseSampler_1_Sampler None
+        %226 = OpCompositeExtract %float %_67_p 3
+        %227 = OpCompositeConstruct %v2float %226 %_73_i
+        %228 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %229 = OpSampledImage %154 %224 %225
+      %_76_l = OpImageSampleImplicitLod %v4float %229 %227 Bias %228
+        %231 = OpLoad %24 %noiseSampler_1_Texture None
+        %232 = OpLoad %21 %noiseSampler_1_Sampler None
+        %233 = OpCompositeExtract %float %_67_p 2
+        %234 = OpCompositeConstruct %v2float %233 %_73_i
+        %235 = OpExtInst %float %52 NClamp %float_n0_474999994 %float_n16 %float_15_9899998
+        %236 = OpSampledImage %154 %231 %232
+      %_77_m = OpImageSampleImplicitLod %v4float %236 %234 Bias %235
                OpStore %_78_n %_skTemp5
-        %218 = OpVectorShuffle %v2float %_74_j %_74_j 1 3
-        %219 = OpVectorShuffle %v2float %_74_j %_74_j 0 2
-        %220 = OpVectorTimesScalar %v2float %219 %float_0_00390625
-        %221 = OpFAdd %v2float %218 %220
-        %222 = OpVectorTimesScalar %v2float %221 %float_2
-        %224 = OpCompositeConstruct %v2float %float_1 %float_1
-        %225 = OpFSub %v2float %222 %224
-        %226 = OpLoad %v2float %_78_n None
-   %_skTemp7 = OpDot %float %225 %226
+        %239 = OpVectorShuffle %v2float %_74_j %_74_j 1 3
+        %240 = OpVectorShuffle %v2float %_74_j %_74_j 0 2
+        %241 = OpVectorTimesScalar %v2float %240 %float_0_00390625
+        %242 = OpFAdd %v2float %239 %241
+        %243 = OpVectorTimesScalar %v2float %242 %float_2
+        %245 = OpCompositeConstruct %v2float %float_1 %float_1
+        %246 = OpFSub %v2float %243 %245
+        %247 = OpLoad %v2float %_78_n None
+   %_skTemp7 = OpDot %float %246 %247
                OpStore %_79_o %_skTemp7
-        %229 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
-        %230 = OpLoad %float %229 None
-        %231 = OpFSub %float %230 %float_1
-        %232 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
-               OpStore %232 %231 None
-        %233 = OpVectorShuffle %v2float %_75_k %_75_k 1 3
-        %234 = OpVectorShuffle %v2float %_75_k %_75_k 0 2
-        %235 = OpVectorTimesScalar %v2float %234 %float_0_00390625
-        %236 = OpFAdd %v2float %233 %235
-        %237 = OpVectorTimesScalar %v2float %236 %float_2
-        %238 = OpCompositeConstruct %v2float %float_1 %float_1
-        %239 = OpFSub %v2float %237 %238
-        %240 = OpLoad %v2float %_78_n None
-   %_skTemp8 = OpDot %float %239 %240
+        %250 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
+        %251 = OpLoad %float %250 None
+        %252 = OpFSub %float %251 %float_1
+        %253 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
+               OpStore %253 %252 None
+        %254 = OpVectorShuffle %v2float %_75_k %_75_k 1 3
+        %255 = OpVectorShuffle %v2float %_75_k %_75_k 0 2
+        %256 = OpVectorTimesScalar %v2float %255 %float_0_00390625
+        %257 = OpFAdd %v2float %254 %256
+        %258 = OpVectorTimesScalar %v2float %257 %float_2
+        %259 = OpCompositeConstruct %v2float %float_1 %float_1
+        %260 = OpFSub %v2float %258 %259
+        %261 = OpLoad %v2float %_78_n None
+   %_skTemp8 = OpDot %float %260 %261
                OpStore %_80_p %_skTemp8
-        %243 = OpLoad %float %_79_o None
-        %244 = OpLoad %float %_80_p None
-        %245 = OpCompositeExtract %float %_skTemp6 0
-   %_skTemp9 = OpExtInst %float %92 FMix %243 %244 %245
-        %247 = OpAccessChain %_ptr_Function_float %_78_n %uint_1
-        %248 = OpLoad %float %247 None
-        %249 = OpFSub %float %248 %float_1
-        %250 = OpAccessChain %_ptr_Function_float %_78_n %uint_1
-               OpStore %250 %249 None
-        %251 = OpVectorShuffle %v2float %_76_l %_76_l 1 3
-        %252 = OpVectorShuffle %v2float %_76_l %_76_l 0 2
-        %253 = OpVectorTimesScalar %v2float %252 %float_0_00390625
-        %254 = OpFAdd %v2float %251 %253
-        %255 = OpVectorTimesScalar %v2float %254 %float_2
-        %256 = OpCompositeConstruct %v2float %float_1 %float_1
-        %257 = OpFSub %v2float %255 %256
-        %258 = OpLoad %v2float %_78_n None
-  %_skTemp10 = OpDot %float %257 %258
+        %264 = OpLoad %float %_79_o None
+        %265 = OpLoad %float %_80_p None
+        %266 = OpCompositeExtract %float %_skTemp6 0
+   %_skTemp9 = OpExtInst %float %52 FMix %264 %265 %266
+        %268 = OpAccessChain %_ptr_Function_float %_78_n %uint_1
+        %269 = OpLoad %float %268 None
+        %270 = OpFSub %float %269 %float_1
+        %271 = OpAccessChain %_ptr_Function_float %_78_n %uint_1
+               OpStore %271 %270 None
+        %272 = OpVectorShuffle %v2float %_76_l %_76_l 1 3
+        %273 = OpVectorShuffle %v2float %_76_l %_76_l 0 2
+        %274 = OpVectorTimesScalar %v2float %273 %float_0_00390625
+        %275 = OpFAdd %v2float %272 %274
+        %276 = OpVectorTimesScalar %v2float %275 %float_2
+        %277 = OpCompositeConstruct %v2float %float_1 %float_1
+        %278 = OpFSub %v2float %276 %277
+        %279 = OpLoad %v2float %_78_n None
+  %_skTemp10 = OpDot %float %278 %279
                OpStore %_80_p %_skTemp10 None
-        %260 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
-        %261 = OpLoad %float %260 None
-        %262 = OpFAdd %float %261 %float_1
-        %263 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
-               OpStore %263 %262 None
-        %264 = OpVectorShuffle %v2float %_77_m %_77_m 1 3
-        %265 = OpVectorShuffle %v2float %_77_m %_77_m 0 2
-        %266 = OpVectorTimesScalar %v2float %265 %float_0_00390625
-        %267 = OpFAdd %v2float %264 %266
-        %268 = OpVectorTimesScalar %v2float %267 %float_2
-        %269 = OpCompositeConstruct %v2float %float_1 %float_1
-        %270 = OpFSub %v2float %268 %269
-        %271 = OpLoad %v2float %_78_n None
-  %_skTemp11 = OpDot %float %270 %271
+        %281 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
+        %282 = OpLoad %float %281 None
+        %283 = OpFAdd %float %282 %float_1
+        %284 = OpAccessChain %_ptr_Function_float %_78_n %uint_0
+               OpStore %284 %283 None
+        %285 = OpVectorShuffle %v2float %_77_m %_77_m 1 3
+        %286 = OpVectorShuffle %v2float %_77_m %_77_m 0 2
+        %287 = OpVectorTimesScalar %v2float %286 %float_0_00390625
+        %288 = OpFAdd %v2float %285 %287
+        %289 = OpVectorTimesScalar %v2float %288 %float_2
+        %290 = OpCompositeConstruct %v2float %float_1 %float_1
+        %291 = OpFSub %v2float %289 %290
+        %292 = OpLoad %v2float %_78_n None
+  %_skTemp11 = OpDot %float %291 %292
                OpStore %_79_o %_skTemp11 None
-        %273 = OpLoad %float %_79_o None
-        %274 = OpLoad %float %_80_p None
-        %275 = OpCompositeExtract %float %_skTemp6 0
-  %_skTemp12 = OpExtInst %float %92 FMix %273 %274 %275
-        %277 = OpCompositeExtract %float %_skTemp6 1
-  %_skTemp13 = OpExtInst %float %92 FMix %_skTemp9 %_skTemp12 %277
-        %279 = OpLoad %int %_72_h None
-        %280 = OpAccessChain %_ptr_Function_float %_71_g %279
-               OpStore %280 %_skTemp13 None
-               OpBranch %181
-        %181 = OpLabel
-        %281 = OpLoad %int %_72_h None
-        %282 = OpIAdd %int %281 %int_1
-               OpStore %_72_h %282 None
-        %284 = OpLoad %int %_72_h None
-        %285 = OpSGreaterThanEqual %bool %284 %int_4
-               OpBranchConditional %285 %183 %182
-        %183 = OpLabel
-        %287 = OpLoad %v4float %_71_g None
-               OpStore %_83_q %287
-        %289 = OpINotEqual %bool %_56_d %int_0
-               OpSelectionMerge %290 None
-               OpBranchConditional %289 %291 %290
-        %291 = OpLabel
-        %292 = OpLoad %v4float %_83_q None
-  %_skTemp14 = OpExtInst %v4float %92 FAbs %292
+        %294 = OpLoad %float %_79_o None
+        %295 = OpLoad %float %_80_p None
+        %296 = OpCompositeExtract %float %_skTemp6 0
+  %_skTemp12 = OpExtInst %float %52 FMix %294 %295 %296
+        %298 = OpCompositeExtract %float %_skTemp6 1
+  %_skTemp13 = OpExtInst %float %52 FMix %_skTemp9 %_skTemp12 %298
+        %300 = OpLoad %int %_72_h None
+        %301 = OpBitcast %uint %300
+        %302 = OpExtInst %uint %52 UMin %301 %uint_3
+        %303 = OpAccessChain %_ptr_Function_float %_71_g %302
+               OpStore %303 %_skTemp13 None
+               OpBranch %202
+        %202 = OpLabel
+        %304 = OpLoad %int %_72_h None
+        %305 = OpIAdd %int %304 %int_1
+               OpStore %_72_h %305 None
+        %307 = OpLoad %int %_72_h None
+        %308 = OpSGreaterThanEqual %bool %307 %int_4
+               OpBranchConditional %308 %204 %203
+        %204 = OpLabel
+        %310 = OpLoad %v4float %_71_g None
+               OpStore %_83_q %310
+        %312 = OpINotEqual %bool %_56_d %int_0
+               OpSelectionMerge %313 None
+               OpBranchConditional %312 %314 %313
+        %314 = OpLabel
+        %315 = OpLoad %v4float %_83_q None
+  %_skTemp14 = OpExtInst %v4float %52 FAbs %315
                OpStore %_83_q %_skTemp14 None
-               OpBranch %290
-        %290 = OpLabel
-        %294 = OpLoad %v4float %_58_l None
-        %295 = OpLoad %v4float %_83_q None
-        %296 = OpLoad %float %_60_n None
-        %297 = OpVectorTimesScalar %v4float %295 %296
-        %298 = OpFAdd %v4float %294 %297
-               OpStore %_58_l %298 None
-        %299 = OpLoad %v2float %_57_k None
-        %300 = OpFMul %v2float %299 %301
-               OpStore %_57_k %300 None
-        %302 = OpLoad %float %_60_n None
-        %303 = OpFMul %float %302 %float_0_5
-               OpStore %_60_n %303 None
-        %304 = OpLoad %v2float %_59_m None
-        %305 = OpFMul %v2float %304 %301
-               OpStore %_59_m %305 None
-               OpBranch %86
-         %88 = OpLabel
-               OpBranch %78
-         %86 = OpLabel
-               OpBranch %76
-         %76 = OpLabel
-        %306 = OpLoad %int %_61_o None
-        %307 = OpIAdd %int %306 %int_1
-               OpStore %_61_o %307 None
-               OpBranch %77
-         %78 = OpLabel
-        %308 = OpIEqual %bool %_56_d %int_0
-               OpSelectionMerge %309 None
-               OpBranchConditional %308 %310 %309
-        %310 = OpLabel
-        %311 = OpLoad %v4float %_58_l None
-        %312 = OpFMul %v4float %311 %313
-        %314 = OpFAdd %v4float %312 %313
-               OpStore %_58_l %314 None
-               OpBranch %309
-        %309 = OpLabel
-        %315 = OpLoad %v4float %_58_l None
-  %_skTemp15 = OpExtInst %v4float %92 NClamp %315 %63 %317
+               OpBranch %313
+        %313 = OpLabel
+        %317 = OpLoad %v4float %_58_l None
+        %318 = OpLoad %v4float %_83_q None
+        %319 = OpLoad %float %_60_n None
+        %320 = OpVectorTimesScalar %v4float %318 %319
+        %321 = OpFAdd %v4float %317 %320
+               OpStore %_58_l %321 None
+        %322 = OpLoad %v2float %_57_k None
+        %323 = OpFMul %v2float %322 %324
+               OpStore %_57_k %323 None
+        %325 = OpLoad %float %_60_n None
+        %326 = OpFMul %float %325 %float_0_5
+               OpStore %_60_n %326 None
+        %327 = OpLoad %v2float %_59_m None
+        %328 = OpFMul %v2float %327 %324
+               OpStore %_59_m %328 None
+               OpBranch %104
+        %106 = OpLabel
+               OpBranch %92
+        %104 = OpLabel
+               OpBranch %90
+         %90 = OpLabel
+        %329 = OpLoad %int %_61_o None
+        %330 = OpIAdd %int %329 %int_1
+               OpStore %_61_o %330 None
+               OpBranch %91
+         %92 = OpLabel
+        %331 = OpIEqual %bool %_56_d %int_0
+               OpSelectionMerge %332 None
+               OpBranchConditional %331 %333 %332
+        %333 = OpLabel
+        %334 = OpLoad %v4float %_58_l None
+        %335 = OpFMul %v4float %334 %336
+        %337 = OpFAdd %v4float %335 %336
+               OpStore %_58_l %337 None
+               OpBranch %332
+        %332 = OpLabel
+        %338 = OpLoad %v4float %_58_l None
+  %_skTemp15 = OpExtInst %v4float %52 NClamp %338 %74 %340
                OpStore %_58_l %_skTemp15 None
-        %318 = OpLoad %v4float %_58_l None
-        %319 = OpVectorShuffle %v3float %318 %318 0 1 2
-        %321 = OpAccessChain %_ptr_Function_float %_58_l %uint_3
-        %322 = OpLoad %float %321 None
-        %323 = OpVectorTimesScalar %v3float %319 %322
-        %324 = OpAccessChain %_ptr_Function_float %_58_l %uint_3
-        %325 = OpLoad %float %324 None
-        %326 = OpCompositeConstruct %v4float %323 %325
-        %327 = OpVectorShuffle %v3float %326 %326 0 1 2
-  %_skTemp16 = OpDot %float %329 %327
-  %_skTemp17 = OpExtInst %float %92 NClamp %_skTemp16 %float_0 %float_1
-        %335 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %_skTemp17
-               OpStore %_84_a %335
-        %337 = OpLoad %uint %shadingSsboIndex None
-        %338 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %337 %uint_7
-      %_85_d = OpLoad %int %338 None
-        %341 = OpINotEqual %bool %_85_d %108
-               OpSelectionMerge %342 None
-               OpBranchConditional %341 %343 %344
-        %343 = OpLabel
-        %346 = OpAccessChain %_ptr_Function_float %_84_a %uint_1
-        %347 = OpLoad %float %346 None
-        %348 = OpAccessChain %_ptr_Function_float %_84_a %uint_2
-        %349 = OpLoad %float %348 None
-        %350 = OpFOrdLessThan %bool %347 %349
-               OpSelectionMerge %351 None
-               OpBranchConditional %350 %352 %353
-        %352 = OpLabel
-        %354 = OpLoad %v4float %_84_a None
-        %355 = OpVectorShuffle %v2float %354 %354 2 1
-        %356 = OpCompositeConstruct %v4float %355 %float_n1 %float_0_666666687
-               OpStore %_skTemp18 %356 None
-               OpBranch %351
-        %353 = OpLabel
-        %359 = OpLoad %v4float %_84_a None
-        %360 = OpVectorShuffle %v2float %359 %359 1 2
-        %361 = OpCompositeConstruct %v4float %360 %float_0 %float_n0_333333343
-               OpStore %_skTemp18 %361 None
-               OpBranch %351
-        %351 = OpLabel
-      %_86_e = OpLoad %v4float %_skTemp18 None
-        %365 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
-        %366 = OpLoad %float %365 None
-        %367 = OpCompositeExtract %float %_86_e 0
-        %368 = OpFOrdLessThan %bool %366 %367
+        %341 = OpLoad %v4float %_58_l None
+        %342 = OpVectorShuffle %v3float %341 %341 0 1 2
+        %344 = OpAccessChain %_ptr_Function_float %_58_l %uint_3
+        %345 = OpLoad %float %344 None
+        %346 = OpVectorTimesScalar %v3float %342 %345
+        %347 = OpAccessChain %_ptr_Function_float %_58_l %uint_3
+        %348 = OpLoad %float %347 None
+        %349 = OpCompositeConstruct %v4float %346 %348
+        %350 = OpVectorShuffle %v3float %349 %349 0 1 2
+  %_skTemp16 = OpDot %float %352 %350
+  %_skTemp17 = OpExtInst %float %52 NClamp %_skTemp16 %float_0 %float_1
+        %358 = OpCompositeConstruct %v4float %float_0 %float_0 %float_0 %_skTemp17
+               OpStore %_84_a %358
+        %360 = OpLoad %uint %shadingSsboIndex None
+        %361 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+        %362 = OpArrayLength %uint %_storage1 0
+        %363 = OpISub %uint %362 %uint_1
+        %364 = OpExtInst %uint %52 UMin %360 %363
+        %365 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %364 %uint_7
+      %_85_d = OpLoad %int %365 None
+        %368 = OpINotEqual %bool %_85_d %129
                OpSelectionMerge %369 None
                OpBranchConditional %368 %370 %371
         %370 = OpLabel
-        %372 = OpCompositeExtract %float %_86_e 0
-        %373 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
+        %373 = OpAccessChain %_ptr_Function_float %_84_a %uint_1
         %374 = OpLoad %float %373 None
-        %375 = OpVectorShuffle %v2float %_86_e %_86_e 1 3
-        %376 = OpCompositeConstruct %v4float %372 %374 %375
-               OpStore %_skTemp19 %376 None
-               OpBranch %369
-        %371 = OpLabel
-        %377 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
-        %378 = OpLoad %float %377 None
-        %379 = OpCompositeExtract %float %_86_e 0
-        %380 = OpVectorShuffle %v2float %_86_e %_86_e 1 2
-        %381 = OpCompositeConstruct %v4float %378 %379 %380
-               OpStore %_skTemp19 %381 None
-               OpBranch %369
-        %369 = OpLabel
+        %375 = OpAccessChain %_ptr_Function_float %_84_a %uint_2
+        %376 = OpLoad %float %375 None
+        %377 = OpFOrdLessThan %bool %374 %376
+               OpSelectionMerge %378 None
+               OpBranchConditional %377 %379 %380
+        %379 = OpLabel
+        %381 = OpLoad %v4float %_84_a None
+        %382 = OpVectorShuffle %v2float %381 %381 2 1
+        %383 = OpCompositeConstruct %v4float %382 %float_n1 %float_0_666666687
+               OpStore %_skTemp18 %383 None
+               OpBranch %378
+        %380 = OpLabel
+        %386 = OpLoad %v4float %_84_a None
+        %387 = OpVectorShuffle %v2float %386 %386 1 2
+        %388 = OpCompositeConstruct %v4float %387 %float_0 %float_n0_333333343
+               OpStore %_skTemp18 %388 None
+               OpBranch %378
+        %378 = OpLabel
+      %_86_e = OpLoad %v4float %_skTemp18 None
+        %392 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
+        %393 = OpLoad %float %392 None
+        %394 = OpCompositeExtract %float %_86_e 0
+        %395 = OpFOrdLessThan %bool %393 %394
+               OpSelectionMerge %396 None
+               OpBranchConditional %395 %397 %398
+        %397 = OpLabel
+        %399 = OpCompositeExtract %float %_86_e 0
+        %400 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
+        %401 = OpLoad %float %400 None
+        %402 = OpVectorShuffle %v2float %_86_e %_86_e 1 3
+        %403 = OpCompositeConstruct %v4float %399 %401 %402
+               OpStore %_skTemp19 %403 None
+               OpBranch %396
+        %398 = OpLabel
+        %404 = OpAccessChain %_ptr_Function_float %_84_a %uint_0
+        %405 = OpLoad %float %404 None
+        %406 = OpCompositeExtract %float %_86_e 0
+        %407 = OpVectorShuffle %v2float %_86_e %_86_e 1 2
+        %408 = OpCompositeConstruct %v4float %405 %406 %407
+               OpStore %_skTemp19 %408 None
+               OpBranch %396
+        %396 = OpLabel
       %_87_f = OpLoad %v4float %_skTemp19 None
       %_88_h = OpCompositeExtract %float %_87_f 0
-        %384 = OpCompositeExtract %float %_87_f 1
-        %385 = OpCompositeExtract %float %_87_f 2
-  %_skTemp20 = OpExtInst %float %92 FMin %384 %385
+        %411 = OpCompositeExtract %float %_87_f 1
+        %412 = OpCompositeExtract %float %_87_f 2
+  %_skTemp20 = OpExtInst %float %52 FMin %411 %412
       %_89_i = OpFSub %float %_88_h %_skTemp20
-        %388 = OpFMul %float %_89_i %float_0_5
-      %_90_j = OpFSub %float %_88_h %388
-        %390 = OpCompositeExtract %float %_87_f 3
-        %391 = OpCompositeExtract %float %_87_f 1
-        %392 = OpCompositeExtract %float %_87_f 2
-        %393 = OpFSub %float %391 %392
-        %394 = OpFMul %float %_89_i %float_6
-        %396 = OpFAdd %float %394 %float_9_99999975en05
-        %398 = OpFDiv %float %393 %396
-        %399 = OpFAdd %float %390 %398
-  %_skTemp21 = OpExtInst %float %92 FAbs %399
-        %401 = OpFMul %float %_90_j %float_2
-        %402 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %403 = OpLoad %float %402 None
-        %404 = OpFSub %float %401 %403
-  %_skTemp22 = OpExtInst %float %92 FAbs %404
-        %406 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %407 = OpLoad %float %406 None
-        %408 = OpFAdd %float %407 %float_9_99999975en05
-        %409 = OpFSub %float %408 %_skTemp22
-      %_92_l = OpFDiv %float %_89_i %409
-        %411 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %412 = OpLoad %float %411 None
-        %413 = OpFAdd %float %412 %float_9_99999975en05
-      %_93_m = OpFDiv %float %_90_j %413
-        %415 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %416 = OpLoad %float %415 None
-        %417 = OpCompositeConstruct %v4float %_skTemp21 %_92_l %_93_m %416
-               OpStore %_84_a %417 None
-               OpBranch %342
-        %344 = OpLabel
-        %418 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %419 = OpLoad %float %418 None
-  %_skTemp23 = OpExtInst %float %92 FMax %419 %float_9_99999975en05
-        %421 = OpLoad %v4float %_84_a None
-        %422 = OpVectorShuffle %v3float %421 %421 0 1 2
-        %423 = OpCompositeConstruct %v3float %_skTemp23 %_skTemp23 %_skTemp23
-        %424 = OpFDiv %v3float %422 %423
-        %425 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
-        %426 = OpLoad %float %425 None
-        %427 = OpCompositeConstruct %v4float %424 %426
-               OpStore %_84_a %427 None
-               OpBranch %342
-        %342 = OpLabel
-        %428 = OpLoad %uint %shadingSsboIndex None
-        %429 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %_storage1 %uint_0 %428 %uint_5
-        %432 = OpLoad %mat4v4float %429 None
-        %433 = OpLoad %v4float %_84_a None
-        %434 = OpMatrixTimesVector %v4float %432 %433
-        %435 = OpLoad %uint %shadingSsboIndex None
-        %436 = OpAccessChain %_ptr_StorageBuffer_v4float %_storage1 %uint_0 %435 %uint_6
-        %439 = OpLoad %v4float %436 None
-        %440 = OpFAdd %v4float %434 %439
-               OpStore %_94_f %440
-        %442 = OpINotEqual %bool %_85_d %108
-               OpSelectionMerge %443 None
-               OpBranchConditional %442 %444 %445
-        %444 = OpLabel
-        %446 = OpAccessChain %_ptr_Function_float %_94_f %uint_2
-        %447 = OpLoad %float %446 None
-        %448 = OpFMul %float %float_2 %447
-        %449 = OpFSub %float %448 %float_1
-  %_skTemp24 = OpExtInst %float %92 FAbs %449
-        %451 = OpFSub %float %float_1 %_skTemp24
-        %452 = OpAccessChain %_ptr_Function_float %_94_f %uint_1
+        %415 = OpFMul %float %_89_i %float_0_5
+      %_90_j = OpFSub %float %_88_h %415
+        %417 = OpCompositeExtract %float %_87_f 3
+        %418 = OpCompositeExtract %float %_87_f 1
+        %419 = OpCompositeExtract %float %_87_f 2
+        %420 = OpFSub %float %418 %419
+        %421 = OpFMul %float %_89_i %float_6
+        %423 = OpFAdd %float %421 %float_9_99999975en05
+        %425 = OpFDiv %float %420 %423
+        %426 = OpFAdd %float %417 %425
+  %_skTemp21 = OpExtInst %float %52 FAbs %426
+        %428 = OpFMul %float %_90_j %float_2
+        %429 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
+        %430 = OpLoad %float %429 None
+        %431 = OpFSub %float %428 %430
+  %_skTemp22 = OpExtInst %float %52 FAbs %431
+        %433 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
+        %434 = OpLoad %float %433 None
+        %435 = OpFAdd %float %434 %float_9_99999975en05
+        %436 = OpFSub %float %435 %_skTemp22
+      %_92_l = OpFDiv %float %_89_i %436
+        %438 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
+        %439 = OpLoad %float %438 None
+        %440 = OpFAdd %float %439 %float_9_99999975en05
+      %_93_m = OpFDiv %float %_90_j %440
+        %442 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
+        %443 = OpLoad %float %442 None
+        %444 = OpCompositeConstruct %v4float %_skTemp21 %_92_l %_93_m %443
+               OpStore %_84_a %444 None
+               OpBranch %369
+        %371 = OpLabel
+        %445 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
+        %446 = OpLoad %float %445 None
+  %_skTemp23 = OpExtInst %float %52 FMax %446 %float_9_99999975en05
+        %448 = OpLoad %v4float %_84_a None
+        %449 = OpVectorShuffle %v3float %448 %448 0 1 2
+        %450 = OpCompositeConstruct %v3float %_skTemp23 %_skTemp23 %_skTemp23
+        %451 = OpFDiv %v3float %449 %450
+        %452 = OpAccessChain %_ptr_Function_float %_84_a %uint_3
         %453 = OpLoad %float %452 None
-      %_95_b = OpFMul %float %451 %453
-        %455 = OpLoad %v4float %_94_f None
-        %456 = OpVectorShuffle %v3float %455 %455 0 0 0
-      %_96_c = OpFAdd %v3float %456 %458
-  %_skTemp25 = OpExtInst %v3float %92 Fract %_96_c
-        %461 = OpVectorTimesScalar %v3float %_skTemp25 %float_6
-        %462 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
-        %464 = OpFSub %v3float %461 %462
-  %_skTemp26 = OpExtInst %v3float %92 FAbs %464
-        %466 = OpCompositeConstruct %v3float %float_1 %float_1 %float_1
-        %467 = OpFSub %v3float %_skTemp26 %466
-  %_skTemp27 = OpExtInst %v3float %92 NClamp %467 %469 %470
-        %471 = OpCompositeConstruct %v3float %float_0_5 %float_0_5 %float_0_5
-        %472 = OpFSub %v3float %_skTemp27 %471
-        %473 = OpVectorTimesScalar %v3float %472 %_95_b
-        %474 = OpAccessChain %_ptr_Function_float %_94_f %uint_2
-        %475 = OpLoad %float %474 None
-        %476 = OpCompositeConstruct %v3float %475 %475 %475
-        %477 = OpFAdd %v3float %473 %476
-        %478 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
-        %479 = OpLoad %float %478 None
-        %480 = OpVectorTimesScalar %v3float %477 %479
-        %481 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %454 = OpCompositeConstruct %v4float %451 %453
+               OpStore %_84_a %454 None
+               OpBranch %369
+        %369 = OpLabel
+        %455 = OpLoad %uint %shadingSsboIndex None
+        %456 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+        %457 = OpArrayLength %uint %_storage1 0
+        %458 = OpISub %uint %457 %uint_1
+        %459 = OpExtInst %uint %52 UMin %455 %458
+        %460 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %_storage1 %uint_0 %459 %uint_5
+        %463 = OpLoad %mat4v4float %460 None
+        %464 = OpLoad %v4float %_84_a None
+        %465 = OpMatrixTimesVector %v4float %463 %464
+        %466 = OpLoad %uint %shadingSsboIndex None
+        %467 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+        %468 = OpArrayLength %uint %_storage1 0
+        %469 = OpISub %uint %468 %uint_1
+        %470 = OpExtInst %uint %52 UMin %466 %469
+        %471 = OpAccessChain %_ptr_StorageBuffer_v4float %_storage1 %uint_0 %470 %uint_6
+        %474 = OpLoad %v4float %471 None
+        %475 = OpFAdd %v4float %465 %474
+               OpStore %_94_f %475
+        %477 = OpINotEqual %bool %_85_d %129
+               OpSelectionMerge %478 None
+               OpBranchConditional %477 %479 %480
+        %479 = OpLabel
+        %481 = OpAccessChain %_ptr_Function_float %_94_f %uint_2
         %482 = OpLoad %float %481 None
-        %483 = OpCompositeConstruct %v4float %480 %482
-  %_skTemp28 = OpExtInst %v4float %92 NClamp %483 %63 %317
+        %483 = OpFMul %float %float_2 %482
+        %484 = OpFSub %float %483 %float_1
+  %_skTemp24 = OpExtInst %float %52 FAbs %484
+        %486 = OpFSub %float %float_1 %_skTemp24
+        %487 = OpAccessChain %_ptr_Function_float %_94_f %uint_1
+        %488 = OpLoad %float %487 None
+      %_95_b = OpFMul %float %486 %488
+        %490 = OpLoad %v4float %_94_f None
+        %491 = OpVectorShuffle %v3float %490 %490 0 0 0
+      %_96_c = OpFAdd %v3float %491 %493
+  %_skTemp25 = OpExtInst %v3float %52 Fract %_96_c
+        %496 = OpVectorTimesScalar %v3float %_skTemp25 %float_6
+        %497 = OpCompositeConstruct %v3float %float_3 %float_3 %float_3
+        %499 = OpFSub %v3float %496 %497
+  %_skTemp26 = OpExtInst %v3float %52 FAbs %499
+        %501 = OpCompositeConstruct %v3float %float_1 %float_1 %float_1
+        %502 = OpFSub %v3float %_skTemp26 %501
+  %_skTemp27 = OpExtInst %v3float %52 NClamp %502 %504 %505
+        %506 = OpCompositeConstruct %v3float %float_0_5 %float_0_5 %float_0_5
+        %507 = OpFSub %v3float %_skTemp27 %506
+        %508 = OpVectorTimesScalar %v3float %507 %_95_b
+        %509 = OpAccessChain %_ptr_Function_float %_94_f %uint_2
+        %510 = OpLoad %float %509 None
+        %511 = OpCompositeConstruct %v3float %510 %510 %510
+        %512 = OpFAdd %v3float %508 %511
+        %513 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %514 = OpLoad %float %513 None
+        %515 = OpVectorTimesScalar %v3float %512 %514
+        %516 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %517 = OpLoad %float %516 None
+        %518 = OpCompositeConstruct %v4float %515 %517
+  %_skTemp28 = OpExtInst %v4float %52 NClamp %518 %74 %340
                OpStore %_94_f %_skTemp28 None
-               OpBranch %443
-        %445 = OpLabel
-        %485 = OpLoad %uint %shadingSsboIndex None
-        %486 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %485 %uint_8
-        %488 = OpLoad %int %486 None
-        %489 = OpINotEqual %bool %488 %108
-               OpSelectionMerge %490 None
-               OpBranchConditional %489 %491 %492
-        %491 = OpLabel
-        %493 = OpLoad %v4float %_94_f None
-  %_skTemp29 = OpExtInst %v4float %92 NClamp %493 %63 %317
+               OpBranch %478
+        %480 = OpLabel
+        %520 = OpLoad %uint %shadingSsboIndex None
+        %521 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage1 %uint_0
+        %522 = OpArrayLength %uint %_storage1 0
+        %523 = OpISub %uint %522 %uint_1
+        %524 = OpExtInst %uint %52 UMin %520 %523
+        %525 = OpAccessChain %_ptr_StorageBuffer_int %_storage1 %uint_0 %524 %uint_8
+        %527 = OpLoad %int %525 None
+        %528 = OpINotEqual %bool %527 %129
+               OpSelectionMerge %529 None
+               OpBranchConditional %528 %530 %531
+        %530 = OpLabel
+        %532 = OpLoad %v4float %_94_f None
+  %_skTemp29 = OpExtInst %v4float %52 NClamp %532 %74 %340
                OpStore %_94_f %_skTemp29 None
-               OpBranch %490
-        %492 = OpLabel
-        %495 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
-        %496 = OpLoad %float %495 None
-  %_skTemp30 = OpExtInst %float %92 NClamp %496 %float_0 %float_1
-        %498 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
-               OpStore %498 %_skTemp30 None
-               OpBranch %490
-        %490 = OpLabel
-        %499 = OpLoad %v4float %_94_f None
-        %500 = OpVectorShuffle %v3float %499 %499 0 1 2
-        %501 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
-        %502 = OpLoad %float %501 None
-        %503 = OpVectorTimesScalar %v3float %500 %502
-        %504 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
-        %505 = OpLoad %float %504 None
-        %506 = OpCompositeConstruct %v4float %503 %505
-               OpStore %_94_f %506 None
-               OpBranch %443
-        %443 = OpLabel
+               OpBranch %529
+        %531 = OpLabel
+        %534 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %535 = OpLoad %float %534 None
+  %_skTemp30 = OpExtInst %float %52 NClamp %535 %float_0 %float_1
+        %537 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+               OpStore %537 %_skTemp30 None
+               OpBranch %529
+        %529 = OpLabel
+        %538 = OpLoad %v4float %_94_f None
+        %539 = OpVectorShuffle %v3float %538 %538 0 1 2
+        %540 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %541 = OpLoad %float %540 None
+        %542 = OpVectorTimesScalar %v3float %539 %541
+        %543 = OpAccessChain %_ptr_Function_float %_94_f %uint_3
+        %544 = OpLoad %float %543 None
+        %545 = OpCompositeConstruct %v4float %542 %544
+               OpStore %_94_f %545 None
+               OpBranch %478
+        %478 = OpLabel
  %outColor_0 = OpLoad %v4float %_94_f None
-        %508 = OpAccessChain %_ptr_Function_v4float %_stageOut_root %uint_0
-               OpStore %508 %outColor_0 None
+        %547 = OpAccessChain %_ptr_Function_v4float %_stageOut_root %uint_0
+               OpStore %547 %outColor_0 None
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %FSOut None %511
+ %main_inner = OpFunction %FSOut None %550
  %_stageIn_0 = OpFunctionParameter %FSIn
-        %512 = OpLabel
-  %_stageOut = OpVariable %_ptr_Function_FSOut Function %514
-        %515 = OpFunctionCall %void %_skslMain %_stageIn_0 %_stageOut
-        %516 = OpLoad %FSOut %_stageOut None
-               OpReturnValue %516
+        %551 = OpLabel
+  %_stageOut = OpVariable %_ptr_Function_FSOut Function %553
+        %554 = OpFunctionCall %void %_skslMain %_stageIn_0 %_stageOut
+        %555 = OpLoad %FSOut %_stageOut None
+               OpReturnValue %555
                OpFunctionEnd
-       %main = OpFunction %void None %518
-        %519 = OpLabel
-        %520 = OpLoad %v2uint %main_loc0_Input None
-        %521 = OpLoad %v2float %main_loc1_Input None
-        %522 = OpCompositeConstruct %FSIn %520 %521
-        %523 = OpFunctionCall %FSOut %main_inner %522
-        %524 = OpCompositeExtract %v4float %523 0
-               OpStore %main_loc0_Output %524 None
+       %main = OpFunction %void None %557
+        %558 = OpLabel
+        %559 = OpLoad %v2uint %main_loc0_Input None
+        %560 = OpLoad %v2float %main_loc1_Input None
+        %561 = OpCompositeConstruct %FSIn %559 %560
+        %562 = OpFunctionCall %FSOut %main_inner %561
+        %563 = OpCompositeExtract %v4float %562 0
+               OpStore %main_loc0_Output %563 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/379684039-2.wgsl.expected.dxc.hlsl
index 7f222be..43b69ac 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.dxc.hlsl
@@ -4,13 +4,15 @@
 }
 
 static uint idx = 0u;
-
 ByteAddressBuffer _storage : register(t2);
 
 void main() {
   int2 vec = (0).xx;
   while (true) {
-    if ((vec.y >= asint(_storage.Load((((128u * idx) + 112u) + 4u))))) {
+    uint tint_symbol_1 = 0u;
+    _storage.GetDimensions(tint_symbol_1);
+    uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 128u);
+    if ((vec.y >= asint(_storage.Load((((128u * min(idx, (tint_symbol_2 - 1u))) + 112u) + 4u))))) {
       break;
     }
   }
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/379684039-2.wgsl.expected.fxc.hlsl
index 7f222be..43b69ac 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.fxc.hlsl
@@ -4,13 +4,15 @@
 }
 
 static uint idx = 0u;
-
 ByteAddressBuffer _storage : register(t2);
 
 void main() {
   int2 vec = (0).xx;
   while (true) {
-    if ((vec.y >= asint(_storage.Load((((128u * idx) + 112u) + 4u))))) {
+    uint tint_symbol_1 = 0u;
+    _storage.GetDimensions(tint_symbol_1);
+    uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 128u);
+    if ((vec.y >= asint(_storage.Load((((128u * min(idx, (tint_symbol_2 - 1u))) + 112u) + 4u))))) {
       break;
     }
   }
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.glsl b/test/tint/bug/tint/379684039-2.wgsl.expected.glsl
index ee77df7..14e0c09 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.glsl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.glsl
@@ -19,7 +19,8 @@
     while(true) {
       int v = vec.y;
       uint v_1 = idx;
-      if ((v >= _storage.fsUniformData[v_1].size.y)) {
+      uint v_2 = min(v_1, (uint(_storage.fsUniformData.length()) - 1u));
+      if ((v >= _storage.fsUniformData[v_2].size.y)) {
         break;
       }
       {
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.dxc.hlsl
index 6f322dc..3bc343a 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.dxc.hlsl
@@ -5,7 +5,9 @@
   int2 vec = (int(0)).xx;
   {
     while(true) {
-      if ((vec.y >= asint(_storage.Load((116u + (idx * 128u)))))) {
+      uint v = 0u;
+      _storage.GetDimensions(v);
+      if ((vec.y >= asint(_storage.Load((116u + (min(idx, ((v / 128u) - 1u)) * 128u)))))) {
         break;
       }
       {
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.fxc.hlsl
index 6f322dc..3bc343a 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.fxc.hlsl
@@ -5,7 +5,9 @@
   int2 vec = (int(0)).xx;
   {
     while(true) {
-      if ((vec.y >= asint(_storage.Load((116u + (idx * 128u)))))) {
+      uint v = 0u;
+      _storage.GetDimensions(v);
+      if ((vec.y >= asint(_storage.Load((116u + (min(idx, ((v / 128u) - 1u)) * 128u)))))) {
         break;
       }
       {
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.msl b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.msl
index ccd939c..971542e 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.ir.msl
@@ -25,13 +25,18 @@
 struct tint_module_vars_struct {
   thread uint* idx;
   const device FSUniforms* _storage;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   int2 tint_symbol_1 = int2(0);
   {
     while(true) {
-      if ((tint_symbol_1[1u] >= (*tint_module_vars._storage).fsUniformData[(*tint_module_vars.idx)].size[1u])) {
+      TINT_ISOLATE_UB(tint_volatile_false)
+      if ((tint_symbol_1[1u] >= (*tint_module_vars._storage).fsUniformData[min((*tint_module_vars.idx), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 128u) - 1u))].size[1u])) {
         break;
       }
       {
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.msl b/test/tint/bug/tint/379684039-2.wgsl.expected.msl
index f5b2c39..1b6f76d 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.msl
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.msl
@@ -14,10 +14,17 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint idx;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct FSUniformData {
   /* 0x0000 */ tint_array<float4, 7> k;
   /* 0x0070 */ int2 size;
@@ -28,10 +35,11 @@
   /* 0x0000 */ tint_array<FSUniformData, 1> fsUniformData;
 };
 
-void tint_symbol(thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_2) {
+void tint_symbol(thread tint_private_vars_struct* const tint_private_vars, const device FSUniforms* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
   int2 tint_symbol_1 = int2(0);
   while(true) {
-    if ((tint_symbol_1[1] >= (*(tint_symbol_2)).fsUniformData[(*(tint_private_vars)).idx].size[1])) {
+    TINT_ISOLATE_UB(tint_volatile_false);
+    if ((tint_symbol_1[1] >= (*(tint_symbol_2)).fsUniformData[min((*(tint_private_vars)).idx, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 128u) - 1u))].size[1])) {
       break;
     }
   }
diff --git a/test/tint/bug/tint/379684039-2.wgsl.expected.spvasm b/test/tint/bug/tint/379684039-2.wgsl.expected.spvasm
index 2c6614e..0dc33e8 100644
--- a/test/tint/bug/tint/379684039-2.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/379684039-2.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -47,8 +48,9 @@
          %22 = OpConstantNull %v2int
 %_ptr_Function_int = OpTypePointer Function %int
      %uint_1 = OpConstant %uint 1
-%_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
+%_ptr_StorageBuffer__runtimearr_FSUniformData = OpTypePointer StorageBuffer %_runtimearr_FSUniformData
      %uint_0 = OpConstant %uint 0
+%_ptr_StorageBuffer_v2int = OpTypePointer StorageBuffer %v2int
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
        %bool = OpTypeBool
        %main = OpFunction %void None %18
@@ -63,15 +65,19 @@
          %27 = OpAccessChain %_ptr_Function_int %vec %uint_1
          %30 = OpLoad %int %27 None
          %31 = OpLoad %uint %idx None
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2int %_storage %uint_0 %31 %uint_1
-         %35 = OpAccessChain %_ptr_StorageBuffer_int %32 %uint_1
-         %37 = OpLoad %int %35 None
-         %38 = OpSGreaterThanEqual %bool %30 %37
-               OpSelectionMerge %40 None
-               OpBranchConditional %38 %41 %40
-         %41 = OpLabel
+         %32 = OpAccessChain %_ptr_StorageBuffer__runtimearr_FSUniformData %_storage %uint_0
+         %35 = OpArrayLength %uint %_storage 0
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %38 UMin %31 %36
+         %39 = OpAccessChain %_ptr_StorageBuffer_v2int %_storage %uint_0 %37 %uint_1
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %39 %uint_1
+         %43 = OpLoad %int %41 None
+         %44 = OpSGreaterThanEqual %bool %30 %43
+               OpSelectionMerge %46 None
+               OpBranchConditional %44 %47 %46
+         %47 = OpLabel
                OpBranch %26
-         %40 = OpLabel
+         %46 = OpLabel
                OpBranch %24
          %24 = OpLabel
                OpBranch %25
@@ -79,6 +85,6 @@
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %18
-         %43 = OpLabel
+         %49 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/379684039.wgsl.expected.ir.msl b/test/tint/bug/tint/379684039.wgsl.expected.ir.msl
index a4b16aa..1c42658 100644
--- a/test/tint/bug/tint/379684039.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/379684039.wgsl.expected.ir.msl
@@ -5,10 +5,14 @@
   const device int2* _storage;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   int2 tint_symbol_1 = int2(0);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((tint_symbol_1[1u] >= (*tint_module_vars._storage)[1u])) {
         break;
       }
diff --git a/test/tint/bug/tint/379684039.wgsl.expected.msl b/test/tint/bug/tint/379684039.wgsl.expected.msl
index 62078ce..37a6707 100644
--- a/test/tint/bug/tint/379684039.wgsl.expected.msl
+++ b/test/tint/bug/tint/379684039.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(const device int2* const tint_symbol_2) {
   int2 tint_symbol_1 = int2(0);
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((tint_symbol_1[1] >= (*(tint_symbol_2))[1])) {
       break;
     }
diff --git a/test/tint/bug/tint/403.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/403.wgsl.expected.dxc.hlsl
index b7c9ef8..38bb71d 100644
--- a/test/tint/bug/tint/403.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/403.wgsl.expected.dxc.hlsl
@@ -35,7 +35,7 @@
   uint x_46 = gl_VertexIndex;
   float2 tint_symbol_3[3] = {float2(-1.0f, 1.0f), (1.0f).xx, (-1.0f).xx};
   indexable = tint_symbol_3;
-  float2 x_51 = indexable[x_46];
+  float2 x_51 = indexable[min(x_46, 2u)];
   float2 x_52 = mul(x_51, float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])));
   return float4(x_52.x, x_52.y, 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/403.wgsl.expected.fxc.hlsl
index b7c9ef8..38bb71d 100644
--- a/test/tint/bug/tint/403.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/403.wgsl.expected.fxc.hlsl
@@ -35,7 +35,7 @@
   uint x_46 = gl_VertexIndex;
   float2 tint_symbol_3[3] = {float2(-1.0f, 1.0f), (1.0f).xx, (-1.0f).xx};
   indexable = tint_symbol_3;
-  float2 x_51 = indexable[x_46];
+  float2 x_51 = indexable[min(x_46, 2u)];
   float2 x_52 = mul(x_51, float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])));
   return float4(x_52.x, x_52.y, 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.glsl b/test/tint/bug/tint/403.wgsl.expected.glsl
index 43b5f66..0289723 100644
--- a/test/tint/bug/tint/403.wgsl.expected.glsl
+++ b/test/tint/bug/tint/403.wgsl.expected.glsl
@@ -25,7 +25,7 @@
   mat2 x_28 = mat2(v_1.inner.transform2_col0, v_1.inner.transform2_col1);
   uint x_46 = tint_symbol_1;
   indexable = vec2[3](vec2(-1.0f, 1.0f), vec2(1.0f), vec2(-1.0f));
-  vec2 x_51 = indexable[x_46];
+  vec2 x_51 = indexable[min(x_46, 2u)];
   vec2 x_52 = (mat2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])) * x_51);
   return vec4(x_52[0u], x_52[1u], 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/403.wgsl.expected.ir.dxc.hlsl
index fcfba61..23734c0 100644
--- a/test/tint/bug/tint/403.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/403.wgsl.expected.ir.dxc.hlsl
@@ -34,7 +34,7 @@
   uint x_46 = gl_VertexIndex;
   float2 v_8[3] = {float2(-1.0f, 1.0f), (1.0f).xx, (-1.0f).xx};
   indexable = v_8;
-  float2 x_51 = indexable[x_46];
+  float2 x_51 = indexable[min(x_46, 2u)];
   float2 x_52 = mul(x_51, float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])));
   return float4(x_52.x, x_52.y, 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/403.wgsl.expected.ir.fxc.hlsl
index fcfba61..23734c0 100644
--- a/test/tint/bug/tint/403.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/403.wgsl.expected.ir.fxc.hlsl
@@ -34,7 +34,7 @@
   uint x_46 = gl_VertexIndex;
   float2 v_8[3] = {float2(-1.0f, 1.0f), (1.0f).xx, (-1.0f).xx};
   indexable = v_8;
-  float2 x_51 = indexable[x_46];
+  float2 x_51 = indexable[min(x_46, 2u)];
   float2 x_52 = mul(x_51, float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])));
   return float4(x_52.x, x_52.y, 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.ir.msl b/test/tint/bug/tint/403.wgsl.expected.ir.msl
index 612dc71..355675a 100644
--- a/test/tint/bug/tint/403.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/403.wgsl.expected.ir.msl
@@ -36,7 +36,7 @@
   float2x2 const x_28 = (*tint_module_vars.x_26).transform2;
   uint const x_46 = gl_VertexIndex;
   indexable = tint_array<float2, 3>{float2(-1.0f, 1.0f), float2(1.0f), float2(-1.0f)};
-  float2 const x_51 = indexable[x_46];
+  float2 const x_51 = indexable[min(x_46, 2u)];
   float2 const x_52 = (float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])) * x_51);
   return float4(x_52[0u], x_52[1u], 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.msl b/test/tint/bug/tint/403.wgsl.expected.msl
index 10c2d04..d203c64 100644
--- a/test/tint/bug/tint/403.wgsl.expected.msl
+++ b/test/tint/bug/tint/403.wgsl.expected.msl
@@ -33,7 +33,7 @@
   uint const x_46 = gl_VertexIndex;
   tint_array<float2, 3> const tint_symbol_2 = tint_array<float2, 3>{float2(-1.0f, 1.0f), float2(1.0f), float2(-1.0f)};
   indexable = tint_symbol_2;
-  float2 const x_51 = indexable[x_46];
+  float2 const x_51 = indexable[min(x_46, 2u)];
   float2 const x_52 = (float2x2((x_23[0u] + x_28[0u]), (x_23[1u] + x_28[1u])) * x_51);
   return float4(x_52[0], x_52[1], 0.0f, 1.0f);
 }
diff --git a/test/tint/bug/tint/403.wgsl.expected.spvasm b/test/tint/bug/tint/403.wgsl.expected.spvasm
index ba8982c..f3cb92c 100644
--- a/test/tint/bug/tint/403.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/403.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+         %49 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %main "main" %main_vertex_index_Input %main_position_Output %main___point_size_Output
                OpMemberName %vertexUniformBuffer1_std140 0 "transform1_col0"
@@ -79,10 +80,11 @@
          %46 = OpConstantComposite %v2float %float_1 %float_1
          %47 = OpConstantComposite %v2float %float_n1 %float_n1
          %42 = OpConstantComposite %_arr_v2float_uint_3 %43 %46 %47
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v2float = OpTypePointer Function %v2float
     %float_0 = OpConstant %float 0
        %void = OpTypeVoid
-         %65 = OpTypeFunction %void
+         %68 = OpTypeFunction %void
  %main_inner = OpFunction %v4float None %21
 %gl_VertexIndex = OpFunctionParameter %uint
          %22 = OpLabel
@@ -98,26 +100,27 @@
          %40 = OpLoad %v2float %39 None
        %x_28 = OpCompositeConstruct %mat2v2float %38 %40
                OpStore %indexable %42 None
-         %48 = OpAccessChain %_ptr_Function_v2float %indexable %gl_VertexIndex
-       %x_51 = OpLoad %v2float %48 None
-         %51 = OpCompositeExtract %v2float %x_23 0
-         %52 = OpCompositeExtract %v2float %x_28 0
-         %53 = OpFAdd %v2float %51 %52
-         %54 = OpCompositeExtract %v2float %x_23 1
-         %55 = OpCompositeExtract %v2float %x_28 1
+         %48 = OpExtInst %uint %49 UMin %gl_VertexIndex %uint_2
+         %51 = OpAccessChain %_ptr_Function_v2float %indexable %48
+       %x_51 = OpLoad %v2float %51 None
+         %54 = OpCompositeExtract %v2float %x_23 0
+         %55 = OpCompositeExtract %v2float %x_28 0
          %56 = OpFAdd %v2float %54 %55
-         %57 = OpCompositeConstruct %mat2v2float %53 %56
-       %x_52 = OpMatrixTimesVector %v2float %57 %x_51
-         %59 = OpCompositeExtract %float %x_52 0
-         %60 = OpCompositeExtract %float %x_52 1
-         %61 = OpCompositeConstruct %v4float %59 %60 %float_0 %float_1
-               OpReturnValue %61
+         %57 = OpCompositeExtract %v2float %x_23 1
+         %58 = OpCompositeExtract %v2float %x_28 1
+         %59 = OpFAdd %v2float %57 %58
+         %60 = OpCompositeConstruct %mat2v2float %56 %59
+       %x_52 = OpMatrixTimesVector %v2float %60 %x_51
+         %62 = OpCompositeExtract %float %x_52 0
+         %63 = OpCompositeExtract %float %x_52 1
+         %64 = OpCompositeConstruct %v4float %62 %63 %float_0 %float_1
+               OpReturnValue %64
                OpFunctionEnd
-       %main = OpFunction %void None %65
-         %66 = OpLabel
-         %67 = OpLoad %uint %main_vertex_index_Input None
-         %68 = OpFunctionCall %v4float %main_inner %67
-               OpStore %main_position_Output %68 None
+       %main = OpFunction %void None %68
+         %69 = OpLabel
+         %70 = OpLoad %uint %main_vertex_index_Input None
+         %71 = OpFunctionCall %v4float %main_inner %70
+               OpStore %main_position_Output %71 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/413.spvasm.expected.glsl b/test/tint/bug/tint/413.spvasm.expected.glsl
index 4c69515..7b2b347 100644
--- a/test/tint/bug/tint/413.spvasm.expected.glsl
+++ b/test/tint/bug/tint/413.spvasm.expected.glsl
@@ -1,11 +1,24 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+};
+
 layout(binding = 1, r32ui) uniform highp writeonly uimage2D Dst;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D Src;
 void main_1() {
   uvec4 srcValue = uvec4(0u);
-  ivec2 v = ivec2(ivec2(0));
-  srcValue = texelFetch(Src, v, int(0));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(0), v_1);
+  uvec2 v_3 = (uvec2(textureSize(Src, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(0)), v_3));
+  srcValue = texelFetch(Src, v_4, int(v_2));
   srcValue[0u] = (srcValue.x + 1u);
   uvec4 x_27 = srcValue;
   imageStore(Dst, ivec2(0), x_27);
diff --git a/test/tint/bug/tint/413.spvasm.expected.ir.dxc.hlsl b/test/tint/bug/tint/413.spvasm.expected.ir.dxc.hlsl
index 6a7ae80..feb2312 100644
--- a/test/tint/bug/tint/413.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/413.spvasm.expected.ir.dxc.hlsl
@@ -3,8 +3,14 @@
 RWTexture2D<uint4> Dst : register(u1);
 void main_1() {
   uint4 srcValue = (0u).xxxx;
-  int2 v = int2((int(0)).xx);
-  srcValue = uint4(Src.Load(int3(v, int(int(0)))));
+  uint3 v = (0u).xxx;
+  Src.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(0)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  Src.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(0)).xx), v_3));
+  srcValue = uint4(Src.Load(int3(v_4, int(v_1))));
   srcValue.x = (srcValue.x + 1u);
   uint4 x_27 = srcValue;
   Dst[(int(0)).xx] = x_27;
diff --git a/test/tint/bug/tint/413.spvasm.expected.ir.fxc.hlsl b/test/tint/bug/tint/413.spvasm.expected.ir.fxc.hlsl
index 6a7ae80..feb2312 100644
--- a/test/tint/bug/tint/413.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/413.spvasm.expected.ir.fxc.hlsl
@@ -3,8 +3,14 @@
 RWTexture2D<uint4> Dst : register(u1);
 void main_1() {
   uint4 srcValue = (0u).xxxx;
-  int2 v = int2((int(0)).xx);
-  srcValue = uint4(Src.Load(int3(v, int(int(0)))));
+  uint3 v = (0u).xxx;
+  Src.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(0)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  Src.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(0)).xx), v_3));
+  srcValue = uint4(Src.Load(int3(v_4, int(v_1))));
   srcValue.x = (srcValue.x + 1u);
   uint4 x_27 = srcValue;
   Dst[(int(0)).xx] = x_27;
diff --git a/test/tint/bug/tint/413.spvasm.expected.ir.msl b/test/tint/bug/tint/413.spvasm.expected.ir.msl
index 7b7a881..28ac06d 100644
--- a/test/tint/bug/tint/413.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/413.spvasm.expected.ir.msl
@@ -8,7 +8,9 @@
 
 void main_1(tint_module_vars_struct tint_module_vars) {
   uint4 srcValue = 0u;
-  srcValue = tint_module_vars.Src.read(uint2(int2(0)), 0);
+  uint const v = min(uint(0), (tint_module_vars.Src.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.Src.get_width(v), tint_module_vars.Src.get_height(v)) - uint2(1u));
+  srcValue = tint_module_vars.Src.read(min(uint2(int2(0)), v_1), v);
   srcValue[0u] = (srcValue[0u] + 1u);
   uint4 const x_27 = srcValue;
   tint_module_vars.Dst.write(x_27, uint2(int2(0)));
diff --git a/test/tint/bug/tint/413.spvasm.expected.msl b/test/tint/bug/tint/413.spvasm.expected.msl
index 6d4a8e3..fbacfa4 100644
--- a/test/tint/bug/tint/413.spvasm.expected.msl
+++ b/test/tint/bug/tint/413.spvasm.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 void main_1(texture2d<uint, access::sample> tint_symbol_1, texture2d<uint, access::write> tint_symbol_2) {
   uint4 srcValue = 0u;
-  srcValue = tint_symbol_1.read(uint2(int2(0)), 0);
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  srcValue = tint_symbol_1.read(uint2(tint_clamp(int2(0), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   srcValue[0] = (srcValue[0] + 1u);
   uint4 const x_27 = srcValue;
   tint_symbol_2.write(x_27, uint2(int2(0)));
diff --git a/test/tint/bug/tint/413.spvasm.expected.spvasm b/test/tint/bug/tint/413.spvasm.expected.spvasm
index a65e782..9cb6bf8 100644
--- a/test/tint/bug/tint/413.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/413.spvasm.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -30,31 +32,41 @@
      %v4uint = OpTypeVector %uint 4
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
          %15 = OpConstantNull %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v2int = OpTypeVector %int 2
-         %18 = OpConstantNull %v2int
       %int_0 = OpConstant %int 0
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantNull %v2int
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_0 = OpConstant %uint 0
-     %uint_1 = OpConstant %uint 1
      %main_1 = OpFunction %void None %10
          %11 = OpLabel
    %srcValue = OpVariable %_ptr_Function_v4uint Function %15
          %16 = OpLoad %3 %Src None
-         %17 = OpImageFetch %v4uint %16 %18 Lod %int_0
-               OpStore %srcValue %17 None
-         %22 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
-         %25 = OpLoad %uint %22 None
-         %26 = OpIAdd %uint %25 %uint_1
-         %28 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
-               OpStore %28 %26 None
+         %17 = OpImageQueryLevels %uint %16
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_0
+         %23 = OpExtInst %uint %24 UMin %20 %18
+         %25 = OpImageQuerySizeLod %v2uint %16 %23
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %24 UMin %29 %27
+         %33 = OpImageFetch %v4uint %16 %32 Lod %23
+               OpStore %srcValue %33 None
+         %34 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
+         %37 = OpLoad %uint %34 None
+         %38 = OpIAdd %uint %37 %uint_1
+         %39 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
+               OpStore %39 %38 None
        %x_27 = OpLoad %v4uint %srcValue None
-         %30 = OpLoad %7 %Dst None
-               OpImageWrite %30 %18 %x_27 None
+         %41 = OpLoad %7 %Dst None
+               OpImageWrite %41 %30 %x_27 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %10
-         %33 = OpLabel
-         %34 = OpFunctionCall %void %main_1
+         %44 = OpLabel
+         %45 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/453.wgsl.expected.glsl b/test/tint/bug/tint/453.wgsl.expected.glsl
index b115934..aac7f7a 100644
--- a/test/tint/bug/tint/453.wgsl.expected.glsl
+++ b/test/tint/bug/tint/453.wgsl.expected.glsl
@@ -1,12 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+};
+
 layout(binding = 1, r32ui) uniform highp writeonly uimage2D Dst;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D Src;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   uvec4 srcValue = uvec4(0u);
-  ivec2 v = ivec2(ivec2(0));
-  uvec4 x_22 = texelFetch(Src, v, int(0));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(0), v_1);
+  uvec2 v_3 = (uvec2(textureSize(Src, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(0)), v_3));
+  uvec4 x_22 = texelFetch(Src, v_4, int(v_2));
   srcValue = x_22;
   uint x_24 = srcValue.x;
   uint x_25 = (x_24 + 1u);
diff --git a/test/tint/bug/tint/453.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/453.wgsl.expected.ir.dxc.hlsl
index e450b7a..0a2e7da 100644
--- a/test/tint/bug/tint/453.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/453.wgsl.expected.ir.dxc.hlsl
@@ -4,8 +4,14 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 srcValue = (0u).xxxx;
-  int2 v = int2((int(0)).xx);
-  uint4 x_22 = uint4(Src.Load(int3(v, int(int(0)))));
+  uint3 v = (0u).xxx;
+  Src.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(0)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  Src.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(0)).xx), v_3));
+  uint4 x_22 = uint4(Src.Load(int3(v_4, int(v_1))));
   srcValue = x_22;
   uint x_24 = srcValue.x;
   uint x_25 = (x_24 + 1u);
diff --git a/test/tint/bug/tint/453.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/453.wgsl.expected.ir.fxc.hlsl
index e450b7a..0a2e7da 100644
--- a/test/tint/bug/tint/453.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/453.wgsl.expected.ir.fxc.hlsl
@@ -4,8 +4,14 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 srcValue = (0u).xxxx;
-  int2 v = int2((int(0)).xx);
-  uint4 x_22 = uint4(Src.Load(int3(v, int(int(0)))));
+  uint3 v = (0u).xxx;
+  Src.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(0)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  Src.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(0)).xx), v_3));
+  uint4 x_22 = uint4(Src.Load(int3(v_4, int(v_1))));
   srcValue = x_22;
   uint x_24 = srcValue.x;
   uint x_25 = (x_24 + 1u);
diff --git a/test/tint/bug/tint/453.wgsl.expected.ir.msl b/test/tint/bug/tint/453.wgsl.expected.ir.msl
index 575b7de..ea9b4f4 100644
--- a/test/tint/bug/tint/453.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/453.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 kernel void tint_symbol(texture2d<uint, access::sample> Src [[texture(0)]], texture2d<uint, access::write> Dst [[texture(1)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.Src=Src, .Dst=Dst};
   uint4 srcValue = 0u;
-  uint4 const x_22 = tint_module_vars.Src.read(uint2(int2(0)), 0);
+  uint const v = min(uint(0), (tint_module_vars.Src.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.Src.get_width(v), tint_module_vars.Src.get_height(v)) - uint2(1u));
+  uint4 const x_22 = tint_module_vars.Src.read(min(uint2(int2(0)), v_1), v);
   srcValue = x_22;
   uint const x_24 = srcValue[0u];
   uint const x_25 = (x_24 + 1u);
diff --git a/test/tint/bug/tint/453.wgsl.expected.msl b/test/tint/bug/tint/453.wgsl.expected.msl
index 9cf9309..77637f1 100644
--- a/test/tint/bug/tint/453.wgsl.expected.msl
+++ b/test/tint/bug/tint/453.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 kernel void tint_symbol(texture2d<uint, access::sample> tint_symbol_1 [[texture(0)]], texture2d<uint, access::write> tint_symbol_2 [[texture(1)]]) {
   uint4 srcValue = 0u;
-  uint4 const x_22 = tint_symbol_1.read(uint2(int2(0)), 0);
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 const x_22 = tint_symbol_1.read(uint2(tint_clamp(int2(0), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   srcValue = x_22;
   uint const x_24 = srcValue[0];
   uint const x_25 = (x_24 + 1u);
diff --git a/test/tint/bug/tint/453.wgsl.expected.spvasm b/test/tint/bug/tint/453.wgsl.expected.spvasm
index 915177d..56b9f7d 100644
--- a/test/tint/bug/tint/453.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/453.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -32,25 +34,35 @@
      %v4uint = OpTypeVector %uint 4
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
          %15 = OpConstantNull %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v2int = OpTypeVector %int 2
-         %18 = OpConstantNull %v2int
       %int_0 = OpConstant %int 0
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantNull %v2int
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_0 = OpConstant %uint 0
-     %uint_1 = OpConstant %uint 1
        %main = OpFunction %void None %10
          %11 = OpLabel
    %srcValue = OpVariable %_ptr_Function_v4uint Function %15
          %16 = OpLoad %3 %Src None
-       %x_22 = OpImageFetch %v4uint %16 %18 Lod %int_0
+         %17 = OpImageQueryLevels %uint %16
+         %18 = OpISub %uint %17 %uint_1
+         %20 = OpBitcast %uint %int_0
+         %23 = OpExtInst %uint %24 UMin %20 %18
+         %25 = OpImageQuerySizeLod %v2uint %16 %23
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %24 UMin %29 %27
+       %x_22 = OpImageFetch %v4uint %16 %32 Lod %23
                OpStore %srcValue %x_22 None
-         %22 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
-       %x_24 = OpLoad %uint %22 None
+         %34 = OpAccessChain %_ptr_Function_uint %srcValue %uint_0
+       %x_24 = OpLoad %uint %34 None
        %x_25 = OpIAdd %uint %x_24 %uint_1
        %x_27 = OpLoad %v4uint %srcValue None
-         %29 = OpLoad %7 %Dst None
-         %30 = OpVectorShuffle %v4uint %x_27 %x_27 0 0 0 0
-               OpImageWrite %29 %18 %30 None
+         %40 = OpLoad %7 %Dst None
+         %41 = OpVectorShuffle %v4uint %x_27 %x_27 0 0 0 0
+               OpImageWrite %40 %30 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/534.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/534.wgsl.expected.dxc.hlsl
index 922786e..2ca61e1 100644
--- a/test/tint/bug/tint/534.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/534.wgsl.expected.dxc.hlsl
@@ -38,19 +38,25 @@
   {
     for(uint i = 0u; (i < uniforms[0].w); i = (i + 1u)) {
       uint tint_symbol_1 = i;
-      set_vector_element(srcColorBits, tint_symbol_1, ConvertToFp16FloatValue(srcColor[i]));
+      set_vector_element(srcColorBits, min(tint_symbol_1, 3u), ConvertToFp16FloatValue(srcColor[min(i, 3u)]));
       bool tint_tmp_1 = success;
       if (tint_tmp_1) {
-        tint_tmp_1 = (srcColorBits[i] == dstColorBits[i]);
+        tint_tmp_1 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       }
       success = (tint_tmp_1);
     }
   }
   uint outputIndex = ((GlobalInvocationID.y * uint(size.x)) + GlobalInvocationID.x);
   if (success) {
-    output.Store((4u * outputIndex), asuint(1u));
+    uint tint_symbol_5 = 0u;
+    output.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_6 - 1u))), asuint(1u));
   } else {
-    output.Store((4u * outputIndex), asuint(0u));
+    uint tint_symbol_7 = 0u;
+    output.GetDimensions(tint_symbol_7);
+    uint tint_symbol_8 = ((tint_symbol_7 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_8 - 1u))), asuint(0u));
   }
 }
 
diff --git a/test/tint/bug/tint/534.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/534.wgsl.expected.fxc.hlsl
index 922786e..2ca61e1 100644
--- a/test/tint/bug/tint/534.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/534.wgsl.expected.fxc.hlsl
@@ -38,19 +38,25 @@
   {
     for(uint i = 0u; (i < uniforms[0].w); i = (i + 1u)) {
       uint tint_symbol_1 = i;
-      set_vector_element(srcColorBits, tint_symbol_1, ConvertToFp16FloatValue(srcColor[i]));
+      set_vector_element(srcColorBits, min(tint_symbol_1, 3u), ConvertToFp16FloatValue(srcColor[min(i, 3u)]));
       bool tint_tmp_1 = success;
       if (tint_tmp_1) {
-        tint_tmp_1 = (srcColorBits[i] == dstColorBits[i]);
+        tint_tmp_1 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       }
       success = (tint_tmp_1);
     }
   }
   uint outputIndex = ((GlobalInvocationID.y * uint(size.x)) + GlobalInvocationID.x);
   if (success) {
-    output.Store((4u * outputIndex), asuint(1u));
+    uint tint_symbol_5 = 0u;
+    output.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_6 - 1u))), asuint(1u));
   } else {
-    output.Store((4u * outputIndex), asuint(0u));
+    uint tint_symbol_7 = 0u;
+    output.GetDimensions(tint_symbol_7);
+    uint tint_symbol_8 = ((tint_symbol_7 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_8 - 1u))), asuint(0u));
   }
 }
 
diff --git a/test/tint/bug/tint/534.wgsl.expected.glsl b/test/tint/bug/tint/534.wgsl.expected.glsl
index e7a81fb..7d95ee6 100644
--- a/test/tint/bug/tint/534.wgsl.expected.glsl
+++ b/test/tint/bug/tint/534.wgsl.expected.glsl
@@ -8,6 +8,11 @@
   uint channelCount;
 };
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+};
+
 layout(binding = 2, std430)
 buffer OutputBuf_1_ssbo {
   uint result[];
@@ -16,6 +21,10 @@
 uniform uniforms_block_1_ubo {
   Uniforms inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_2_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D src;
 uniform highp sampler2D dst;
 uint ConvertToFp16FloatValue(float fp32) {
@@ -31,10 +40,16 @@
   if ((v.inner.dstTextureFlipY == 1u)) {
     srcTexCoord[1u] = ((size.y - dstTexCoord.y) - 1u);
   }
-  ivec2 v_1 = ivec2(srcTexCoord);
-  vec4 srcColor = texelFetch(src, v_1, int(0));
-  ivec2 v_2 = ivec2(dstTexCoord);
-  vec4 dstColor = texelFetch(dst, v_2, int(0));
+  uvec2 v_2 = srcTexCoord;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(0), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(src, int(v_4))) - uvec2(1u))));
+  vec4 srcColor = texelFetch(src, v_5, int(v_4));
+  uvec2 v_6 = dstTexCoord;
+  uint v_7 = (v_1.inner.tint_builtin_value_1 - 1u);
+  uint v_8 = min(uint(0), v_7);
+  ivec2 v_9 = ivec2(min(v_6, (uvec2(textureSize(dst, int(v_8))) - uvec2(1u))));
+  vec4 dstColor = texelFetch(dst, v_9, int(v_8));
   bool success = true;
   uvec4 srcColorBits = uvec4(0u);
   uvec4 dstColorBits = tint_v4f32_to_v4u32(dstColor);
@@ -45,15 +60,15 @@
       } else {
         break;
       }
-      uint v_3 = i;
-      srcColorBits[v_3] = ConvertToFp16FloatValue(srcColor[i]);
-      bool v_4 = false;
+      uint v_10 = i;
+      srcColorBits[min(v_10, 3u)] = ConvertToFp16FloatValue(srcColor[min(i, 3u)]);
+      bool v_11 = false;
       if (success) {
-        v_4 = (srcColorBits[i] == dstColorBits[i]);
+        v_11 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       } else {
-        v_4 = false;
+        v_11 = false;
       }
-      success = v_4;
+      success = v_11;
       {
         i = (i + 1u);
       }
@@ -62,11 +77,13 @@
   }
   uint outputIndex = ((GlobalInvocationID[1u] * uint(size.x)) + GlobalInvocationID[0u]);
   if (success) {
-    uint v_5 = outputIndex;
-    tint_symbol.result[v_5] = 1u;
+    uint v_12 = outputIndex;
+    uint v_13 = min(v_12, (uint(tint_symbol.result.length()) - 1u));
+    tint_symbol.result[v_13] = 1u;
   } else {
-    uint v_6 = outputIndex;
-    tint_symbol.result[v_6] = 0u;
+    uint v_14 = outputIndex;
+    uint v_15 = min(v_14, (uint(tint_symbol.result.length()) - 1u));
+    tint_symbol.result[v_15] = 0u;
   }
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/tint/534.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/534.wgsl.expected.ir.dxc.hlsl
index d244ca6..a9adb48 100644
--- a/test/tint/bug/tint/534.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/534.wgsl.expected.ir.dxc.hlsl
@@ -26,10 +26,22 @@
   if ((uniforms[0u].x == 1u)) {
     srcTexCoord.y = ((size.y - dstTexCoord.y) - 1u);
   }
-  int2 v_1 = int2(srcTexCoord);
-  float4 srcColor = float4(src.Load(int3(v_1, int(int(0)))));
-  int2 v_2 = int2(dstTexCoord);
-  float4 dstColor = float4(tint_symbol.Load(int3(v_2, int(int(0)))));
+  uint2 v_1 = srcTexCoord;
+  uint3 v_2 = (0u).xxx;
+  src.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(int(0)), (v_2.z - 1u));
+  uint3 v_4 = (0u).xxx;
+  src.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z);
+  int2 v_5 = int2(min(v_1, (v_4.xy - (1u).xx)));
+  float4 srcColor = float4(src.Load(int3(v_5, int(v_3))));
+  uint2 v_6 = dstTexCoord;
+  uint3 v_7 = (0u).xxx;
+  tint_symbol.GetDimensions(0u, v_7.x, v_7.y, v_7.z);
+  uint v_8 = min(uint(int(0)), (v_7.z - 1u));
+  uint3 v_9 = (0u).xxx;
+  tint_symbol.GetDimensions(uint(v_8), v_9.x, v_9.y, v_9.z);
+  int2 v_10 = int2(min(v_6, (v_9.xy - (1u).xx)));
+  float4 dstColor = float4(tint_symbol.Load(int3(v_10, int(v_8))));
   bool success = true;
   uint4 srcColorBits = (0u).xxxx;
   uint4 dstColorBits = tint_v4f32_to_v4u32(dstColor);
@@ -40,15 +52,15 @@
       } else {
         break;
       }
-      uint v_3 = i;
-      srcColorBits[v_3] = ConvertToFp16FloatValue(srcColor[i]);
-      bool v_4 = false;
+      uint v_11 = i;
+      srcColorBits[min(v_11, 3u)] = ConvertToFp16FloatValue(srcColor[min(i, 3u)]);
+      bool v_12 = false;
       if (success) {
-        v_4 = (srcColorBits[i] == dstColorBits[i]);
+        v_12 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       } else {
-        v_4 = false;
+        v_12 = false;
       }
-      success = v_4;
+      success = v_12;
       {
         i = (i + 1u);
       }
@@ -57,9 +69,13 @@
   }
   uint outputIndex = ((GlobalInvocationID.y * uint(size.x)) + GlobalInvocationID.x);
   if (success) {
-    output.Store((0u + (outputIndex * 4u)), 1u);
+    uint v_13 = 0u;
+    output.GetDimensions(v_13);
+    output.Store((0u + (min(outputIndex, ((v_13 / 4u) - 1u)) * 4u)), 1u);
   } else {
-    output.Store((0u + (outputIndex * 4u)), 0u);
+    uint v_14 = 0u;
+    output.GetDimensions(v_14);
+    output.Store((0u + (min(outputIndex, ((v_14 / 4u) - 1u)) * 4u)), 0u);
   }
 }
 
diff --git a/test/tint/bug/tint/534.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/534.wgsl.expected.ir.fxc.hlsl
index 66b230b..3fa8342 100644
--- a/test/tint/bug/tint/534.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/534.wgsl.expected.ir.fxc.hlsl
@@ -26,10 +26,22 @@
   if ((uniforms[0u].x == 1u)) {
     srcTexCoord.y = ((size.y - dstTexCoord.y) - 1u);
   }
-  int2 v_1 = int2(srcTexCoord);
-  float4 srcColor = float4(src.Load(int3(v_1, int(int(0)))));
-  int2 v_2 = int2(dstTexCoord);
-  float4 dstColor = float4(tint_symbol.Load(int3(v_2, int(int(0)))));
+  uint2 v_1 = srcTexCoord;
+  uint3 v_2 = (0u).xxx;
+  src.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(int(0)), (v_2.z - 1u));
+  uint3 v_4 = (0u).xxx;
+  src.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z);
+  int2 v_5 = int2(min(v_1, (v_4.xy - (1u).xx)));
+  float4 srcColor = float4(src.Load(int3(v_5, int(v_3))));
+  uint2 v_6 = dstTexCoord;
+  uint3 v_7 = (0u).xxx;
+  tint_symbol.GetDimensions(0u, v_7.x, v_7.y, v_7.z);
+  uint v_8 = min(uint(int(0)), (v_7.z - 1u));
+  uint3 v_9 = (0u).xxx;
+  tint_symbol.GetDimensions(uint(v_8), v_9.x, v_9.y, v_9.z);
+  int2 v_10 = int2(min(v_6, (v_9.xy - (1u).xx)));
+  float4 dstColor = float4(tint_symbol.Load(int3(v_10, int(v_8))));
   bool success = true;
   uint4 srcColorBits = (0u).xxxx;
   uint4 dstColorBits = tint_v4f32_to_v4u32(dstColor);
@@ -40,17 +52,17 @@
       } else {
         break;
       }
-      uint v_3 = i;
-      uint v_4 = ConvertToFp16FloatValue(srcColor[i]);
-      uint4 v_5 = srcColorBits;
-      srcColorBits = (((v_3.xxxx == uint4(int(0), int(1), int(2), int(3)))) ? (v_4.xxxx) : (v_5));
-      bool v_6 = false;
+      uint v_11 = i;
+      uint v_12 = ConvertToFp16FloatValue(srcColor[min(i, 3u)]);
+      uint4 v_13 = srcColorBits;
+      srcColorBits = (((v_11.xxxx == uint4(int(0), int(1), int(2), int(3)))) ? (v_12.xxxx) : (v_13));
+      bool v_14 = false;
       if (success) {
-        v_6 = (srcColorBits[i] == dstColorBits[i]);
+        v_14 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       } else {
-        v_6 = false;
+        v_14 = false;
       }
-      success = v_6;
+      success = v_14;
       {
         i = (i + 1u);
       }
@@ -59,9 +71,13 @@
   }
   uint outputIndex = ((GlobalInvocationID.y * uint(size.x)) + GlobalInvocationID.x);
   if (success) {
-    output.Store((0u + (outputIndex * 4u)), 1u);
+    uint v_15 = 0u;
+    output.GetDimensions(v_15);
+    output.Store((0u + (min(outputIndex, ((v_15 / 4u) - 1u)) * 4u)), 1u);
   } else {
-    output.Store((0u + (outputIndex * 4u)), 0u);
+    uint v_16 = 0u;
+    output.GetDimensions(v_16);
+    output.Store((0u + (min(outputIndex, ((v_16 / 4u) - 1u)) * 4u)), 0u);
   }
 }
 
diff --git a/test/tint/bug/tint/534.wgsl.expected.ir.msl b/test/tint/bug/tint/534.wgsl.expected.ir.msl
index 73504f5..9dff06c 100644
--- a/test/tint/bug/tint/534.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/534.wgsl.expected.ir.msl
@@ -29,8 +29,12 @@
   texture2d<float, access::sample> dst;
   device OutputBuf* output;
   const constant Uniforms* uniforms;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 uint ConvertToFp16FloatValue(float fp32) {
   return 1u;
 }
@@ -46,27 +50,32 @@
   if (((*tint_module_vars.uniforms).dstTextureFlipY == 1u)) {
     srcTexCoord[1u] = ((size[1u] - dstTexCoord[1u]) - 1u);
   }
-  float4 srcColor = tint_module_vars.src.read(srcTexCoord, 0);
-  float4 dstColor = tint_module_vars.dst.read(dstTexCoord, 0);
+  uint2 const v = srcTexCoord;
+  uint const v_1 = min(uint(0), (tint_module_vars.src.get_num_mip_levels() - 1u));
+  float4 srcColor = tint_module_vars.src.read(min(v, (uint2(tint_module_vars.src.get_width(v_1), tint_module_vars.src.get_height(v_1)) - uint2(1u))), v_1);
+  uint2 const v_2 = dstTexCoord;
+  uint const v_3 = min(uint(0), (tint_module_vars.dst.get_num_mip_levels() - 1u));
+  float4 dstColor = tint_module_vars.dst.read(min(v_2, (uint2(tint_module_vars.dst.get_width(v_3), tint_module_vars.dst.get_height(v_3)) - uint2(1u))), v_3);
   bool success = true;
   uint4 srcColorBits = 0u;
   uint4 dstColorBits = tint_v4f32_to_v4u32(dstColor);
   {
     uint i = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < (*tint_module_vars.uniforms).channelCount)) {
       } else {
         break;
       }
-      uint const v = i;
-      srcColorBits[v] = ConvertToFp16FloatValue(srcColor[i]);
-      bool v_1 = false;
+      uint const v_4 = i;
+      srcColorBits[min(v_4, 3u)] = ConvertToFp16FloatValue(srcColor[min(i, 3u)]);
+      bool v_5 = false;
       if (success) {
-        v_1 = (srcColorBits[i] == dstColorBits[i]);
+        v_5 = (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]);
       } else {
-        v_1 = false;
+        v_5 = false;
       }
-      success = v_1;
+      success = v_5;
       {
         i = (i + 1u);
       }
@@ -75,13 +84,13 @@
   }
   uint outputIndex = ((GlobalInvocationID[1u] * uint(size[0u])) + GlobalInvocationID[0u]);
   if (success) {
-    (*tint_module_vars.output).result[outputIndex] = 1u;
+    (*tint_module_vars.output).result[min(outputIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))] = 1u;
   } else {
-    (*tint_module_vars.output).result[outputIndex] = 0u;
+    (*tint_module_vars.output).result[min(outputIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))] = 0u;
   }
 }
 
-kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d<float, access::sample> src [[texture(0)]], texture2d<float, access::sample> dst [[texture(1)]], device OutputBuf* output [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src=src, .dst=dst, .output=output, .uniforms=uniforms};
+kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d<float, access::sample> src [[texture(0)]], texture2d<float, access::sample> dst [[texture(1)]], device OutputBuf* output [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src=src, .dst=dst, .output=output, .uniforms=uniforms, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/534.wgsl.expected.msl b/test/tint/bug/tint/534.wgsl.expected.msl
index fe81248..ff2e01d 100644
--- a/test/tint/bug/tint/534.wgsl.expected.msl
+++ b/test/tint/bug/tint/534.wgsl.expected.msl
@@ -14,6 +14,13 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 uint4 tint_ftou(float4 v) {
   return select(uint4(4294967295u), select(uint4(v), uint4(0u), (v < float4(0.0f))), (v <= float4(4294967040.0f)));
 }
@@ -33,33 +40,36 @@
   return 1u;
 }
 
-void tint_symbol_inner(uint3 GlobalInvocationID, texture2d<float, access::sample> tint_symbol_2, const constant Uniforms* const tint_symbol_3, texture2d<float, access::sample> tint_symbol_4, device OutputBuf* const tint_symbol_5) {
+void tint_symbol_inner(uint3 GlobalInvocationID, texture2d<float, access::sample> tint_symbol_2, const constant Uniforms* const tint_symbol_3, texture2d<float, access::sample> tint_symbol_4, device OutputBuf* const tint_symbol_5, const constant TintArrayLengths* const tint_symbol_6) {
   uint2 size = uint2(tint_symbol_2.get_width(), tint_symbol_2.get_height());
   uint2 dstTexCoord = GlobalInvocationID.xy;
   uint2 srcTexCoord = dstTexCoord;
   if (((*(tint_symbol_3)).dstTextureFlipY == 1u)) {
     srcTexCoord[1] = ((size[1] - dstTexCoord[1]) - 1u);
   }
-  float4 srcColor = tint_symbol_2.read(uint2(srcTexCoord), 0);
-  float4 dstColor = tint_symbol_4.read(uint2(dstTexCoord), 0);
+  uint const level_idx = min(0u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  float4 srcColor = tint_symbol_2.read(uint2(min(srcTexCoord, (uint2(tint_symbol_2.get_width(level_idx), tint_symbol_2.get_height(level_idx)) - uint2(1u)))), level_idx);
+  uint const level_idx_1 = min(0u, (tint_symbol_4.get_num_mip_levels() - 1u));
+  float4 dstColor = tint_symbol_4.read(uint2(min(dstTexCoord, (uint2(tint_symbol_4.get_width(level_idx_1), tint_symbol_4.get_height(level_idx_1)) - uint2(1u)))), level_idx_1);
   bool success = true;
   uint4 srcColorBits = 0u;
   uint4 dstColorBits = tint_ftou(dstColor);
   for(uint i = 0u; (i < (*(tint_symbol_3)).channelCount); i = (i + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const tint_symbol_1 = i;
-    srcColorBits[tint_symbol_1] = ConvertToFp16FloatValue(srcColor[i]);
-    success = (success && (srcColorBits[i] == dstColorBits[i]));
+    srcColorBits[min(tint_symbol_1, 3u)] = ConvertToFp16FloatValue(srcColor[min(i, 3u)]);
+    success = (success && (srcColorBits[min(i, 3u)] == dstColorBits[min(i, 3u)]));
   }
   uint outputIndex = ((GlobalInvocationID[1] * uint(size[0])) + GlobalInvocationID[0]);
   if (success) {
-    (*(tint_symbol_5)).result[outputIndex] = 1u;
+    (*(tint_symbol_5)).result[min(outputIndex, ((((*(tint_symbol_6)).array_lengths[0u][1u] - 0u) / 4u) - 1u))] = 1u;
   } else {
-    (*(tint_symbol_5)).result[outputIndex] = 0u;
+    (*(tint_symbol_5)).result[min(outputIndex, ((((*(tint_symbol_6)).array_lengths[0u][1u] - 0u) / 4u) - 1u))] = 0u;
   }
 }
 
-kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_6 [[texture(0)]], const constant Uniforms* tint_symbol_7 [[buffer(0)]], texture2d<float, access::sample> tint_symbol_8 [[texture(1)]], device OutputBuf* tint_symbol_9 [[buffer(1)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  tint_symbol_inner(GlobalInvocationID, tint_symbol_6, tint_symbol_7, tint_symbol_8, tint_symbol_9);
+kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_7 [[texture(0)]], const constant Uniforms* tint_symbol_8 [[buffer(0)]], texture2d<float, access::sample> tint_symbol_9 [[texture(1)]], device OutputBuf* tint_symbol_10 [[buffer(1)]], const constant TintArrayLengths* tint_symbol_11 [[buffer(30)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  tint_symbol_inner(GlobalInvocationID, tint_symbol_7, tint_symbol_8, tint_symbol_9, tint_symbol_10, tint_symbol_11);
   return;
 }
 
diff --git a/test/tint/bug/tint/534.wgsl.expected.spvasm b/test/tint/bug/tint/534.wgsl.expected.spvasm
index 88c5556..7b27ee6 100644
--- a/test/tint/bug/tint/534.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/534.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 146
+; Bound: 175
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %61 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_global_invocation_id_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -85,27 +86,29 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
        %bool = OpTypeBool
 %_ptr_Function_uint = OpTypePointer Function %uint
-    %v4float = OpTypeVector %float 4
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+         %64 = OpConstantComposite %v2uint %uint_1 %uint_1
+    %v4float = OpTypeVector %float 4
 %_ptr_Function_v4float = OpTypePointer Function %v4float
 %_ptr_Function_bool = OpTypePointer Function %bool
        %true = OpConstantTrue %bool
      %v4uint = OpTypeVector %uint 4
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
-         %71 = OpConstantNull %v4uint
+         %87 = OpConstantNull %v4uint
      %uint_3 = OpConstant %uint 3
 %_ptr_Function_float = OpTypePointer Function %float
       %false = OpConstantFalse %bool
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-        %128 = OpTypeFunction %v4uint %v4float
-        %132 = OpConstantNull %v4float
+        %157 = OpTypeFunction %v4uint %v4float
+        %161 = OpConstantNull %v4float
      %v4bool = OpTypeVector %bool 4
 %float_4_29496704e_09 = OpConstant %float 4.29496704e+09
-        %136 = OpConstantComposite %v4float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
+        %165 = OpConstantComposite %v4float %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09 %float_4_29496704e_09
 %uint_4294967295 = OpConstant %uint 4294967295
-        %139 = OpConstantComposite %v4uint %uint_4294967295 %uint_4294967295 %uint_4294967295 %uint_4294967295
-        %142 = OpTypeFunction %void
+        %168 = OpConstantComposite %v4uint %uint_4294967295 %uint_4294967295 %uint_4294967295 %uint_4294967295
+        %171 = OpTypeFunction %void
 %ConvertToFp16FloatValue = OpFunction %uint None %20
        %fp32 = OpFunctionParameter %float
          %21 = OpLabel
@@ -120,7 +123,7 @@
    %srcColor = OpVariable %_ptr_Function_v4float Function
    %dstColor = OpVariable %_ptr_Function_v4float Function
     %success = OpVariable %_ptr_Function_bool Function
-%srcColorBits = OpVariable %_ptr_Function_v4uint Function %71
+%srcColorBits = OpVariable %_ptr_Function_v4uint Function %87
 %dstColorBits = OpVariable %_ptr_Function_v4uint Function
           %i = OpVariable %_ptr_Function_uint Function
 %outputIndex = OpVariable %_ptr_Function_uint Function
@@ -149,100 +152,126 @@
          %43 = OpLabel
          %53 = OpLoad %3 %src None
          %54 = OpLoad %v2uint %srcTexCoord None
-         %55 = OpImageFetch %v4float %53 %54 Lod %int_0
-               OpStore %srcColor %55
-         %61 = OpLoad %3 %dst None
-         %62 = OpLoad %v2uint %dstTexCoord None
-         %63 = OpImageFetch %v4float %61 %62 Lod %int_0
-               OpStore %dstColor %63
+         %55 = OpImageQueryLevels %uint %53
+         %56 = OpISub %uint %55 %uint_1
+         %57 = OpBitcast %uint %int_0
+         %60 = OpExtInst %uint %61 UMin %57 %56
+         %62 = OpImageQuerySizeLod %v2uint %53 %60
+         %63 = OpISub %v2uint %62 %64
+         %65 = OpExtInst %v2uint %61 UMin %54 %63
+         %66 = OpImageFetch %v4float %53 %65 Lod %60
+               OpStore %srcColor %66
+         %70 = OpLoad %3 %dst None
+         %71 = OpLoad %v2uint %dstTexCoord None
+         %72 = OpImageQueryLevels %uint %70
+         %73 = OpISub %uint %72 %uint_1
+         %74 = OpBitcast %uint %int_0
+         %75 = OpExtInst %uint %61 UMin %74 %73
+         %76 = OpImageQuerySizeLod %v2uint %70 %75
+         %77 = OpISub %v2uint %76 %64
+         %78 = OpExtInst %v2uint %61 UMin %71 %77
+         %79 = OpImageFetch %v4float %70 %78 Lod %75
+               OpStore %dstColor %79
                OpStore %success %true
-         %72 = OpLoad %v4float %dstColor None
-         %73 = OpFunctionCall %v4uint %tint_v4f32_to_v4u32 %72
-               OpStore %dstColorBits %73
-               OpBranch %76
-         %76 = OpLabel
+         %88 = OpLoad %v4float %dstColor None
+         %89 = OpFunctionCall %v4uint %tint_v4f32_to_v4u32 %88
+               OpStore %dstColorBits %89
+               OpBranch %92
+         %92 = OpLabel
                OpStore %i %uint_0
-               OpBranch %79
-         %79 = OpLabel
-               OpLoopMerge %80 %78 None
-               OpBranch %77
-         %77 = OpLabel
-         %82 = OpLoad %uint %i None
-         %83 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_3
-         %85 = OpLoad %uint %83 None
-         %86 = OpULessThan %bool %82 %85
-               OpSelectionMerge %87 None
-               OpBranchConditional %86 %87 %88
-         %88 = OpLabel
-               OpBranch %80
-         %87 = OpLabel
-         %89 = OpLoad %uint %i None
-         %90 = OpLoad %uint %i None
-         %91 = OpAccessChain %_ptr_Function_float %srcColor %90
-         %93 = OpLoad %float %91 None
-         %94 = OpFunctionCall %uint %ConvertToFp16FloatValue %93
-         %95 = OpAccessChain %_ptr_Function_uint %srcColorBits %89
-               OpStore %95 %94 None
-         %96 = OpLoad %bool %success None
-               OpSelectionMerge %97 None
-               OpBranchConditional %96 %98 %99
-         %98 = OpLabel
-        %100 = OpLoad %uint %i None
-        %101 = OpAccessChain %_ptr_Function_uint %srcColorBits %100
-        %102 = OpLoad %uint %101 None
-        %103 = OpLoad %uint %i None
-        %104 = OpAccessChain %_ptr_Function_uint %dstColorBits %103
-        %105 = OpLoad %uint %104 None
-        %106 = OpIEqual %bool %102 %105
-               OpBranch %97
-         %99 = OpLabel
-               OpBranch %97
-         %97 = OpLabel
-        %107 = OpPhi %bool %106 %98 %false %99
-               OpStore %success %107 None
-               OpBranch %78
-         %78 = OpLabel
-        %109 = OpLoad %uint %i None
-        %110 = OpIAdd %uint %109 %uint_1
-               OpStore %i %110 None
-               OpBranch %79
-         %80 = OpLabel
-        %111 = OpCompositeExtract %uint %GlobalInvocationID 1
-        %112 = OpAccessChain %_ptr_Function_uint %size %uint_0
-        %113 = OpLoad %uint %112 None
-        %114 = OpIMul %uint %111 %113
-        %115 = OpCompositeExtract %uint %GlobalInvocationID 0
-        %116 = OpIAdd %uint %114 %115
-               OpStore %outputIndex %116
-        %118 = OpLoad %bool %success None
-               OpSelectionMerge %119 None
-               OpBranchConditional %118 %120 %121
-        %120 = OpLabel
-        %122 = OpLoad %uint %outputIndex None
-        %123 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %122
-               OpStore %123 %uint_1 None
-               OpBranch %119
-        %121 = OpLabel
-        %125 = OpLoad %uint %outputIndex None
-        %126 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %125
-               OpStore %126 %uint_0 None
-               OpBranch %119
-        %119 = OpLabel
+               OpBranch %95
+         %95 = OpLabel
+               OpLoopMerge %96 %94 None
+               OpBranch %93
+         %93 = OpLabel
+         %98 = OpLoad %uint %i None
+         %99 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_3
+        %101 = OpLoad %uint %99 None
+        %102 = OpULessThan %bool %98 %101
+               OpSelectionMerge %103 None
+               OpBranchConditional %102 %103 %104
+        %104 = OpLabel
+               OpBranch %96
+        %103 = OpLabel
+        %105 = OpLoad %uint %i None
+        %106 = OpLoad %uint %i None
+        %107 = OpExtInst %uint %61 UMin %106 %uint_3
+        %108 = OpAccessChain %_ptr_Function_float %srcColor %107
+        %110 = OpLoad %float %108 None
+        %111 = OpFunctionCall %uint %ConvertToFp16FloatValue %110
+        %112 = OpExtInst %uint %61 UMin %105 %uint_3
+        %113 = OpAccessChain %_ptr_Function_uint %srcColorBits %112
+               OpStore %113 %111 None
+        %114 = OpLoad %bool %success None
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %117
+        %116 = OpLabel
+        %118 = OpLoad %uint %i None
+        %119 = OpExtInst %uint %61 UMin %118 %uint_3
+        %120 = OpAccessChain %_ptr_Function_uint %srcColorBits %119
+        %121 = OpLoad %uint %120 None
+        %122 = OpLoad %uint %i None
+        %123 = OpExtInst %uint %61 UMin %122 %uint_3
+        %124 = OpAccessChain %_ptr_Function_uint %dstColorBits %123
+        %125 = OpLoad %uint %124 None
+        %126 = OpIEqual %bool %121 %125
+               OpBranch %115
+        %117 = OpLabel
+               OpBranch %115
+        %115 = OpLabel
+        %127 = OpPhi %bool %126 %116 %false %117
+               OpStore %success %127 None
+               OpBranch %94
+         %94 = OpLabel
+        %129 = OpLoad %uint %i None
+        %130 = OpIAdd %uint %129 %uint_1
+               OpStore %i %130 None
+               OpBranch %95
+         %96 = OpLabel
+        %131 = OpCompositeExtract %uint %GlobalInvocationID 1
+        %132 = OpAccessChain %_ptr_Function_uint %size %uint_0
+        %133 = OpLoad %uint %132 None
+        %134 = OpIMul %uint %131 %133
+        %135 = OpCompositeExtract %uint %GlobalInvocationID 0
+        %136 = OpIAdd %uint %134 %135
+               OpStore %outputIndex %136
+        %138 = OpLoad %bool %success None
+               OpSelectionMerge %139 None
+               OpBranchConditional %138 %140 %141
+        %140 = OpLabel
+        %142 = OpLoad %uint %outputIndex None
+        %143 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %output %uint_0
+        %145 = OpArrayLength %uint %output 0
+        %146 = OpISub %uint %145 %uint_1
+        %147 = OpExtInst %uint %61 UMin %142 %146
+        %148 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %147
+               OpStore %148 %uint_1 None
+               OpBranch %139
+        %141 = OpLabel
+        %150 = OpLoad %uint %outputIndex None
+        %151 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %output %uint_0
+        %152 = OpArrayLength %uint %output 0
+        %153 = OpISub %uint %152 %uint_1
+        %154 = OpExtInst %uint %61 UMin %150 %153
+        %155 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %154
+               OpStore %155 %uint_0 None
+               OpBranch %139
+        %139 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_v4f32_to_v4u32 = OpFunction %v4uint None %128
+%tint_v4f32_to_v4u32 = OpFunction %v4uint None %157
       %value = OpFunctionParameter %v4float
-        %129 = OpLabel
-        %130 = OpConvertFToU %v4uint %value
-        %131 = OpFOrdGreaterThanEqual %v4bool %value %132
-        %134 = OpSelect %v4uint %131 %130 %71
-        %135 = OpFOrdLessThanEqual %v4bool %value %136
-        %138 = OpSelect %v4uint %135 %134 %139
-               OpReturnValue %138
+        %158 = OpLabel
+        %159 = OpConvertFToU %v4uint %value
+        %160 = OpFOrdGreaterThanEqual %v4bool %value %161
+        %163 = OpSelect %v4uint %160 %159 %87
+        %164 = OpFOrdLessThanEqual %v4bool %value %165
+        %167 = OpSelect %v4uint %164 %163 %168
+               OpReturnValue %167
                OpFunctionEnd
-       %main = OpFunction %void None %142
-        %143 = OpLabel
-        %144 = OpLoad %v3uint %main_global_invocation_id_Input None
-        %145 = OpFunctionCall %void %main_inner %144
+       %main = OpFunction %void None %171
+        %172 = OpLabel
+        %173 = OpLoad %v3uint %main_global_invocation_id_Input None
+        %174 = OpFunctionCall %void %main_inner %173
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/744.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/744.wgsl.expected.dxc.hlsl
index 3cd6866..aa2952d 100644
--- a/test/tint/bug/tint/744.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/744.wgsl.expected.dxc.hlsl
@@ -10,19 +10,28 @@
 };
 
 void main_inner(uint3 global_id) {
+  uint tint_symbol_8 = 0u;
+  resultMatrix.GetDimensions(tint_symbol_8);
+  uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 4u);
   uint2 resultCell = uint2(global_id.y, global_id.x);
   uint dimInner = uniforms[0].y;
   uint dimOutter = uniforms[1].y;
   uint result = 0u;
   {
     for(uint i = 0u; (i < dimInner); i = (i + 1u)) {
+      uint tint_symbol_3 = 0u;
+      firstMatrix.GetDimensions(tint_symbol_3);
+      uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+      uint tint_symbol_5 = 0u;
+      secondMatrix.GetDimensions(tint_symbol_5);
+      uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 4u);
       uint a = (i + (resultCell.x * dimInner));
       uint b = (resultCell.y + (i * dimOutter));
-      result = (result + (firstMatrix.Load((4u * a)) * secondMatrix.Load((4u * b))));
+      result = (result + (firstMatrix.Load((4u * min(a, (tint_symbol_4 - 1u)))) * secondMatrix.Load((4u * min(b, (tint_symbol_6 - 1u))))));
     }
   }
   uint index = (resultCell.y + (resultCell.x * dimOutter));
-  resultMatrix.Store((4u * index), asuint(result));
+  resultMatrix.Store((4u * min(index, (tint_symbol_9 - 1u))), asuint(result));
 }
 
 [numthreads(2, 2, 1)]
diff --git a/test/tint/bug/tint/744.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/744.wgsl.expected.fxc.hlsl
index 3cd6866..aa2952d 100644
--- a/test/tint/bug/tint/744.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/744.wgsl.expected.fxc.hlsl
@@ -10,19 +10,28 @@
 };
 
 void main_inner(uint3 global_id) {
+  uint tint_symbol_8 = 0u;
+  resultMatrix.GetDimensions(tint_symbol_8);
+  uint tint_symbol_9 = ((tint_symbol_8 - 0u) / 4u);
   uint2 resultCell = uint2(global_id.y, global_id.x);
   uint dimInner = uniforms[0].y;
   uint dimOutter = uniforms[1].y;
   uint result = 0u;
   {
     for(uint i = 0u; (i < dimInner); i = (i + 1u)) {
+      uint tint_symbol_3 = 0u;
+      firstMatrix.GetDimensions(tint_symbol_3);
+      uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+      uint tint_symbol_5 = 0u;
+      secondMatrix.GetDimensions(tint_symbol_5);
+      uint tint_symbol_6 = ((tint_symbol_5 - 0u) / 4u);
       uint a = (i + (resultCell.x * dimInner));
       uint b = (resultCell.y + (i * dimOutter));
-      result = (result + (firstMatrix.Load((4u * a)) * secondMatrix.Load((4u * b))));
+      result = (result + (firstMatrix.Load((4u * min(a, (tint_symbol_4 - 1u)))) * secondMatrix.Load((4u * min(b, (tint_symbol_6 - 1u))))));
     }
   }
   uint index = (resultCell.y + (resultCell.x * dimOutter));
-  resultMatrix.Store((4u * index), asuint(result));
+  resultMatrix.Store((4u * min(index, (tint_symbol_9 - 1u))), asuint(result));
 }
 
 [numthreads(2, 2, 1)]
diff --git a/test/tint/bug/tint/744.wgsl.expected.glsl b/test/tint/bug/tint/744.wgsl.expected.glsl
index fac0625..6f36ebb 100644
--- a/test/tint/bug/tint/744.wgsl.expected.glsl
+++ b/test/tint/bug/tint/744.wgsl.expected.glsl
@@ -37,7 +37,11 @@
       }
       uint a = (i + (resultCell[0u] * dimInner));
       uint b = (resultCell[1u] + (i * dimOutter));
-      result = (result + (firstMatrix.numbers[a] * secondMatrix.numbers[b]));
+      uint v_1 = result;
+      uint v_2 = min(a, (uint(firstMatrix.numbers.length()) - 1u));
+      uint v_3 = firstMatrix.numbers[v_2];
+      uint v_4 = min(b, (uint(secondMatrix.numbers.length()) - 1u));
+      result = (v_1 + (v_3 * secondMatrix.numbers[v_4]));
       {
         i = (i + 1u);
       }
@@ -45,7 +49,8 @@
     }
   }
   uint index = (resultCell[1u] + (resultCell[0u] * dimOutter));
-  resultMatrix.numbers[index] = result;
+  uint v_5 = min(index, (uint(resultMatrix.numbers.length()) - 1u));
+  resultMatrix.numbers[v_5] = result;
 }
 layout(local_size_x = 2, local_size_y = 2, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/744.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/744.wgsl.expected.ir.dxc.hlsl
index 6bdb246..4723036 100644
--- a/test/tint/bug/tint/744.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/744.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,11 @@
       }
       uint a = (i + (resultCell.x * dimInner));
       uint b = (resultCell.y + (i * dimOutter));
-      result = (result + (firstMatrix.Load((0u + (a * 4u))) * secondMatrix.Load((0u + (b * 4u)))));
+      uint v = 0u;
+      firstMatrix.GetDimensions(v);
+      uint v_1 = 0u;
+      secondMatrix.GetDimensions(v_1);
+      result = (result + (firstMatrix.Load((0u + (min(a, ((v / 4u) - 1u)) * 4u))) * secondMatrix.Load((0u + (min(b, ((v_1 / 4u) - 1u)) * 4u)))));
       {
         i = (i + 1u);
       }
@@ -31,7 +35,9 @@
     }
   }
   uint index = (resultCell.y + (resultCell.x * dimOutter));
-  resultMatrix.Store((0u + (index * 4u)), result);
+  uint v_2 = 0u;
+  resultMatrix.GetDimensions(v_2);
+  resultMatrix.Store((0u + (min(index, ((v_2 / 4u) - 1u)) * 4u)), result);
 }
 
 [numthreads(2, 2, 1)]
diff --git a/test/tint/bug/tint/744.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/744.wgsl.expected.ir.fxc.hlsl
index 6bdb246..4723036 100644
--- a/test/tint/bug/tint/744.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/744.wgsl.expected.ir.fxc.hlsl
@@ -23,7 +23,11 @@
       }
       uint a = (i + (resultCell.x * dimInner));
       uint b = (resultCell.y + (i * dimOutter));
-      result = (result + (firstMatrix.Load((0u + (a * 4u))) * secondMatrix.Load((0u + (b * 4u)))));
+      uint v = 0u;
+      firstMatrix.GetDimensions(v);
+      uint v_1 = 0u;
+      secondMatrix.GetDimensions(v_1);
+      result = (result + (firstMatrix.Load((0u + (min(a, ((v / 4u) - 1u)) * 4u))) * secondMatrix.Load((0u + (min(b, ((v_1 / 4u) - 1u)) * 4u)))));
       {
         i = (i + 1u);
       }
@@ -31,7 +35,9 @@
     }
   }
   uint index = (resultCell.y + (resultCell.x * dimOutter));
-  resultMatrix.Store((0u + (index * 4u)), result);
+  uint v_2 = 0u;
+  resultMatrix.GetDimensions(v_2);
+  resultMatrix.Store((0u + (min(index, ((v_2 / 4u) - 1u)) * 4u)), result);
 }
 
 [numthreads(2, 2, 1)]
diff --git a/test/tint/bug/tint/744.wgsl.expected.ir.msl b/test/tint/bug/tint/744.wgsl.expected.ir.msl
index b1d6f8d..029f76b 100644
--- a/test/tint/bug/tint/744.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/744.wgsl.expected.ir.msl
@@ -28,6 +28,7 @@
   const device Matrix* secondMatrix;
   device Matrix* resultMatrix;
   const constant Uniforms* uniforms;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint3 global_id, tint_module_vars_struct tint_module_vars) {
@@ -44,7 +45,7 @@
       }
       uint const a = (i + (resultCell[0u] * dimInner));
       uint const b = (resultCell[1u] + (i * dimOutter));
-      result = (result + ((*tint_module_vars.firstMatrix).numbers[a] * (*tint_module_vars.secondMatrix).numbers[b]));
+      result = (result + ((*tint_module_vars.firstMatrix).numbers[min(a, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))] * (*tint_module_vars.secondMatrix).numbers[min(b, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))]));
       {
         i = (i + 1u);
       }
@@ -52,10 +53,10 @@
     }
   }
   uint const index = (resultCell[1u] + (resultCell[0u] * dimOutter));
-  (*tint_module_vars.resultMatrix).numbers[index] = result;
+  (*tint_module_vars.resultMatrix).numbers[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u))] = result;
 }
 
-kernel void tint_symbol(uint3 global_id [[thread_position_in_grid]], const device Matrix* firstMatrix [[buffer(2)]], const device Matrix* secondMatrix [[buffer(3)]], device Matrix* resultMatrix [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.firstMatrix=firstMatrix, .secondMatrix=secondMatrix, .resultMatrix=resultMatrix, .uniforms=uniforms};
+kernel void tint_symbol(uint3 global_id [[thread_position_in_grid]], const device Matrix* firstMatrix [[buffer(2)]], const device Matrix* secondMatrix [[buffer(3)]], device Matrix* resultMatrix [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.firstMatrix=firstMatrix, .secondMatrix=secondMatrix, .resultMatrix=resultMatrix, .uniforms=uniforms, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(global_id, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/744.wgsl.expected.msl b/test/tint/bug/tint/744.wgsl.expected.msl
index 7c01635..dd9d9f0 100644
--- a/test/tint/bug/tint/744.wgsl.expected.msl
+++ b/test/tint/bug/tint/744.wgsl.expected.msl
@@ -14,6 +14,13 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Uniforms {
   /* 0x0000 */ uint2 aShape;
   /* 0x0008 */ uint2 bShape;
@@ -24,22 +31,23 @@
   /* 0x0000 */ tint_array<uint, 1> numbers;
 };
 
-void tint_symbol_inner(uint3 global_id, const constant Uniforms* const tint_symbol_1, const device Matrix* const tint_symbol_2, const device Matrix* const tint_symbol_3, device Matrix* const tint_symbol_4) {
+void tint_symbol_inner(uint3 global_id, const constant Uniforms* const tint_symbol_1, const device Matrix* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3, const device Matrix* const tint_symbol_4, device Matrix* const tint_symbol_5) {
   uint2 const resultCell = uint2(global_id[1], global_id[0]);
   uint const dimInner = (*(tint_symbol_1)).aShape[1];
   uint const dimOutter = (*(tint_symbol_1)).outShape[1];
   uint result = 0u;
   for(uint i = 0u; (i < dimInner); i = (i + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const a = (i + (resultCell[0] * dimInner));
     uint const b = (resultCell[1] + (i * dimOutter));
-    result = (result + ((*(tint_symbol_2)).numbers[a] * (*(tint_symbol_3)).numbers[b]));
+    result = (result + ((*(tint_symbol_2)).numbers[min(a, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] * (*(tint_symbol_4)).numbers[min(b, ((((*(tint_symbol_3)).array_lengths[0u][1u] - 0u) / 4u) - 1u))]));
   }
   uint const index = (resultCell[1] + (resultCell[0] * dimOutter));
-  (*(tint_symbol_4)).numbers[index] = result;
+  (*(tint_symbol_5)).numbers[min(index, ((((*(tint_symbol_3)).array_lengths[0u][2u] - 0u) / 4u) - 1u))] = result;
 }
 
-kernel void tint_symbol(const constant Uniforms* tint_symbol_5 [[buffer(0)]], const device Matrix* tint_symbol_6 [[buffer(2)]], const device Matrix* tint_symbol_7 [[buffer(3)]], device Matrix* tint_symbol_8 [[buffer(1)]], uint3 global_id [[thread_position_in_grid]]) {
-  tint_symbol_inner(global_id, tint_symbol_5, tint_symbol_6, tint_symbol_7, tint_symbol_8);
+kernel void tint_symbol(const constant Uniforms* tint_symbol_6 [[buffer(0)]], const device Matrix* tint_symbol_7 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_8 [[buffer(30)]], const device Matrix* tint_symbol_9 [[buffer(3)]], device Matrix* tint_symbol_10 [[buffer(1)]], uint3 global_id [[thread_position_in_grid]]) {
+  tint_symbol_inner(global_id, tint_symbol_6, tint_symbol_7, tint_symbol_8, tint_symbol_9, tint_symbol_10);
   return;
 }
 
diff --git a/test/tint/bug/tint/744.wgsl.expected.spvasm b/test/tint/bug/tint/744.wgsl.expected.spvasm
index de08a89..43ed499 100644
--- a/test/tint/bug/tint/744.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/744.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 79
+; Bound: 94
 ; Schema: 0
                OpCapability Shader
+         %63 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_global_invocation_id_Input
                OpExecutionMode %main LocalSize 2 2 1
@@ -76,9 +77,11 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint_0 = OpTypePointer StorageBuffer %_runtimearr_uint
 %_ptr_StorageBuffer_uint_0 = OpTypePointer StorageBuffer %uint
-         %75 = OpTypeFunction %void
+         %90 = OpTypeFunction %void
  %main_inner = OpFunction %void None %20
   %global_id = OpFunctionParameter %v3uint
          %21 = OpLabel
@@ -118,32 +121,44 @@
          %55 = OpIMul %uint %54 %dimOutter
           %b = OpIAdd %uint %53 %55
          %57 = OpLoad %uint %result None
-         %58 = OpAccessChain %_ptr_StorageBuffer_uint %firstMatrix %uint_0 %a
-         %60 = OpLoad %uint %58 None
-         %61 = OpAccessChain %_ptr_StorageBuffer_uint %secondMatrix %uint_0 %b
-         %62 = OpLoad %uint %61 None
-         %63 = OpIMul %uint %60 %62
-         %64 = OpIAdd %uint %57 %63
-               OpStore %result %64 None
+         %58 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %firstMatrix %uint_0
+         %60 = OpArrayLength %uint %firstMatrix 0
+         %61 = OpISub %uint %60 %uint_1
+         %62 = OpExtInst %uint %63 UMin %a %61
+         %64 = OpAccessChain %_ptr_StorageBuffer_uint %firstMatrix %uint_0 %62
+         %66 = OpLoad %uint %64 None
+         %67 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %secondMatrix %uint_0
+         %68 = OpArrayLength %uint %secondMatrix 0
+         %69 = OpISub %uint %68 %uint_1
+         %70 = OpExtInst %uint %63 UMin %b %69
+         %71 = OpAccessChain %_ptr_StorageBuffer_uint %secondMatrix %uint_0 %70
+         %72 = OpLoad %uint %71 None
+         %73 = OpIMul %uint %66 %72
+         %74 = OpIAdd %uint %57 %73
+               OpStore %result %74 None
                OpBranch %40
          %40 = OpLabel
-         %65 = OpLoad %uint %i None
-         %66 = OpIAdd %uint %65 %uint_1
-               OpStore %i %66 None
+         %75 = OpLoad %uint %i None
+         %76 = OpIAdd %uint %75 %uint_1
+               OpStore %i %76 None
                OpBranch %41
          %42 = OpLabel
-         %67 = OpCompositeExtract %uint %resultCell 1
-         %68 = OpCompositeExtract %uint %resultCell 0
-         %69 = OpIMul %uint %68 %dimOutter
-      %index = OpIAdd %uint %67 %69
-         %71 = OpAccessChain %_ptr_StorageBuffer_uint_0 %resultMatrix %uint_0 %index
-         %73 = OpLoad %uint %result None
-               OpStore %71 %73 None
+         %77 = OpCompositeExtract %uint %resultCell 1
+         %78 = OpCompositeExtract %uint %resultCell 0
+         %79 = OpIMul %uint %78 %dimOutter
+      %index = OpIAdd %uint %77 %79
+         %81 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint_0 %resultMatrix %uint_0
+         %83 = OpArrayLength %uint %resultMatrix 0
+         %84 = OpISub %uint %83 %uint_1
+         %85 = OpExtInst %uint %63 UMin %index %84
+         %86 = OpAccessChain %_ptr_StorageBuffer_uint_0 %resultMatrix %uint_0 %85
+         %88 = OpLoad %uint %result None
+               OpStore %86 %88 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %75
-         %76 = OpLabel
-         %77 = OpLoad %v3uint %main_global_invocation_id_Input None
-         %78 = OpFunctionCall %void %main_inner %77
+       %main = OpFunction %void None %90
+         %91 = OpLabel
+         %92 = OpLoad %v3uint %main_global_invocation_id_Input None
+         %93 = OpFunctionCall %void %main_inner %92
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/757.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/757.wgsl.expected.dxc.hlsl
index 455a1eb..1b50ff0 100644
--- a/test/tint/bug/tint/757.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/757.wgsl.expected.dxc.hlsl
@@ -2,7 +2,6 @@
   uint4 constants[1];
 };
 Texture2DArray<float4> myTexture : register(t1);
-
 RWByteAddressBuffer result : register(u3);
 
 struct tint_symbol_1 {
@@ -15,7 +14,10 @@
   float4 texel = myTexture.Load(int4(int3(int2(GlobalInvocationID.xy), 0), 0));
   {
     for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-      result.Store((4u * (flatIndex + i)), asuint(texel.r));
+      uint tint_symbol_3 = 0u;
+      result.GetDimensions(tint_symbol_3);
+      uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+      result.Store((4u * min((flatIndex + i), (tint_symbol_4 - 1u))), asuint(texel.r));
     }
   }
 }
diff --git a/test/tint/bug/tint/757.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/757.wgsl.expected.fxc.hlsl
index 455a1eb..1b50ff0 100644
--- a/test/tint/bug/tint/757.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/757.wgsl.expected.fxc.hlsl
@@ -2,7 +2,6 @@
   uint4 constants[1];
 };
 Texture2DArray<float4> myTexture : register(t1);
-
 RWByteAddressBuffer result : register(u3);
 
 struct tint_symbol_1 {
@@ -15,7 +14,10 @@
   float4 texel = myTexture.Load(int4(int3(int2(GlobalInvocationID.xy), 0), 0));
   {
     for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-      result.Store((4u * (flatIndex + i)), asuint(texel.r));
+      uint tint_symbol_3 = 0u;
+      result.GetDimensions(tint_symbol_3);
+      uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+      result.Store((4u * min((flatIndex + i), (tint_symbol_4 - 1u))), asuint(texel.r));
     }
   }
 }
diff --git a/test/tint/bug/tint/757.wgsl.expected.glsl b/test/tint/bug/tint/757.wgsl.expected.glsl
index 19a3f06..6f91026 100644
--- a/test/tint/bug/tint/757.wgsl.expected.glsl
+++ b/test/tint/bug/tint/757.wgsl.expected.glsl
@@ -1,16 +1,31 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 3, std430)
 buffer Result_1_ssbo {
   float values[];
 } result;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray myTexture;
 void tint_symbol_inner(uvec3 GlobalInvocationID) {
   uint flatIndex = (((4u * GlobalInvocationID[2u]) + (2u * GlobalInvocationID[1u])) + GlobalInvocationID[0u]);
   flatIndex = (flatIndex * 1u);
-  ivec2 v = ivec2(ivec2(GlobalInvocationID.xy));
-  ivec3 v_1 = ivec3(v, int(0));
-  vec4 texel = texelFetch(myTexture, v_1, int(0));
+  ivec2 v_1 = ivec2(GlobalInvocationID.xy);
+  uint v_2 = (uint(textureSize(myTexture, 0).z) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  uint v_4 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(0), v_4);
+  uvec2 v_6 = (uvec2(textureSize(myTexture, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_1), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  vec4 texel = texelFetch(myTexture, v_8, int(v_5));
   {
     uint i = 0u;
     while(true) {
@@ -18,8 +33,9 @@
       } else {
         break;
       }
-      uint v_2 = (flatIndex + i);
-      result.values[v_2] = texel.x;
+      uint v_9 = (flatIndex + i);
+      uint v_10 = min(v_9, (uint(result.values.length()) - 1u));
+      result.values[v_10] = texel.x;
       {
         i = (i + 1u);
       }
diff --git a/test/tint/bug/tint/757.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/757.wgsl.expected.ir.dxc.hlsl
index 584799b..ecad862 100644
--- a/test/tint/bug/tint/757.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/757.wgsl.expected.ir.dxc.hlsl
@@ -11,9 +11,19 @@
 void main_inner(uint3 GlobalInvocationID) {
   uint flatIndex = (((4u * GlobalInvocationID.z) + (2u * GlobalInvocationID.y)) + GlobalInvocationID.x);
   flatIndex = (flatIndex * 1u);
-  int2 v = int2(int2(GlobalInvocationID.xy));
-  int v_1 = int(int(0));
-  float4 texel = float4(myTexture.Load(int4(v, v_1, int(int(0)))));
+  int2 v = int2(GlobalInvocationID.xy);
+  uint3 v_1 = (0u).xxx;
+  myTexture.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(int(0)), (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  myTexture.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(int(0)), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  myTexture.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 texel = float4(myTexture.Load(int4(v_7, v_8, int(v_4))));
   {
     uint i = 0u;
     while(true) {
@@ -21,7 +31,9 @@
       } else {
         break;
       }
-      result.Store((0u + ((flatIndex + i) * 4u)), asuint(texel.x));
+      uint v_9 = 0u;
+      result.GetDimensions(v_9);
+      result.Store((0u + (min((flatIndex + i), ((v_9 / 4u) - 1u)) * 4u)), asuint(texel.x));
       {
         i = (i + 1u);
       }
diff --git a/test/tint/bug/tint/757.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/757.wgsl.expected.ir.fxc.hlsl
index 584799b..ecad862 100644
--- a/test/tint/bug/tint/757.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/757.wgsl.expected.ir.fxc.hlsl
@@ -11,9 +11,19 @@
 void main_inner(uint3 GlobalInvocationID) {
   uint flatIndex = (((4u * GlobalInvocationID.z) + (2u * GlobalInvocationID.y)) + GlobalInvocationID.x);
   flatIndex = (flatIndex * 1u);
-  int2 v = int2(int2(GlobalInvocationID.xy));
-  int v_1 = int(int(0));
-  float4 texel = float4(myTexture.Load(int4(v, v_1, int(int(0)))));
+  int2 v = int2(GlobalInvocationID.xy);
+  uint3 v_1 = (0u).xxx;
+  myTexture.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(int(0)), (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  myTexture.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(int(0)), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  myTexture.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 texel = float4(myTexture.Load(int4(v_7, v_8, int(v_4))));
   {
     uint i = 0u;
     while(true) {
@@ -21,7 +31,9 @@
       } else {
         break;
       }
-      result.Store((0u + ((flatIndex + i) * 4u)), asuint(texel.x));
+      uint v_9 = 0u;
+      result.GetDimensions(v_9);
+      result.Store((0u + (min((flatIndex + i), ((v_9 / 4u) - 1u)) * 4u)), asuint(texel.x));
       {
         i = (i + 1u);
       }
diff --git a/test/tint/bug/tint/757.wgsl.expected.ir.msl b/test/tint/bug/tint/757.wgsl.expected.ir.msl
index 12d3138..1a31b47 100644
--- a/test/tint/bug/tint/757.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/757.wgsl.expected.ir.msl
@@ -25,12 +25,17 @@
   const constant Constants* constants;
   texture2d_array<float, access::sample> myTexture;
   device Result* result;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint3 GlobalInvocationID, tint_module_vars_struct tint_module_vars) {
   uint flatIndex = (((4u * GlobalInvocationID[2u]) + (2u * GlobalInvocationID[1u])) + GlobalInvocationID[0u]);
   flatIndex = (flatIndex * 1u);
-  float4 texel = tint_module_vars.myTexture.read(uint2(int2(GlobalInvocationID.xy)), 0, 0);
+  int2 const v = int2(GlobalInvocationID.xy);
+  uint const v_1 = min(uint(0), (tint_module_vars.myTexture.get_array_size() - 1u));
+  uint const v_2 = min(uint(0), (tint_module_vars.myTexture.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.myTexture.get_width(v_2), tint_module_vars.myTexture.get_height(v_2)) - uint2(1u));
+  float4 texel = tint_module_vars.myTexture.read(min(uint2(v), v_3), v_1, v_2);
   {
     uint i = 0u;
     while(true) {
@@ -38,7 +43,7 @@
       } else {
         break;
       }
-      (*tint_module_vars.result).values[(flatIndex + i)] = texel[0u];
+      (*tint_module_vars.result).values[min((flatIndex + i), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))] = texel[0u];
       {
         i = (i + 1u);
       }
@@ -47,7 +52,7 @@
   }
 }
 
-kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d_array<float, access::sample> myTexture [[texture(0)]], device Result* result [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.myTexture=myTexture, .result=result};
+kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d_array<float, access::sample> myTexture [[texture(0)]], device Result* result [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.myTexture=myTexture, .result=result, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/757.wgsl.expected.msl b/test/tint/bug/tint/757.wgsl.expected.msl
index f9ee13b..9e03dc5 100644
--- a/test/tint/bug/tint/757.wgsl.expected.msl
+++ b/test/tint/bug/tint/757.wgsl.expected.msl
@@ -14,6 +14,21 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 struct Constants {
   int level;
 };
@@ -22,17 +37,19 @@
   /* 0x0000 */ tint_array<float, 1> values;
 };
 
-void tint_symbol_inner(uint3 GlobalInvocationID, texture2d_array<float, access::sample> tint_symbol_1, device Result* const tint_symbol_2) {
+void tint_symbol_inner(uint3 GlobalInvocationID, texture2d_array<float, access::sample> tint_symbol_1, device Result* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
   uint flatIndex = (((4u * GlobalInvocationID[2]) + (2u * GlobalInvocationID[1])) + GlobalInvocationID[0]);
   flatIndex = (flatIndex * 1u);
-  float4 texel = tint_symbol_1.read(uint2(int2(GlobalInvocationID.xy)), 0, 0);
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 texel = tint_symbol_1.read(uint2(tint_clamp(int2(GlobalInvocationID.xy), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(0, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   for(uint i = 0u; (i < 1u); i = (i + 1u)) {
-    (*(tint_symbol_2)).values[(flatIndex + i)] = texel[0];
+    TINT_ISOLATE_UB(tint_volatile_false);
+    (*(tint_symbol_2)).values[min((flatIndex + i), ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] = texel[0];
   }
 }
 
-kernel void tint_symbol(texture2d_array<float, access::sample> tint_symbol_3 [[texture(0)]], device Result* tint_symbol_4 [[buffer(0)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  tint_symbol_inner(GlobalInvocationID, tint_symbol_3, tint_symbol_4);
+kernel void tint_symbol(texture2d_array<float, access::sample> tint_symbol_4 [[texture(0)]], device Result* tint_symbol_5 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_6 [[buffer(30)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  tint_symbol_inner(GlobalInvocationID, tint_symbol_4, tint_symbol_5, tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/bug/tint/757.wgsl.expected.spvasm b/test/tint/bug/tint/757.wgsl.expected.spvasm
index 9c44f65..0de551d 100644
--- a/test/tint/bug/tint/757.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/757.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 76
+; Bound: 96
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %49 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_global_invocation_id_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -62,15 +64,16 @@
      %uint_1 = OpConstant %uint 1
      %v2uint = OpTypeVector %uint 2
       %v2int = OpTypeVector %int 2
-      %v3int = OpTypeVector %int 3
+     %uint_0 = OpConstant %uint 0
       %int_0 = OpConstant %int 0
+         %57 = OpConstantComposite %v2uint %uint_1 %uint_1
     %v4float = OpTypeVector %float 4
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-     %uint_0 = OpConstant %uint 0
        %bool = OpTypeBool
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Function_float = OpTypePointer Function %float
-         %72 = OpTypeFunction %void
+         %92 = OpTypeFunction %void
  %main_inner = OpFunction %void None %21
 %GlobalInvocationID = OpFunctionParameter %v3uint
          %22 = OpLabel
@@ -91,43 +94,61 @@
          %37 = OpLoad %8 %myTexture None
          %38 = OpVectorShuffle %v2uint %GlobalInvocationID %GlobalInvocationID 0 1
          %41 = OpBitcast %v2int %38
-         %43 = OpCompositeConstruct %v3int %41 %int_0
-         %45 = OpImageFetch %v4float %37 %43 Lod %int_0
-               OpStore %texel %45
-               OpBranch %49
-         %49 = OpLabel
+         %42 = OpImageQuerySizeLod %v3uint %37 %uint_0
+         %44 = OpCompositeExtract %uint %42 2
+         %45 = OpISub %uint %44 %uint_1
+         %46 = OpBitcast %uint %int_0
+         %48 = OpExtInst %uint %49 UMin %46 %45
+         %50 = OpImageQueryLevels %uint %37
+         %51 = OpISub %uint %50 %uint_1
+         %52 = OpBitcast %uint %int_0
+         %53 = OpExtInst %uint %49 UMin %52 %51
+         %54 = OpImageQuerySizeLod %v3uint %37 %53
+         %55 = OpVectorShuffle %v2uint %54 %54 0 1
+         %56 = OpISub %v2uint %55 %57
+         %58 = OpBitcast %v2uint %41
+         %59 = OpExtInst %v2uint %49 UMin %58 %56
+         %60 = OpCompositeConstruct %v3uint %59 %48
+         %61 = OpImageFetch %v4float %37 %60 Lod %53
+               OpStore %texel %61
+               OpBranch %65
+         %65 = OpLabel
                OpStore %i %uint_0
-               OpBranch %52
-         %52 = OpLabel
-               OpLoopMerge %53 %51 None
-               OpBranch %50
-         %50 = OpLabel
-         %56 = OpLoad %uint %i None
-         %57 = OpULessThan %bool %56 %uint_1
-               OpSelectionMerge %59 None
-               OpBranchConditional %57 %59 %60
-         %60 = OpLabel
-               OpBranch %53
-         %59 = OpLabel
-         %61 = OpLoad %uint %flatIndex None
-         %62 = OpLoad %uint %i None
-         %63 = OpIAdd %uint %61 %62
-         %64 = OpAccessChain %_ptr_StorageBuffer_float %result %uint_0 %63
-         %66 = OpAccessChain %_ptr_Function_float %texel %uint_0
-         %68 = OpLoad %float %66 None
-               OpStore %64 %68 None
-               OpBranch %51
-         %51 = OpLabel
-         %69 = OpLoad %uint %i None
-         %70 = OpIAdd %uint %69 %uint_1
-               OpStore %i %70 None
-               OpBranch %52
-         %53 = OpLabel
+               OpBranch %68
+         %68 = OpLabel
+               OpLoopMerge %69 %67 None
+               OpBranch %66
+         %66 = OpLabel
+         %71 = OpLoad %uint %i None
+         %72 = OpULessThan %bool %71 %uint_1
+               OpSelectionMerge %74 None
+               OpBranchConditional %72 %74 %75
+         %75 = OpLabel
+               OpBranch %69
+         %74 = OpLabel
+         %76 = OpLoad %uint %flatIndex None
+         %77 = OpLoad %uint %i None
+         %78 = OpIAdd %uint %76 %77
+         %79 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %result %uint_0
+         %81 = OpArrayLength %uint %result 0
+         %82 = OpISub %uint %81 %uint_1
+         %83 = OpExtInst %uint %49 UMin %78 %82
+         %84 = OpAccessChain %_ptr_StorageBuffer_float %result %uint_0 %83
+         %86 = OpAccessChain %_ptr_Function_float %texel %uint_0
+         %88 = OpLoad %float %86 None
+               OpStore %84 %88 None
+               OpBranch %67
+         %67 = OpLabel
+         %89 = OpLoad %uint %i None
+         %90 = OpIAdd %uint %89 %uint_1
+               OpStore %i %90 None
+               OpBranch %68
+         %69 = OpLabel
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %72
-         %73 = OpLabel
-         %74 = OpLoad %v3uint %main_global_invocation_id_Input None
-         %75 = OpFunctionCall %void %main_inner %74
+       %main = OpFunction %void None %92
+         %93 = OpLabel
+         %94 = OpLoad %v3uint %main_global_invocation_id_Input None
+         %95 = OpFunctionCall %void %main_inner %94
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/764.wgsl.expected.glsl b/test/tint/bug/tint/764.wgsl.expected.glsl
index 8baa603..9570a8e 100644
--- a/test/tint/bug/tint/764.wgsl.expected.glsl
+++ b/test/tint/bug/tint/764.wgsl.expected.glsl
@@ -2,8 +2,8 @@
 
 void f() {
   mat4 m = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  vec4 v1 = m[0];
-  float a = v1[0];
+  vec4 v1 = m[0u];
+  float a = v1[0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/764.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/764.wgsl.expected.ir.dxc.hlsl
index ea04dd9..cff5174 100644
--- a/test/tint/bug/tint/764.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/764.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 void f() {
   float4x4 m = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  float4 v1 = m[int(0)];
+  float4 v1 = m[0u];
   float a = v1.x;
 }
 
diff --git a/test/tint/bug/tint/764.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/764.wgsl.expected.ir.fxc.hlsl
index ea04dd9..cff5174 100644
--- a/test/tint/bug/tint/764.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/764.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 void f() {
   float4x4 m = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  float4 v1 = m[int(0)];
+  float4 v1 = m[0u];
   float a = v1.x;
 }
 
diff --git a/test/tint/bug/tint/764.wgsl.expected.ir.msl b/test/tint/bug/tint/764.wgsl.expected.ir.msl
index 7a3cc67..080c0b8 100644
--- a/test/tint/bug/tint/764.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/764.wgsl.expected.ir.msl
@@ -3,6 +3,6 @@
 
 void f() {
   float4x4 const m = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f));
-  float4 const v1 = m[0];
-  float const a = v1[0];
+  float4 const v1 = m[0u];
+  float const a = v1[0u];
 }
diff --git a/test/tint/bug/tint/824.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/824.wgsl.expected.dxc.hlsl
index d9ec6df..2499187 100644
--- a/test/tint/bug/tint/824.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/824.wgsl.expected.dxc.hlsl
@@ -13,11 +13,11 @@
 
 Output main_inner(uint VertexIndex, uint InstanceIndex) {
   float2 zv[4] = {(0.20000000298023223877f).xx, (0.30000001192092895508f).xx, (-0.10000000149011611938f).xx, (1.10000002384185791016f).xx};
-  float z = zv[InstanceIndex].x;
+  float z = zv[min(InstanceIndex, 3u)].x;
   Output output = (Output)0;
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   float4 colors[4] = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), (1.0f).xxxx};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   return output;
 }
 
diff --git a/test/tint/bug/tint/824.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/824.wgsl.expected.fxc.hlsl
index d9ec6df..2499187 100644
--- a/test/tint/bug/tint/824.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/824.wgsl.expected.fxc.hlsl
@@ -13,11 +13,11 @@
 
 Output main_inner(uint VertexIndex, uint InstanceIndex) {
   float2 zv[4] = {(0.20000000298023223877f).xx, (0.30000001192092895508f).xx, (-0.10000000149011611938f).xx, (1.10000002384185791016f).xx};
-  float z = zv[InstanceIndex].x;
+  float z = zv[min(InstanceIndex, 3u)].x;
   Output output = (Output)0;
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   float4 colors[4] = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), (1.0f).xxxx};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   return output;
 }
 
diff --git a/test/tint/bug/tint/824.wgsl.expected.glsl b/test/tint/bug/tint/824.wgsl.expected.glsl
index d63adac..e203f55 100644
--- a/test/tint/bug/tint/824.wgsl.expected.glsl
+++ b/test/tint/bug/tint/824.wgsl.expected.glsl
@@ -14,11 +14,11 @@
 layout(location = 0) out vec4 tint_symbol_loc0_Output;
 Output tint_symbol_inner(uint VertexIndex, uint InstanceIndex) {
   vec2 zv[4] = vec2[4](vec2(0.20000000298023223877f), vec2(0.30000001192092895508f), vec2(-0.10000000149011611938f), vec2(1.10000002384185791016f));
-  float z = zv[InstanceIndex][0u];
+  float z = zv[min(InstanceIndex, 3u)][0u];
   Output tint_symbol_1 = Output(vec4(0.0f), vec4(0.0f));
   tint_symbol_1.Position = vec4(0.5f, 0.5f, z, 1.0f);
   vec4 colors[4] = vec4[4](vec4(1.0f, 0.0f, 0.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), vec4(0.0f, 0.0f, 1.0f, 1.0f), vec4(1.0f));
-  tint_symbol_1.color = colors[InstanceIndex];
+  tint_symbol_1.color = colors[min(InstanceIndex, 3u)];
   return tint_symbol_1;
 }
 void main() {
diff --git a/test/tint/bug/tint/824.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/824.wgsl.expected.ir.dxc.hlsl
index b0a3df4..b7c02c4 100644
--- a/test/tint/bug/tint/824.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/824.wgsl.expected.ir.dxc.hlsl
@@ -16,11 +16,11 @@
 
 Output main_inner(uint VertexIndex, uint InstanceIndex) {
   float2 zv[4] = {(0.20000000298023223877f).xx, (0.30000001192092895508f).xx, (-0.10000000149011611938f).xx, (1.10000002384185791016f).xx};
-  float z = zv[InstanceIndex].x;
+  float z = zv[min(InstanceIndex, 3u)].x;
   Output output = (Output)0;
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   float4 colors[4] = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), (1.0f).xxxx};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   Output v = output;
   return v;
 }
diff --git a/test/tint/bug/tint/824.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/824.wgsl.expected.ir.fxc.hlsl
index b0a3df4..b7c02c4 100644
--- a/test/tint/bug/tint/824.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/824.wgsl.expected.ir.fxc.hlsl
@@ -16,11 +16,11 @@
 
 Output main_inner(uint VertexIndex, uint InstanceIndex) {
   float2 zv[4] = {(0.20000000298023223877f).xx, (0.30000001192092895508f).xx, (-0.10000000149011611938f).xx, (1.10000002384185791016f).xx};
-  float z = zv[InstanceIndex].x;
+  float z = zv[min(InstanceIndex, 3u)].x;
   Output output = (Output)0;
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   float4 colors[4] = {float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), (1.0f).xxxx};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   Output v = output;
   return v;
 }
diff --git a/test/tint/bug/tint/824.wgsl.expected.ir.msl b/test/tint/bug/tint/824.wgsl.expected.ir.msl
index f6a67c2..ca805ff 100644
--- a/test/tint/bug/tint/824.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/824.wgsl.expected.ir.msl
@@ -25,11 +25,11 @@
 
 Output tint_symbol_inner(uint VertexIndex, uint InstanceIndex) {
   tint_array<float2, 4> const zv = tint_array<float2, 4>{float2(0.20000000298023223877f), float2(0.30000001192092895508f), float2(-0.10000000149011611938f), float2(1.10000002384185791016f)};
-  float const z = zv[InstanceIndex][0u];
+  float const z = zv[min(InstanceIndex, 3u)][0u];
   Output output = {};
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   tint_array<float4, 4> const colors = tint_array<float4, 4>{float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), float4(1.0f)};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   return output;
 }
 
diff --git a/test/tint/bug/tint/824.wgsl.expected.msl b/test/tint/bug/tint/824.wgsl.expected.msl
index f7b83d5..d7e6185 100644
--- a/test/tint/bug/tint/824.wgsl.expected.msl
+++ b/test/tint/bug/tint/824.wgsl.expected.msl
@@ -26,11 +26,11 @@
 
 Output tint_symbol_inner(uint VertexIndex, uint InstanceIndex) {
   tint_array<float2, 4> const zv = tint_array<float2, 4>{float2(0.20000000298023223877f), float2(0.30000001192092895508f), float2(-0.10000000149011611938f), float2(1.10000002384185791016f)};
-  float const z = zv[InstanceIndex][0];
+  float const z = zv[min(InstanceIndex, 3u)][0];
   Output output = {};
   output.Position = float4(0.5f, 0.5f, z, 1.0f);
   tint_array<float4, 4> const colors = tint_array<float4, 4>{float4(1.0f, 0.0f, 0.0f, 1.0f), float4(0.0f, 1.0f, 0.0f, 1.0f), float4(0.0f, 0.0f, 1.0f, 1.0f), float4(1.0f)};
-  output.color = colors[InstanceIndex];
+  output.color = colors[min(InstanceIndex, 3u)];
   return output;
 }
 
diff --git a/test/tint/bug/tint/824.wgsl.expected.spvasm b/test/tint/bug/tint/824.wgsl.expected.spvasm
index 9c28e6a..aafd46e 100644
--- a/test/tint/bug/tint/824.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/824.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %main "main" %main_vertex_index_Input %main_instance_index_Input %main_position_Output %main_loc0_Output %main___point_size_Output
                OpName %main_vertex_index_Input "main_vertex_index_Input"
@@ -57,56 +58,59 @@
          %28 = OpConstantComposite %v2float %float_1_10000002 %float_1_10000002
          %zv = OpConstantComposite %_arr_v2float_uint_4 %22 %24 %26 %28
 %_ptr_Function__arr_v2float_uint_4 = OpTypePointer Function %_arr_v2float_uint_4
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_v2float = OpTypePointer Function %v2float
 %_ptr_Function_float = OpTypePointer Function %float
      %uint_0 = OpConstant %uint 0
 %_ptr_Function_Output = OpTypePointer Function %Output
-         %40 = OpConstantNull %Output
+         %43 = OpConstantNull %Output
 %_ptr_Function_v4float = OpTypePointer Function %v4float
   %float_0_5 = OpConstant %float 0.5
     %float_1 = OpConstant %float 1
 %_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
     %float_0 = OpConstant %float 0
-         %48 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
-         %50 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
-         %51 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
-         %52 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
-     %colors = OpConstantComposite %_arr_v4float_uint_4 %48 %50 %51 %52
+         %51 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+         %53 = OpConstantComposite %v4float %float_0 %float_1 %float_0 %float_1
+         %54 = OpConstantComposite %v4float %float_0 %float_0 %float_1 %float_1
+         %55 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+     %colors = OpConstantComposite %_arr_v4float_uint_4 %51 %53 %54 %55
 %_ptr_Function__arr_v4float_uint_4 = OpTypePointer Function %_arr_v4float_uint_4
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %62 = OpTypeFunction %void
+         %66 = OpTypeFunction %void
  %main_inner = OpFunction %Output None %16
 %VertexIndex = OpFunctionParameter %uint
 %InstanceIndex = OpFunctionParameter %uint
          %17 = OpLabel
          %30 = OpVariable %_ptr_Function__arr_v2float_uint_4 Function
-     %output = OpVariable %_ptr_Function_Output Function %40
-         %53 = OpVariable %_ptr_Function__arr_v4float_uint_4 Function
+     %output = OpVariable %_ptr_Function_Output Function %43
+         %56 = OpVariable %_ptr_Function__arr_v4float_uint_4 Function
                OpStore %30 %zv
-         %32 = OpAccessChain %_ptr_Function_v2float %30 %InstanceIndex
-         %34 = OpAccessChain %_ptr_Function_float %32 %uint_0
-          %z = OpLoad %float %34 None
-         %41 = OpAccessChain %_ptr_Function_v4float %output %uint_0
-         %43 = OpCompositeConstruct %v4float %float_0_5 %float_0_5 %z %float_1
-               OpStore %41 %43 None
-               OpStore %53 %colors
-         %55 = OpAccessChain %_ptr_Function_v4float %output %uint_1
-         %57 = OpAccessChain %_ptr_Function_v4float %53 %InstanceIndex
-         %58 = OpLoad %v4float %57 None
-               OpStore %55 %58 None
-         %59 = OpLoad %Output %output None
-               OpReturnValue %59
+         %32 = OpExtInst %uint %33 UMin %InstanceIndex %uint_3
+         %35 = OpAccessChain %_ptr_Function_v2float %30 %32
+         %37 = OpAccessChain %_ptr_Function_float %35 %uint_0
+          %z = OpLoad %float %37 None
+         %44 = OpAccessChain %_ptr_Function_v4float %output %uint_0
+         %46 = OpCompositeConstruct %v4float %float_0_5 %float_0_5 %z %float_1
+               OpStore %44 %46 None
+               OpStore %56 %colors
+         %58 = OpAccessChain %_ptr_Function_v4float %output %uint_1
+         %60 = OpExtInst %uint %33 UMin %InstanceIndex %uint_3
+         %61 = OpAccessChain %_ptr_Function_v4float %56 %60
+         %62 = OpLoad %v4float %61 None
+               OpStore %58 %62 None
+         %63 = OpLoad %Output %output None
+               OpReturnValue %63
                OpFunctionEnd
-       %main = OpFunction %void None %62
-         %63 = OpLabel
-         %64 = OpLoad %uint %main_vertex_index_Input None
-         %65 = OpLoad %uint %main_instance_index_Input None
-         %66 = OpFunctionCall %Output %main_inner %64 %65
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %main_position_Output %67 None
-         %68 = OpCompositeExtract %v4float %66 1
-               OpStore %main_loc0_Output %68 None
+       %main = OpFunction %void None %66
+         %67 = OpLabel
+         %68 = OpLoad %uint %main_vertex_index_Input None
+         %69 = OpLoad %uint %main_instance_index_Input None
+         %70 = OpFunctionCall %Output %main_inner %68 %69
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %main_loc0_Output %72 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/825.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/825.wgsl.expected.dxc.hlsl
index 1d6cae1..98e2c3d 100644
--- a/test/tint/bug/tint/825.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/825.wgsl.expected.dxc.hlsl
@@ -7,5 +7,5 @@
   int i = 0;
   int j = 0;
   float2x2 m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float f_1 = m[i][j];
+  float f_1 = m[min(uint(i), 1u)][min(uint(j), 1u)];
 }
diff --git a/test/tint/bug/tint/825.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/825.wgsl.expected.fxc.hlsl
index 1d6cae1..98e2c3d 100644
--- a/test/tint/bug/tint/825.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/825.wgsl.expected.fxc.hlsl
@@ -7,5 +7,5 @@
   int i = 0;
   int j = 0;
   float2x2 m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float f_1 = m[i][j];
+  float f_1 = m[min(uint(i), 1u)][min(uint(j), 1u)];
 }
diff --git a/test/tint/bug/tint/825.wgsl.expected.glsl b/test/tint/bug/tint/825.wgsl.expected.glsl
index 1e8fbe6..c06d2b9 100644
--- a/test/tint/bug/tint/825.wgsl.expected.glsl
+++ b/test/tint/bug/tint/825.wgsl.expected.glsl
@@ -4,7 +4,9 @@
   int i = 0;
   int j = 0;
   mat2 m = mat2(vec2(1.0f, 2.0f), vec2(3.0f, 4.0f));
-  float f_1 = m[i][j];
+  int v = j;
+  uint v_1 = min(uint(i), 1u);
+  float f_1 = m[v_1][min(uint(v), 1u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/825.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/825.wgsl.expected.ir.dxc.hlsl
index 9fc148d..0530c33 100644
--- a/test/tint/bug/tint/825.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/825.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
   int i = int(0);
   int j = int(0);
   float2x2 m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float f_1 = m[i][j];
+  int v = j;
+  uint v_1 = min(uint(i), 1u);
+  float f_1 = m[v_1][min(uint(v), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/825.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/825.wgsl.expected.ir.fxc.hlsl
index 9fc148d..0530c33 100644
--- a/test/tint/bug/tint/825.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/825.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
   int i = int(0);
   int j = int(0);
   float2x2 m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float f_1 = m[i][j];
+  int v = j;
+  uint v_1 = min(uint(i), 1u);
+  float f_1 = m[v_1][min(uint(v), 1u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/825.wgsl.expected.ir.msl b/test/tint/bug/tint/825.wgsl.expected.ir.msl
index c5816df..53f50f8 100644
--- a/test/tint/bug/tint/825.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/825.wgsl.expected.ir.msl
@@ -5,5 +5,7 @@
   int i = 0;
   int j = 0;
   float2x2 const m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float const f_1 = m[i][j];
+  int const v = j;
+  uint const v_1 = min(uint(i), 1u);
+  float const f_1 = m[v_1][min(uint(v), 1u)];
 }
diff --git a/test/tint/bug/tint/825.wgsl.expected.msl b/test/tint/bug/tint/825.wgsl.expected.msl
index b3f1c1a..63ac18a 100644
--- a/test/tint/bug/tint/825.wgsl.expected.msl
+++ b/test/tint/bug/tint/825.wgsl.expected.msl
@@ -5,6 +5,6 @@
   int i = 0;
   int j = 0;
   float2x2 const m = float2x2(float2(1.0f, 2.0f), float2(3.0f, 4.0f));
-  float const f_1 = m[i][j];
+  float const f_1 = m[min(uint(i), 1u)][min(uint(j), 1u)];
 }
 
diff --git a/test/tint/bug/tint/825.wgsl.expected.spvasm b/test/tint/bug/tint/825.wgsl.expected.spvasm
index f958ae9..959c68e 100644
--- a/test/tint/bug/tint/825.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/825.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -29,6 +30,8 @@
          %17 = OpConstantComposite %v2float %float_3 %float_4
           %m = OpConstantComposite %mat2v2float %14 %17
 %_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2float = OpTypePointer Function %v2float
 %_ptr_Function_float = OpTypePointer Function %float
           %f = OpFunction %void None %3
@@ -39,12 +42,16 @@
                OpStore %20 %m
          %22 = OpLoad %int %i None
          %23 = OpLoad %int %j None
-         %24 = OpAccessChain %_ptr_Function_v2float %20 %22
-         %26 = OpAccessChain %_ptr_Function_float %24 %23
-        %f_0 = OpLoad %float %26 None
+         %25 = OpBitcast %uint %22
+         %26 = OpExtInst %uint %27 UMin %25 %uint_1
+         %29 = OpBitcast %uint %23
+         %30 = OpExtInst %uint %27 UMin %29 %uint_1
+         %31 = OpAccessChain %_ptr_Function_v2float %20 %26
+         %33 = OpAccessChain %_ptr_Function_float %31 %30
+        %f_0 = OpLoad %float %33 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %3
-         %30 = OpLabel
+         %37 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/827.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/827.wgsl.expected.dxc.hlsl
index af0b9d5..8fd515d 100644
--- a/test/tint/bug/tint/827.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/827.wgsl.expected.dxc.hlsl
@@ -6,7 +6,10 @@
 };
 
 void main_inner(uint3 GlobalInvocationId) {
-  result.Store((4u * ((GlobalInvocationId.y * 128u) + GlobalInvocationId.x)), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0)).x));
+  uint tint_symbol_3 = 0u;
+  result.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+  result.Store((4u * min(((GlobalInvocationId.y * 128u) + GlobalInvocationId.x), (tint_symbol_4 - 1u))), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0)).x));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/827.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/827.wgsl.expected.fxc.hlsl
index af0b9d5..8fd515d 100644
--- a/test/tint/bug/tint/827.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/827.wgsl.expected.fxc.hlsl
@@ -6,7 +6,10 @@
 };
 
 void main_inner(uint3 GlobalInvocationId) {
-  result.Store((4u * ((GlobalInvocationId.y * 128u) + GlobalInvocationId.x)), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0)).x));
+  uint tint_symbol_3 = 0u;
+  result.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
+  result.Store((4u * min(((GlobalInvocationId.y * 128u) + GlobalInvocationId.x), (tint_symbol_4 - 1u))), asuint(tex.Load(int3(int(GlobalInvocationId.x), int(GlobalInvocationId.y), 0)).x));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/827.wgsl.expected.glsl b/test/tint/bug/tint/827.wgsl.expected.glsl
index 5daf228..b7cc0b0 100644
--- a/test/tint/bug/tint/827.wgsl.expected.glsl
+++ b/test/tint/bug/tint/827.wgsl.expected.glsl
@@ -1,14 +1,28 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 1, std430)
 buffer Result_1_ssbo {
   float values[];
 } result;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D tex;
 void tint_symbol_inner(uvec3 GlobalInvocationId) {
-  int v = int(GlobalInvocationId[0u]);
-  ivec2 v_1 = ivec2(ivec2(v, int(GlobalInvocationId[1u])));
-  result.values[((GlobalInvocationId[1u] * 128u) + GlobalInvocationId[0u])] = texelFetch(tex, v_1, int(0)).x;
+  uint v_1 = min(((GlobalInvocationId[1u] * 128u) + GlobalInvocationId[0u]), (uint(result.values.length()) - 1u));
+  int v_2 = int(GlobalInvocationId[0u]);
+  ivec2 v_3 = ivec2(v_2, int(GlobalInvocationId[1u]));
+  uint v_4 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(0), v_4);
+  uvec2 v_6 = (uvec2(textureSize(tex, int(v_5))) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_3), v_6));
+  result.values[v_1] = texelFetch(tex, v_7, int(v_5)).x;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/bug/tint/827.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/827.wgsl.expected.ir.dxc.hlsl
index 8030b09..6e70959 100644
--- a/test/tint/bug/tint/827.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/827.wgsl.expected.ir.dxc.hlsl
@@ -6,9 +6,19 @@
 Texture2D tex : register(t0);
 RWByteAddressBuffer result : register(u1);
 void main_inner(uint3 GlobalInvocationId) {
-  int v = int(GlobalInvocationId.x);
-  int2 v_1 = int2(int2(v, int(GlobalInvocationId.y)));
-  result.Store((0u + (((GlobalInvocationId.y * 128u) + GlobalInvocationId.x) * 4u)), asuint(tex.Load(int3(v_1, int(int(0)))).x));
+  uint v = 0u;
+  result.GetDimensions(v);
+  uint v_1 = (min(((GlobalInvocationId.y * 128u) + GlobalInvocationId.x), ((v / 4u) - 1u)) * 4u);
+  int v_2 = int(GlobalInvocationId.x);
+  int2 v_3 = int2(v_2, int(GlobalInvocationId.y));
+  uint3 v_4 = (0u).xxx;
+  tex.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint v_5 = min(uint(int(0)), (v_4.z - 1u));
+  uint3 v_6 = (0u).xxx;
+  tex.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v_3), v_7));
+  result.Store((0u + v_1), asuint(tex.Load(int3(v_8, int(v_5))).x));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/827.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/827.wgsl.expected.ir.fxc.hlsl
index 8030b09..6e70959 100644
--- a/test/tint/bug/tint/827.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/827.wgsl.expected.ir.fxc.hlsl
@@ -6,9 +6,19 @@
 Texture2D tex : register(t0);
 RWByteAddressBuffer result : register(u1);
 void main_inner(uint3 GlobalInvocationId) {
-  int v = int(GlobalInvocationId.x);
-  int2 v_1 = int2(int2(v, int(GlobalInvocationId.y)));
-  result.Store((0u + (((GlobalInvocationId.y * 128u) + GlobalInvocationId.x) * 4u)), asuint(tex.Load(int3(v_1, int(int(0)))).x));
+  uint v = 0u;
+  result.GetDimensions(v);
+  uint v_1 = (min(((GlobalInvocationId.y * 128u) + GlobalInvocationId.x), ((v / 4u) - 1u)) * 4u);
+  int v_2 = int(GlobalInvocationId.x);
+  int2 v_3 = int2(v_2, int(GlobalInvocationId.y));
+  uint3 v_4 = (0u).xxx;
+  tex.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint v_5 = min(uint(int(0)), (v_4.z - 1u));
+  uint3 v_6 = (0u).xxx;
+  tex.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v_3), v_7));
+  result.Store((0u + v_1), asuint(tex.Load(int3(v_8, int(v_5))).x));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/827.wgsl.expected.ir.msl b/test/tint/bug/tint/827.wgsl.expected.ir.msl
index 8aa648a..3dddc49 100644
--- a/test/tint/bug/tint/827.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/827.wgsl.expected.ir.msl
@@ -20,14 +20,19 @@
 struct tint_module_vars_struct {
   depth2d<float, access::sample> tex;
   device Result* result;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint3 GlobalInvocationId, tint_module_vars_struct tint_module_vars) {
-  int const v = int(GlobalInvocationId[0u]);
-  (*tint_module_vars.result).values[((GlobalInvocationId[1u] * 128u) + GlobalInvocationId[0u])] = tint_module_vars.tex.read(uint2(int2(v, int(GlobalInvocationId[1u]))), 0);
+  device float* const v = (&(*tint_module_vars.result).values[min(((GlobalInvocationId[1u] * 128u) + GlobalInvocationId[0u]), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))]);
+  int const v_1 = int(GlobalInvocationId[0u]);
+  int2 const v_2 = int2(v_1, int(GlobalInvocationId[1u]));
+  uint const v_3 = min(uint(0), (tint_module_vars.tex.get_num_mip_levels() - 1u));
+  uint2 const v_4 = (uint2(tint_module_vars.tex.get_width(v_3), tint_module_vars.tex.get_height(v_3)) - uint2(1u));
+  (*v) = tint_module_vars.tex.read(min(uint2(v_2), v_4), v_3);
 }
 
-kernel void tint_symbol(uint3 GlobalInvocationId [[thread_position_in_grid]], depth2d<float, access::sample> tex [[texture(0)]], device Result* result [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.tex=tex, .result=result};
+kernel void tint_symbol(uint3 GlobalInvocationId [[thread_position_in_grid]], depth2d<float, access::sample> tex [[texture(0)]], device Result* result [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.tex=tex, .result=result, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(GlobalInvocationId, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/827.wgsl.expected.msl b/test/tint/bug/tint/827.wgsl.expected.msl
index b230160..8ad91d0 100644
--- a/test/tint/bug/tint/827.wgsl.expected.msl
+++ b/test/tint/bug/tint/827.wgsl.expected.msl
@@ -14,16 +14,25 @@
     T elements[N];
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 struct Result {
   /* 0x0000 */ tint_array<float, 1> values;
 };
 
-void tint_symbol_inner(uint3 GlobalInvocationId, device Result* const tint_symbol_1, depth2d<float, access::sample> tint_symbol_2) {
-  (*(tint_symbol_1)).values[((GlobalInvocationId[1] * 128u) + GlobalInvocationId[0])] = tint_symbol_2.read(uint2(int2(int(GlobalInvocationId[0]), int(GlobalInvocationId[1]))), 0);
+void tint_symbol_inner(uint3 GlobalInvocationId, depth2d<float, access::sample> tint_symbol_1, device Result* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  (*(tint_symbol_2)).values[min(((GlobalInvocationId[1] * 128u) + GlobalInvocationId[0]), ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] = tint_symbol_1.read(uint2(tint_clamp(int2(int(GlobalInvocationId[0]), int(GlobalInvocationId[1])), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
 }
 
-kernel void tint_symbol(device Result* tint_symbol_3 [[buffer(0)]], depth2d<float, access::sample> tint_symbol_4 [[texture(0)]], uint3 GlobalInvocationId [[thread_position_in_grid]]) {
-  tint_symbol_inner(GlobalInvocationId, tint_symbol_3, tint_symbol_4);
+kernel void tint_symbol(depth2d<float, access::sample> tint_symbol_4 [[texture(0)]], device Result* tint_symbol_5 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_6 [[buffer(30)]], uint3 GlobalInvocationId [[thread_position_in_grid]]) {
+  tint_symbol_inner(GlobalInvocationId, tint_symbol_4, tint_symbol_5, tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/bug/tint/827.wgsl.expected.spvasm b/test/tint/bug/tint/827.wgsl.expected.spvasm
index 2db67eb..08f9e4e 100644
--- a/test/tint/bug/tint/827.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/827.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_global_invocation_id_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -39,13 +41,17 @@
        %void = OpTypeVoid
          %16 = OpTypeFunction %void %v3uint
    %uint_128 = OpConstant %uint 128
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
-    %v4float = OpTypeVector %float 4
       %int_0 = OpConstant %int 0
-         %39 = OpTypeFunction %void
+     %v2uint = OpTypeVector %uint 2
+         %49 = OpConstantComposite %v2uint %uint_1 %uint_1
+    %v4float = OpTypeVector %float 4
+         %56 = OpTypeFunction %void
  %main_inner = OpFunction %void None %16
 %GlobalInvocationId = OpFunctionParameter %v3uint
          %17 = OpLabel
@@ -53,21 +59,33 @@
          %19 = OpIMul %uint %18 %uint_128
          %21 = OpCompositeExtract %uint %GlobalInvocationId 0
          %22 = OpIAdd %uint %19 %21
-         %23 = OpAccessChain %_ptr_StorageBuffer_float %result %uint_0 %22
-         %26 = OpLoad %3 %tex None
-         %27 = OpCompositeExtract %uint %GlobalInvocationId 0
-         %29 = OpBitcast %int %27
-         %30 = OpCompositeExtract %uint %GlobalInvocationId 1
-         %31 = OpBitcast %int %30
-         %33 = OpCompositeConstruct %v2int %29 %31
-         %34 = OpImageFetch %v4float %26 %33 Lod %int_0
-         %37 = OpCompositeExtract %float %34 0
-               OpStore %23 %37 None
+         %23 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %result %uint_0
+         %26 = OpArrayLength %uint %result 0
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpExtInst %uint %30 UMin %22 %27
+         %31 = OpAccessChain %_ptr_StorageBuffer_float %result %uint_0 %29
+         %33 = OpLoad %3 %tex None
+         %34 = OpCompositeExtract %uint %GlobalInvocationId 0
+         %36 = OpBitcast %int %34
+         %37 = OpCompositeExtract %uint %GlobalInvocationId 1
+         %38 = OpBitcast %int %37
+         %40 = OpCompositeConstruct %v2int %36 %38
+         %41 = OpImageQueryLevels %uint %33
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpBitcast %uint %int_0
+         %45 = OpExtInst %uint %30 UMin %43 %42
+         %46 = OpImageQuerySizeLod %v2uint %33 %45
+         %48 = OpISub %v2uint %46 %49
+         %50 = OpBitcast %v2uint %40
+         %51 = OpExtInst %v2uint %30 UMin %50 %48
+         %52 = OpImageFetch %v4float %33 %51 Lod %45
+         %54 = OpCompositeExtract %float %52 0
+               OpStore %31 %54 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpLoad %v3uint %main_global_invocation_id_Input None
-         %42 = OpFunctionCall %void %main_inner %41
+       %main = OpFunction %void None %56
+         %57 = OpLabel
+         %58 = OpLoad %v3uint %main_global_invocation_id_Input None
+         %59 = OpFunctionCall %void %main_inner %58
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/870.spvasm.expected.glsl b/test/tint/bug/tint/870.spvasm.expected.glsl
index 2bedf5e..bef1b17 100644
--- a/test/tint/bug/tint/870.spvasm.expected.glsl
+++ b/test/tint/bug/tint/870.spvasm.expected.glsl
@@ -22,12 +22,12 @@
 void main_1() {
   int orientation[6] = int[6](0, 0, 0, 0, 0, 0);
   int x_23[6] = v.inner.passthru.orientation;
-  orientation[0] = x_23[0u];
-  orientation[1] = x_23[1u];
-  orientation[2] = x_23[2u];
-  orientation[3] = x_23[3u];
-  orientation[4] = x_23[4u];
-  orientation[5] = x_23[5u];
+  orientation[0u] = x_23[0u];
+  orientation[1u] = x_23[1u];
+  orientation[2u] = x_23[2u];
+  orientation[3u] = x_23[3u];
+  orientation[4u] = x_23[4u];
+  orientation[5u] = x_23[5u];
 }
 void main() {
   main_1();
diff --git a/test/tint/bug/tint/870.spvasm.expected.ir.dxc.hlsl b/test/tint/bug/tint/870.spvasm.expected.ir.dxc.hlsl
index 8ae4bd9..29a6496 100644
--- a/test/tint/bug/tint/870.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/870.spvasm.expected.ir.dxc.hlsl
@@ -25,12 +25,12 @@
 void main_1() {
   int orientation[6] = (int[6])0;
   int x_23[6] = v(36u);
-  orientation[int(0)] = x_23[0u];
-  orientation[int(1)] = x_23[1u];
-  orientation[int(2)] = x_23[2u];
-  orientation[int(3)] = x_23[3u];
-  orientation[int(4)] = x_23[4u];
-  orientation[int(5)] = x_23[5u];
+  orientation[0u] = x_23[0u];
+  orientation[1u] = x_23[1u];
+  orientation[2u] = x_23[2u];
+  orientation[3u] = x_23[3u];
+  orientation[4u] = x_23[4u];
+  orientation[5u] = x_23[5u];
 }
 
 void main() {
diff --git a/test/tint/bug/tint/870.spvasm.expected.ir.fxc.hlsl b/test/tint/bug/tint/870.spvasm.expected.ir.fxc.hlsl
index 8ae4bd9..29a6496 100644
--- a/test/tint/bug/tint/870.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/870.spvasm.expected.ir.fxc.hlsl
@@ -25,12 +25,12 @@
 void main_1() {
   int orientation[6] = (int[6])0;
   int x_23[6] = v(36u);
-  orientation[int(0)] = x_23[0u];
-  orientation[int(1)] = x_23[1u];
-  orientation[int(2)] = x_23[2u];
-  orientation[int(3)] = x_23[3u];
-  orientation[int(4)] = x_23[4u];
-  orientation[int(5)] = x_23[5u];
+  orientation[0u] = x_23[0u];
+  orientation[1u] = x_23[1u];
+  orientation[2u] = x_23[2u];
+  orientation[3u] = x_23[3u];
+  orientation[4u] = x_23[4u];
+  orientation[5u] = x_23[5u];
 }
 
 void main() {
diff --git a/test/tint/bug/tint/870.spvasm.expected.ir.msl b/test/tint/bug/tint/870.spvasm.expected.ir.msl
index 2300f40..2f7f102 100644
--- a/test/tint/bug/tint/870.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/870.spvasm.expected.ir.msl
@@ -32,12 +32,12 @@
 void main_1(tint_module_vars_struct tint_module_vars) {
   tint_array<int, 6> orientation = {};
   tint_array<int, 6> const x_23 = (*tint_module_vars.sspp962805860buildInformation).passthru.orientation;
-  orientation[0] = x_23[0u];
-  orientation[1] = x_23[1u];
-  orientation[2] = x_23[2u];
-  orientation[3] = x_23[3u];
-  orientation[4] = x_23[4u];
-  orientation[5] = x_23[5u];
+  orientation[0u] = x_23[0u];
+  orientation[1u] = x_23[1u];
+  orientation[2u] = x_23[2u];
+  orientation[3u] = x_23[3u];
+  orientation[4u] = x_23[4u];
+  orientation[5u] = x_23[5u];
 }
 
 fragment void tint_symbol(const device x_B4_BuildInformation* sspp962805860buildInformation [[buffer(0)]]) {
diff --git a/test/tint/bug/tint/870.spvasm.expected.spvasm b/test/tint/bug/tint/870.spvasm.expected.spvasm
index b0f3e41..682a35d 100644
--- a/test/tint/bug/tint/870.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/870.spvasm.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -50,39 +50,37 @@
      %uint_0 = OpConstant %uint 0
      %uint_3 = OpConstant %uint 3
 %_ptr_Function_int = OpTypePointer Function %int
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
-      %int_2 = OpConstant %int 2
-      %int_3 = OpConstant %int 3
-      %int_4 = OpConstant %int 4
-      %int_5 = OpConstant %int 5
+     %uint_1 = OpConstant %uint 1
+     %uint_2 = OpConstant %uint 2
+     %uint_4 = OpConstant %uint 4
+     %uint_5 = OpConstant %uint 5
      %main_1 = OpFunction %void None %14
          %15 = OpLabel
 %orientation = OpVariable %_ptr_Function__arr_int_uint_6 Function %18
          %19 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_6 %1 %uint_0 %uint_0 %uint_3
        %x_23 = OpLoad %_arr_int_uint_6 %19 None
-         %24 = OpAccessChain %_ptr_Function_int %orientation %int_0
-         %27 = OpCompositeExtract %int %x_23 0
-               OpStore %24 %27 None
-         %28 = OpAccessChain %_ptr_Function_int %orientation %int_1
-         %30 = OpCompositeExtract %int %x_23 1
-               OpStore %28 %30 None
-         %31 = OpAccessChain %_ptr_Function_int %orientation %int_2
-         %33 = OpCompositeExtract %int %x_23 2
-               OpStore %31 %33 None
-         %34 = OpAccessChain %_ptr_Function_int %orientation %int_3
-         %36 = OpCompositeExtract %int %x_23 3
-               OpStore %34 %36 None
-         %37 = OpAccessChain %_ptr_Function_int %orientation %int_4
-         %39 = OpCompositeExtract %int %x_23 4
-               OpStore %37 %39 None
-         %40 = OpAccessChain %_ptr_Function_int %orientation %int_5
-         %42 = OpCompositeExtract %int %x_23 5
-               OpStore %40 %42 None
+         %24 = OpAccessChain %_ptr_Function_int %orientation %uint_0
+         %26 = OpCompositeExtract %int %x_23 0
+               OpStore %24 %26 None
+         %27 = OpAccessChain %_ptr_Function_int %orientation %uint_1
+         %29 = OpCompositeExtract %int %x_23 1
+               OpStore %27 %29 None
+         %30 = OpAccessChain %_ptr_Function_int %orientation %uint_2
+         %32 = OpCompositeExtract %int %x_23 2
+               OpStore %30 %32 None
+         %33 = OpAccessChain %_ptr_Function_int %orientation %uint_3
+         %34 = OpCompositeExtract %int %x_23 3
+               OpStore %33 %34 None
+         %35 = OpAccessChain %_ptr_Function_int %orientation %uint_4
+         %37 = OpCompositeExtract %int %x_23 4
+               OpStore %35 %37 None
+         %38 = OpAccessChain %_ptr_Function_int %orientation %uint_5
+         %40 = OpCompositeExtract %int %x_23 5
+               OpStore %38 %40 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %14
-         %44 = OpLabel
-         %45 = OpFunctionCall %void %main_1
+         %42 = OpLabel
+         %43 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/913.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/913.wgsl.expected.dxc.hlsl
index 63f481a..87e9e71 100644
--- a/test/tint/bug/tint/913.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/913.wgsl.expected.dxc.hlsl
@@ -80,9 +80,15 @@
   }
   uint outputIndex = ((GlobalInvocationID.y * dstSize.x) + GlobalInvocationID.x);
   if (success) {
-    output.Store((4u * outputIndex), asuint(1u));
+    uint tint_symbol_10 = 0u;
+    output.GetDimensions(tint_symbol_10);
+    uint tint_symbol_11 = ((tint_symbol_10 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_11 - 1u))), asuint(1u));
   } else {
-    output.Store((4u * outputIndex), asuint(0u));
+    uint tint_symbol_12 = 0u;
+    output.GetDimensions(tint_symbol_12);
+    uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_13 - 1u))), asuint(0u));
   }
 }
 
diff --git a/test/tint/bug/tint/913.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/913.wgsl.expected.fxc.hlsl
index 63f481a..87e9e71 100644
--- a/test/tint/bug/tint/913.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/913.wgsl.expected.fxc.hlsl
@@ -80,9 +80,15 @@
   }
   uint outputIndex = ((GlobalInvocationID.y * dstSize.x) + GlobalInvocationID.x);
   if (success) {
-    output.Store((4u * outputIndex), asuint(1u));
+    uint tint_symbol_10 = 0u;
+    output.GetDimensions(tint_symbol_10);
+    uint tint_symbol_11 = ((tint_symbol_10 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_11 - 1u))), asuint(1u));
   } else {
-    output.Store((4u * outputIndex), asuint(0u));
+    uint tint_symbol_12 = 0u;
+    output.GetDimensions(tint_symbol_12);
+    uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 4u);
+    output.Store((4u * min(outputIndex, (tint_symbol_13 - 1u))), asuint(0u));
   }
 }
 
diff --git a/test/tint/bug/tint/913.wgsl.expected.glsl b/test/tint/bug/tint/913.wgsl.expected.glsl
index 53cdd5b..c4cd709 100644
--- a/test/tint/bug/tint/913.wgsl.expected.glsl
+++ b/test/tint/bug/tint/913.wgsl.expected.glsl
@@ -9,6 +9,11 @@
   uvec2 copySize;
 };
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+};
+
 layout(binding = 2, std430)
 buffer OutputBuf_1_ssbo {
   uint result[];
@@ -17,6 +22,10 @@
 uniform uniforms_block_1_ubo {
   Uniforms inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_2_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D src;
 uniform highp sampler2D dst;
 bool aboutEqual(float value, float expect) {
@@ -28,89 +37,103 @@
   uvec2 dstTexCoord = uvec2(GlobalInvocationID.xy);
   vec4 nonCoveredColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
   bool success = true;
-  bool v_1 = false;
-  if ((dstTexCoord[0u] < v.inner.dstCopyOrigin.x)) {
-    v_1 = true;
-  } else {
-    v_1 = (dstTexCoord[1u] < v.inner.dstCopyOrigin.y);
-  }
   bool v_2 = false;
-  if (v_1) {
+  if ((dstTexCoord[0u] < v.inner.dstCopyOrigin.x)) {
     v_2 = true;
   } else {
-    v_2 = (dstTexCoord[0u] >= (v.inner.dstCopyOrigin.x + v.inner.copySize.x));
+    v_2 = (dstTexCoord[1u] < v.inner.dstCopyOrigin.y);
   }
   bool v_3 = false;
   if (v_2) {
     v_3 = true;
   } else {
-    v_3 = (dstTexCoord[1u] >= (v.inner.dstCopyOrigin.y + v.inner.copySize.y));
+    v_3 = (dstTexCoord[0u] >= (v.inner.dstCopyOrigin.x + v.inner.copySize.x));
   }
+  bool v_4 = false;
   if (v_3) {
-    bool v_4 = false;
+    v_4 = true;
+  } else {
+    v_4 = (dstTexCoord[1u] >= (v.inner.dstCopyOrigin.y + v.inner.copySize.y));
+  }
+  if (v_4) {
+    bool v_5 = false;
     if (success) {
-      ivec2 v_5 = ivec2(ivec2(dstTexCoord));
-      v_4 = all(equal(texelFetch(dst, v_5, int(0)), nonCoveredColor));
+      ivec2 v_6 = ivec2(dstTexCoord);
+      uint v_7 = (v_1.inner.tint_builtin_value_1 - 1u);
+      uint v_8 = min(uint(0), v_7);
+      uvec2 v_9 = (uvec2(textureSize(dst, int(v_8))) - uvec2(1u));
+      ivec2 v_10 = ivec2(min(uvec2(v_6), v_9));
+      v_5 = all(equal(texelFetch(dst, v_10, int(v_8)), nonCoveredColor));
     } else {
-      v_4 = false;
+      v_5 = false;
     }
-    success = v_4;
+    success = v_5;
   } else {
     uvec2 srcTexCoord = ((dstTexCoord - v.inner.dstCopyOrigin) + v.inner.srcCopyOrigin);
     if ((v.inner.dstTextureFlipY == 1u)) {
       srcTexCoord[1u] = ((srcSize[1u] - srcTexCoord.y) - 1u);
     }
-    ivec2 v_6 = ivec2(ivec2(srcTexCoord));
-    vec4 srcColor = texelFetch(src, v_6, int(0));
-    ivec2 v_7 = ivec2(ivec2(dstTexCoord));
-    vec4 dstColor = texelFetch(dst, v_7, int(0));
+    ivec2 v_11 = ivec2(srcTexCoord);
+    uint v_12 = (v_1.inner.tint_builtin_value_0 - 1u);
+    uint v_13 = min(uint(0), v_12);
+    uvec2 v_14 = (uvec2(textureSize(src, int(v_13))) - uvec2(1u));
+    ivec2 v_15 = ivec2(min(uvec2(v_11), v_14));
+    vec4 srcColor = texelFetch(src, v_15, int(v_13));
+    ivec2 v_16 = ivec2(dstTexCoord);
+    uint v_17 = (v_1.inner.tint_builtin_value_1 - 1u);
+    uint v_18 = min(uint(0), v_17);
+    uvec2 v_19 = (uvec2(textureSize(dst, int(v_18))) - uvec2(1u));
+    ivec2 v_20 = ivec2(min(uvec2(v_16), v_19));
+    vec4 dstColor = texelFetch(dst, v_20, int(v_18));
     if ((v.inner.channelCount == 2u)) {
-      bool v_8 = false;
+      bool v_21 = false;
       if (success) {
-        v_8 = aboutEqual(dstColor[0u], srcColor[0u]);
+        v_21 = aboutEqual(dstColor[0u], srcColor[0u]);
       } else {
-        v_8 = false;
+        v_21 = false;
       }
-      bool v_9 = false;
-      if (v_8) {
-        v_9 = aboutEqual(dstColor[1u], srcColor[1u]);
+      bool v_22 = false;
+      if (v_21) {
+        v_22 = aboutEqual(dstColor[1u], srcColor[1u]);
       } else {
-        v_9 = false;
+        v_22 = false;
       }
-      success = v_9;
+      success = v_22;
     } else {
-      bool v_10 = false;
+      bool v_23 = false;
       if (success) {
-        v_10 = aboutEqual(dstColor[0u], srcColor[0u]);
+        v_23 = aboutEqual(dstColor[0u], srcColor[0u]);
       } else {
-        v_10 = false;
+        v_23 = false;
       }
-      bool v_11 = false;
-      if (v_10) {
-        v_11 = aboutEqual(dstColor[1u], srcColor[1u]);
+      bool v_24 = false;
+      if (v_23) {
+        v_24 = aboutEqual(dstColor[1u], srcColor[1u]);
       } else {
-        v_11 = false;
+        v_24 = false;
       }
-      bool v_12 = false;
-      if (v_11) {
-        v_12 = aboutEqual(dstColor[2u], srcColor[2u]);
+      bool v_25 = false;
+      if (v_24) {
+        v_25 = aboutEqual(dstColor[2u], srcColor[2u]);
       } else {
-        v_12 = false;
+        v_25 = false;
       }
-      bool v_13 = false;
-      if (v_12) {
-        v_13 = aboutEqual(dstColor[3u], srcColor[3u]);
+      bool v_26 = false;
+      if (v_25) {
+        v_26 = aboutEqual(dstColor[3u], srcColor[3u]);
       } else {
-        v_13 = false;
+        v_26 = false;
       }
-      success = v_13;
+      success = v_26;
     }
   }
   uint outputIndex = ((GlobalInvocationID[1u] * dstSize[0u]) + GlobalInvocationID[0u]);
   if (success) {
-    tint_symbol.result[outputIndex] = 1u;
+    uint v_27 = min(outputIndex, (uint(tint_symbol.result.length()) - 1u));
+    tint_symbol.result[v_27] = 1u;
   } else {
-    tint_symbol.result[outputIndex] = 0u;
+    uint v_28 = min(outputIndex, (uint(tint_symbol.result.length()) - 1u));
+    tint_symbol.result[v_28] = 0u;
   }
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/tint/913.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/913.wgsl.expected.ir.dxc.hlsl
index 7100aeb..8bae696 100644
--- a/test/tint/bug/tint/913.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/913.wgsl.expected.ir.dxc.hlsl
@@ -44,8 +44,15 @@
   if (v_4) {
     bool v_5 = false;
     if (success) {
-      int2 v_6 = int2(int2(dstTexCoord));
-      v_5 = all((float4(tint_symbol.Load(int3(v_6, int(int(0))))) == nonCoveredColor));
+      int2 v_6 = int2(dstTexCoord);
+      uint3 v_7 = (0u).xxx;
+      tint_symbol.GetDimensions(0u, v_7.x, v_7.y, v_7.z);
+      uint v_8 = min(uint(int(0)), (v_7.z - 1u));
+      uint3 v_9 = (0u).xxx;
+      tint_symbol.GetDimensions(uint(v_8), v_9.x, v_9.y, v_9.z);
+      uint2 v_10 = (v_9.xy - (1u).xx);
+      int2 v_11 = int2(min(uint2(v_6), v_10));
+      v_5 = all((float4(tint_symbol.Load(int3(v_11, int(v_8)))) == nonCoveredColor));
     } else {
       v_5 = false;
     }
@@ -55,57 +62,75 @@
     if ((uniforms[0u].x == 1u)) {
       srcTexCoord.y = ((srcSize.y - srcTexCoord.y) - 1u);
     }
-    int2 v_7 = int2(int2(srcTexCoord));
-    float4 srcColor = float4(src.Load(int3(v_7, int(int(0)))));
-    int2 v_8 = int2(int2(dstTexCoord));
-    float4 dstColor = float4(tint_symbol.Load(int3(v_8, int(int(0)))));
+    int2 v_12 = int2(srcTexCoord);
+    uint3 v_13 = (0u).xxx;
+    src.GetDimensions(0u, v_13.x, v_13.y, v_13.z);
+    uint v_14 = min(uint(int(0)), (v_13.z - 1u));
+    uint3 v_15 = (0u).xxx;
+    src.GetDimensions(uint(v_14), v_15.x, v_15.y, v_15.z);
+    uint2 v_16 = (v_15.xy - (1u).xx);
+    int2 v_17 = int2(min(uint2(v_12), v_16));
+    float4 srcColor = float4(src.Load(int3(v_17, int(v_14))));
+    int2 v_18 = int2(dstTexCoord);
+    uint3 v_19 = (0u).xxx;
+    tint_symbol.GetDimensions(0u, v_19.x, v_19.y, v_19.z);
+    uint v_20 = min(uint(int(0)), (v_19.z - 1u));
+    uint3 v_21 = (0u).xxx;
+    tint_symbol.GetDimensions(uint(v_20), v_21.x, v_21.y, v_21.z);
+    uint2 v_22 = (v_21.xy - (1u).xx);
+    int2 v_23 = int2(min(uint2(v_18), v_22));
+    float4 dstColor = float4(tint_symbol.Load(int3(v_23, int(v_20))));
     if ((uniforms[0u].y == 2u)) {
-      bool v_9 = false;
+      bool v_24 = false;
       if (success) {
-        v_9 = aboutEqual(dstColor.x, srcColor.x);
+        v_24 = aboutEqual(dstColor.x, srcColor.x);
       } else {
-        v_9 = false;
+        v_24 = false;
       }
-      bool v_10 = false;
-      if (v_9) {
-        v_10 = aboutEqual(dstColor.y, srcColor.y);
+      bool v_25 = false;
+      if (v_24) {
+        v_25 = aboutEqual(dstColor.y, srcColor.y);
       } else {
-        v_10 = false;
+        v_25 = false;
       }
-      success = v_10;
+      success = v_25;
     } else {
-      bool v_11 = false;
+      bool v_26 = false;
       if (success) {
-        v_11 = aboutEqual(dstColor.x, srcColor.x);
+        v_26 = aboutEqual(dstColor.x, srcColor.x);
       } else {
-        v_11 = false;
+        v_26 = false;
       }
-      bool v_12 = false;
-      if (v_11) {
-        v_12 = aboutEqual(dstColor.y, srcColor.y);
+      bool v_27 = false;
+      if (v_26) {
+        v_27 = aboutEqual(dstColor.y, srcColor.y);
       } else {
-        v_12 = false;
+        v_27 = false;
       }
-      bool v_13 = false;
-      if (v_12) {
-        v_13 = aboutEqual(dstColor.z, srcColor.z);
+      bool v_28 = false;
+      if (v_27) {
+        v_28 = aboutEqual(dstColor.z, srcColor.z);
       } else {
-        v_13 = false;
+        v_28 = false;
       }
-      bool v_14 = false;
-      if (v_13) {
-        v_14 = aboutEqual(dstColor.w, srcColor.w);
+      bool v_29 = false;
+      if (v_28) {
+        v_29 = aboutEqual(dstColor.w, srcColor.w);
       } else {
-        v_14 = false;
+        v_29 = false;
       }
-      success = v_14;
+      success = v_29;
     }
   }
   uint outputIndex = ((GlobalInvocationID.y * dstSize.x) + GlobalInvocationID.x);
   if (success) {
-    output.Store((0u + (outputIndex * 4u)), 1u);
+    uint v_30 = 0u;
+    output.GetDimensions(v_30);
+    output.Store((0u + (min(outputIndex, ((v_30 / 4u) - 1u)) * 4u)), 1u);
   } else {
-    output.Store((0u + (outputIndex * 4u)), 0u);
+    uint v_31 = 0u;
+    output.GetDimensions(v_31);
+    output.Store((0u + (min(outputIndex, ((v_31 / 4u) - 1u)) * 4u)), 0u);
   }
 }
 
diff --git a/test/tint/bug/tint/913.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/913.wgsl.expected.ir.fxc.hlsl
index 7100aeb..8bae696 100644
--- a/test/tint/bug/tint/913.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/913.wgsl.expected.ir.fxc.hlsl
@@ -44,8 +44,15 @@
   if (v_4) {
     bool v_5 = false;
     if (success) {
-      int2 v_6 = int2(int2(dstTexCoord));
-      v_5 = all((float4(tint_symbol.Load(int3(v_6, int(int(0))))) == nonCoveredColor));
+      int2 v_6 = int2(dstTexCoord);
+      uint3 v_7 = (0u).xxx;
+      tint_symbol.GetDimensions(0u, v_7.x, v_7.y, v_7.z);
+      uint v_8 = min(uint(int(0)), (v_7.z - 1u));
+      uint3 v_9 = (0u).xxx;
+      tint_symbol.GetDimensions(uint(v_8), v_9.x, v_9.y, v_9.z);
+      uint2 v_10 = (v_9.xy - (1u).xx);
+      int2 v_11 = int2(min(uint2(v_6), v_10));
+      v_5 = all((float4(tint_symbol.Load(int3(v_11, int(v_8)))) == nonCoveredColor));
     } else {
       v_5 = false;
     }
@@ -55,57 +62,75 @@
     if ((uniforms[0u].x == 1u)) {
       srcTexCoord.y = ((srcSize.y - srcTexCoord.y) - 1u);
     }
-    int2 v_7 = int2(int2(srcTexCoord));
-    float4 srcColor = float4(src.Load(int3(v_7, int(int(0)))));
-    int2 v_8 = int2(int2(dstTexCoord));
-    float4 dstColor = float4(tint_symbol.Load(int3(v_8, int(int(0)))));
+    int2 v_12 = int2(srcTexCoord);
+    uint3 v_13 = (0u).xxx;
+    src.GetDimensions(0u, v_13.x, v_13.y, v_13.z);
+    uint v_14 = min(uint(int(0)), (v_13.z - 1u));
+    uint3 v_15 = (0u).xxx;
+    src.GetDimensions(uint(v_14), v_15.x, v_15.y, v_15.z);
+    uint2 v_16 = (v_15.xy - (1u).xx);
+    int2 v_17 = int2(min(uint2(v_12), v_16));
+    float4 srcColor = float4(src.Load(int3(v_17, int(v_14))));
+    int2 v_18 = int2(dstTexCoord);
+    uint3 v_19 = (0u).xxx;
+    tint_symbol.GetDimensions(0u, v_19.x, v_19.y, v_19.z);
+    uint v_20 = min(uint(int(0)), (v_19.z - 1u));
+    uint3 v_21 = (0u).xxx;
+    tint_symbol.GetDimensions(uint(v_20), v_21.x, v_21.y, v_21.z);
+    uint2 v_22 = (v_21.xy - (1u).xx);
+    int2 v_23 = int2(min(uint2(v_18), v_22));
+    float4 dstColor = float4(tint_symbol.Load(int3(v_23, int(v_20))));
     if ((uniforms[0u].y == 2u)) {
-      bool v_9 = false;
+      bool v_24 = false;
       if (success) {
-        v_9 = aboutEqual(dstColor.x, srcColor.x);
+        v_24 = aboutEqual(dstColor.x, srcColor.x);
       } else {
-        v_9 = false;
+        v_24 = false;
       }
-      bool v_10 = false;
-      if (v_9) {
-        v_10 = aboutEqual(dstColor.y, srcColor.y);
+      bool v_25 = false;
+      if (v_24) {
+        v_25 = aboutEqual(dstColor.y, srcColor.y);
       } else {
-        v_10 = false;
+        v_25 = false;
       }
-      success = v_10;
+      success = v_25;
     } else {
-      bool v_11 = false;
+      bool v_26 = false;
       if (success) {
-        v_11 = aboutEqual(dstColor.x, srcColor.x);
+        v_26 = aboutEqual(dstColor.x, srcColor.x);
       } else {
-        v_11 = false;
+        v_26 = false;
       }
-      bool v_12 = false;
-      if (v_11) {
-        v_12 = aboutEqual(dstColor.y, srcColor.y);
+      bool v_27 = false;
+      if (v_26) {
+        v_27 = aboutEqual(dstColor.y, srcColor.y);
       } else {
-        v_12 = false;
+        v_27 = false;
       }
-      bool v_13 = false;
-      if (v_12) {
-        v_13 = aboutEqual(dstColor.z, srcColor.z);
+      bool v_28 = false;
+      if (v_27) {
+        v_28 = aboutEqual(dstColor.z, srcColor.z);
       } else {
-        v_13 = false;
+        v_28 = false;
       }
-      bool v_14 = false;
-      if (v_13) {
-        v_14 = aboutEqual(dstColor.w, srcColor.w);
+      bool v_29 = false;
+      if (v_28) {
+        v_29 = aboutEqual(dstColor.w, srcColor.w);
       } else {
-        v_14 = false;
+        v_29 = false;
       }
-      success = v_14;
+      success = v_29;
     }
   }
   uint outputIndex = ((GlobalInvocationID.y * dstSize.x) + GlobalInvocationID.x);
   if (success) {
-    output.Store((0u + (outputIndex * 4u)), 1u);
+    uint v_30 = 0u;
+    output.GetDimensions(v_30);
+    output.Store((0u + (min(outputIndex, ((v_30 / 4u) - 1u)) * 4u)), 1u);
   } else {
-    output.Store((0u + (outputIndex * 4u)), 0u);
+    uint v_31 = 0u;
+    output.GetDimensions(v_31);
+    output.Store((0u + (min(outputIndex, ((v_31 / 4u) - 1u)) * 4u)), 0u);
   }
 }
 
diff --git a/test/tint/bug/tint/913.wgsl.expected.ir.msl b/test/tint/bug/tint/913.wgsl.expected.ir.msl
index 08531cf..821639b 100644
--- a/test/tint/bug/tint/913.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/913.wgsl.expected.ir.msl
@@ -30,6 +30,7 @@
   texture2d<float, access::sample> dst;
   device OutputBuf* output;
   const constant Uniforms* uniforms;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 bool aboutEqual(float value, float expect) {
@@ -63,7 +64,10 @@
   if (v_2) {
     bool v_3 = false;
     if (success) {
-      v_3 = all((tint_module_vars.dst.read(uint2(int2(dstTexCoord)), 0) == nonCoveredColor));
+      int2 const v_4 = int2(dstTexCoord);
+      uint const v_5 = min(uint(0), (tint_module_vars.dst.get_num_mip_levels() - 1u));
+      uint2 const v_6 = (uint2(tint_module_vars.dst.get_width(v_5), tint_module_vars.dst.get_height(v_5)) - uint2(1u));
+      v_3 = all((tint_module_vars.dst.read(min(uint2(v_4), v_6), v_5) == nonCoveredColor));
     } else {
       v_3 = false;
     }
@@ -73,59 +77,65 @@
     if (((*tint_module_vars.uniforms).dstTextureFlipY == 1u)) {
       srcTexCoord[1u] = ((srcSize[1u] - srcTexCoord[1u]) - 1u);
     }
-    float4 const srcColor = tint_module_vars.src.read(uint2(int2(srcTexCoord)), 0);
-    float4 const dstColor = tint_module_vars.dst.read(uint2(int2(dstTexCoord)), 0);
+    int2 const v_7 = int2(srcTexCoord);
+    uint const v_8 = min(uint(0), (tint_module_vars.src.get_num_mip_levels() - 1u));
+    uint2 const v_9 = (uint2(tint_module_vars.src.get_width(v_8), tint_module_vars.src.get_height(v_8)) - uint2(1u));
+    float4 const srcColor = tint_module_vars.src.read(min(uint2(v_7), v_9), v_8);
+    int2 const v_10 = int2(dstTexCoord);
+    uint const v_11 = min(uint(0), (tint_module_vars.dst.get_num_mip_levels() - 1u));
+    uint2 const v_12 = (uint2(tint_module_vars.dst.get_width(v_11), tint_module_vars.dst.get_height(v_11)) - uint2(1u));
+    float4 const dstColor = tint_module_vars.dst.read(min(uint2(v_10), v_12), v_11);
     if (((*tint_module_vars.uniforms).channelCount == 2u)) {
-      bool v_4 = false;
+      bool v_13 = false;
       if (success) {
-        v_4 = aboutEqual(dstColor[0u], srcColor[0u]);
+        v_13 = aboutEqual(dstColor[0u], srcColor[0u]);
       } else {
-        v_4 = false;
+        v_13 = false;
       }
-      bool v_5 = false;
-      if (v_4) {
-        v_5 = aboutEqual(dstColor[1u], srcColor[1u]);
+      bool v_14 = false;
+      if (v_13) {
+        v_14 = aboutEqual(dstColor[1u], srcColor[1u]);
       } else {
-        v_5 = false;
+        v_14 = false;
       }
-      success = v_5;
+      success = v_14;
     } else {
-      bool v_6 = false;
+      bool v_15 = false;
       if (success) {
-        v_6 = aboutEqual(dstColor[0u], srcColor[0u]);
+        v_15 = aboutEqual(dstColor[0u], srcColor[0u]);
       } else {
-        v_6 = false;
+        v_15 = false;
       }
-      bool v_7 = false;
-      if (v_6) {
-        v_7 = aboutEqual(dstColor[1u], srcColor[1u]);
+      bool v_16 = false;
+      if (v_15) {
+        v_16 = aboutEqual(dstColor[1u], srcColor[1u]);
       } else {
-        v_7 = false;
+        v_16 = false;
       }
-      bool v_8 = false;
-      if (v_7) {
-        v_8 = aboutEqual(dstColor[2u], srcColor[2u]);
+      bool v_17 = false;
+      if (v_16) {
+        v_17 = aboutEqual(dstColor[2u], srcColor[2u]);
       } else {
-        v_8 = false;
+        v_17 = false;
       }
-      bool v_9 = false;
-      if (v_8) {
-        v_9 = aboutEqual(dstColor[3u], srcColor[3u]);
+      bool v_18 = false;
+      if (v_17) {
+        v_18 = aboutEqual(dstColor[3u], srcColor[3u]);
       } else {
-        v_9 = false;
+        v_18 = false;
       }
-      success = v_9;
+      success = v_18;
     }
   }
   uint const outputIndex = ((GlobalInvocationID[1u] * dstSize[0u]) + GlobalInvocationID[0u]);
   if (success) {
-    (*tint_module_vars.output).result[outputIndex] = 1u;
+    (*tint_module_vars.output).result[min(outputIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))] = 1u;
   } else {
-    (*tint_module_vars.output).result[outputIndex] = 0u;
+    (*tint_module_vars.output).result[min(outputIndex, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))] = 0u;
   }
 }
 
-kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d<float, access::sample> src [[texture(0)]], texture2d<float, access::sample> dst [[texture(1)]], device OutputBuf* output [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src=src, .dst=dst, .output=output, .uniforms=uniforms};
+kernel void tint_symbol(uint3 GlobalInvocationID [[thread_position_in_grid]], texture2d<float, access::sample> src [[texture(0)]], texture2d<float, access::sample> dst [[texture(1)]], device OutputBuf* output [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.src=src, .dst=dst, .output=output, .uniforms=uniforms, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(GlobalInvocationID, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/913.wgsl.expected.msl b/test/tint/bug/tint/913.wgsl.expected.msl
index 6a4fbea..7fe62fc 100644
--- a/test/tint/bug/tint/913.wgsl.expected.msl
+++ b/test/tint/bug/tint/913.wgsl.expected.msl
@@ -14,6 +14,14 @@
     T elements[N];
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 struct Uniforms {
   /* 0x0000 */ uint dstTextureFlipY;
   /* 0x0004 */ uint channelCount;
@@ -30,21 +38,24 @@
   return (fabs((value - expect)) < 0.00100000004749745131f);
 }
 
-void tint_symbol_inner(uint3 GlobalInvocationID, texture2d<float, access::sample> tint_symbol_7, texture2d<float, access::sample> tint_symbol_8, const constant Uniforms* const tint_symbol_9, device OutputBuf* const tint_symbol_10) {
+void tint_symbol_inner(uint3 GlobalInvocationID, texture2d<float, access::sample> tint_symbol_7, texture2d<float, access::sample> tint_symbol_8, const constant Uniforms* const tint_symbol_9, device OutputBuf* const tint_symbol_10, const constant TintArrayLengths* const tint_symbol_11) {
   uint2 const srcSize = uint2(tint_symbol_7.get_width(), tint_symbol_7.get_height());
   uint2 const dstSize = uint2(tint_symbol_8.get_width(), tint_symbol_8.get_height());
   uint2 const dstTexCoord = uint2(GlobalInvocationID.xy);
   float4 const nonCoveredColor = float4(0.0f, 1.0f, 0.0f, 1.0f);
   bool success = true;
   if (((((dstTexCoord[0] < (*(tint_symbol_9)).dstCopyOrigin[0]) || (dstTexCoord[1] < (*(tint_symbol_9)).dstCopyOrigin[1])) || (dstTexCoord[0] >= ((*(tint_symbol_9)).dstCopyOrigin[0] + (*(tint_symbol_9)).copySize[0]))) || (dstTexCoord[1] >= ((*(tint_symbol_9)).dstCopyOrigin[1] + (*(tint_symbol_9)).copySize[1])))) {
-    success = (success && all((tint_symbol_8.read(uint2(int2(dstTexCoord)), 0) == nonCoveredColor)));
+    uint const level_idx = min(0u, (tint_symbol_8.get_num_mip_levels() - 1u));
+    success = (success && all((tint_symbol_8.read(uint2(tint_clamp(int2(dstTexCoord), int2(0), int2((uint2(tint_symbol_8.get_width(level_idx), tint_symbol_8.get_height(level_idx)) - uint2(1u))))), level_idx) == nonCoveredColor)));
   } else {
     uint2 srcTexCoord = ((dstTexCoord - (*(tint_symbol_9)).dstCopyOrigin) + (*(tint_symbol_9)).srcCopyOrigin);
     if (((*(tint_symbol_9)).dstTextureFlipY == 1u)) {
       srcTexCoord[1] = ((srcSize[1] - srcTexCoord[1]) - 1u);
     }
-    float4 const srcColor = tint_symbol_7.read(uint2(int2(srcTexCoord)), 0);
-    float4 const dstColor = tint_symbol_8.read(uint2(int2(dstTexCoord)), 0);
+    uint const level_idx_1 = min(0u, (tint_symbol_7.get_num_mip_levels() - 1u));
+    float4 const srcColor = tint_symbol_7.read(uint2(tint_clamp(int2(srcTexCoord), int2(0), int2((uint2(tint_symbol_7.get_width(level_idx_1), tint_symbol_7.get_height(level_idx_1)) - uint2(1u))))), level_idx_1);
+    uint const level_idx_2 = min(0u, (tint_symbol_8.get_num_mip_levels() - 1u));
+    float4 const dstColor = tint_symbol_8.read(uint2(tint_clamp(int2(dstTexCoord), int2(0), int2((uint2(tint_symbol_8.get_width(level_idx_2), tint_symbol_8.get_height(level_idx_2)) - uint2(1u))))), level_idx_2);
     if (((*(tint_symbol_9)).channelCount == 2u)) {
       bool tint_symbol_2 = success;
       if (tint_symbol_2) {
@@ -77,14 +88,14 @@
   }
   uint const outputIndex = ((GlobalInvocationID[1] * dstSize[0]) + GlobalInvocationID[0]);
   if (success) {
-    (*(tint_symbol_10)).result[outputIndex] = 1u;
+    (*(tint_symbol_10)).result[min(outputIndex, ((((*(tint_symbol_11)).array_lengths[0u][1u] - 0u) / 4u) - 1u))] = 1u;
   } else {
-    (*(tint_symbol_10)).result[outputIndex] = 0u;
+    (*(tint_symbol_10)).result[min(outputIndex, ((((*(tint_symbol_11)).array_lengths[0u][1u] - 0u) / 4u) - 1u))] = 0u;
   }
 }
 
-kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_11 [[texture(0)]], texture2d<float, access::sample> tint_symbol_12 [[texture(1)]], const constant Uniforms* tint_symbol_13 [[buffer(0)]], device OutputBuf* tint_symbol_14 [[buffer(1)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
-  tint_symbol_inner(GlobalInvocationID, tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14);
+kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_12 [[texture(0)]], texture2d<float, access::sample> tint_symbol_13 [[texture(1)]], const constant Uniforms* tint_symbol_14 [[buffer(0)]], device OutputBuf* tint_symbol_15 [[buffer(1)]], const constant TintArrayLengths* tint_symbol_16 [[buffer(30)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
+  tint_symbol_inner(GlobalInvocationID, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15, tint_symbol_16);
   return;
 }
 
diff --git a/test/tint/bug/tint/913.wgsl.expected.spvasm b/test/tint/bug/tint/913.wgsl.expected.spvasm
index 7256a06..5eb801c 100644
--- a/test/tint/bug/tint/913.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/913.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 206
+; Bound: 240
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
@@ -97,13 +97,15 @@
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_0 = OpConstant %int 0
+        %111 = OpConstantComposite %v2uint %uint_1 %uint_1
      %v4bool = OpTypeVector %bool 4
       %false = OpConstantFalse %bool
      %uint_2 = OpConstant %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
 %_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-        %202 = OpTypeFunction %void
+        %236 = OpTypeFunction %void
  %aboutEqual = OpFunction %bool None %23
       %value = OpFunctionParameter %float
      %expect = OpFunctionParameter %float
@@ -185,150 +187,182 @@
          %98 = OpLabel
         %100 = OpLoad %3 %dst None
         %103 = OpBitcast %v2int %dstTexCoord
-        %104 = OpImageFetch %v4float %100 %103 Lod %int_0
-        %106 = OpFOrdEqual %v4bool %104 %nonCoveredColor
-        %108 = OpAll %bool %106
+        %104 = OpImageQueryLevels %uint %100
+        %105 = OpISub %uint %104 %uint_1
+        %106 = OpBitcast %uint %int_0
+        %108 = OpExtInst %uint %27 UMin %106 %105
+        %109 = OpImageQuerySizeLod %v2uint %100 %108
+        %110 = OpISub %v2uint %109 %111
+        %112 = OpBitcast %v2uint %103
+        %113 = OpExtInst %v2uint %27 UMin %112 %110
+        %114 = OpImageFetch %v4float %100 %113 Lod %108
+        %115 = OpFOrdEqual %v4bool %114 %nonCoveredColor
+        %117 = OpAll %bool %115
                OpBranch %97
          %99 = OpLabel
                OpBranch %97
          %97 = OpLabel
-        %109 = OpPhi %bool %108 %98 %false %99
-               OpStore %success %109 None
+        %118 = OpPhi %bool %117 %98 %false %99
+               OpStore %success %118 None
                OpBranch %93
          %95 = OpLabel
-        %111 = OpAccessChain %_ptr_Uniform_v2uint %11 %uint_0 %uint_3
-        %112 = OpLoad %v2uint %111 None
-        %113 = OpISub %v2uint %dstTexCoord %112
-        %114 = OpAccessChain %_ptr_Uniform_v2uint %11 %uint_0 %uint_2
-        %116 = OpLoad %v2uint %114 None
-        %117 = OpIAdd %v2uint %113 %116
-               OpStore %srcTexCoord %117
-        %120 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_0
-        %121 = OpLoad %uint %120 None
-        %122 = OpIEqual %bool %121 %uint_1
-               OpSelectionMerge %123 None
-               OpBranchConditional %122 %124 %123
-        %124 = OpLabel
-        %125 = OpCompositeExtract %uint %srcSize 1
-        %126 = OpAccessChain %_ptr_Function_uint %srcTexCoord %uint_1
-        %128 = OpLoad %uint %126 None
-        %129 = OpISub %uint %125 %128
-        %130 = OpISub %uint %129 %uint_1
-        %131 = OpAccessChain %_ptr_Function_uint %srcTexCoord %uint_1
-               OpStore %131 %130 None
-               OpBranch %123
-        %123 = OpLabel
-        %132 = OpLoad %3 %src None
-        %133 = OpLoad %v2uint %srcTexCoord None
-        %134 = OpBitcast %v2int %133
-   %srcColor = OpImageFetch %v4float %132 %134 Lod %int_0
-        %136 = OpLoad %3 %dst None
-        %137 = OpBitcast %v2int %dstTexCoord
-   %dstColor = OpImageFetch %v4float %136 %137 Lod %int_0
-        %139 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_1
-        %140 = OpLoad %uint %139 None
-        %141 = OpIEqual %bool %140 %uint_2
-               OpSelectionMerge %142 None
-               OpBranchConditional %141 %143 %144
-        %143 = OpLabel
-        %145 = OpLoad %bool %success None
-               OpSelectionMerge %146 None
-               OpBranchConditional %145 %147 %148
-        %147 = OpLabel
-        %149 = OpCompositeExtract %float %dstColor 0
-        %150 = OpCompositeExtract %float %srcColor 0
-        %151 = OpFunctionCall %bool %aboutEqual %149 %150
-               OpBranch %146
-        %148 = OpLabel
-               OpBranch %146
-        %146 = OpLabel
-        %152 = OpPhi %bool %151 %147 %false %148
-               OpSelectionMerge %153 None
-               OpBranchConditional %152 %154 %155
-        %154 = OpLabel
-        %156 = OpCompositeExtract %float %dstColor 1
-        %157 = OpCompositeExtract %float %srcColor 1
-        %158 = OpFunctionCall %bool %aboutEqual %156 %157
-               OpBranch %153
-        %155 = OpLabel
-               OpBranch %153
-        %153 = OpLabel
-        %159 = OpPhi %bool %158 %154 %false %155
-               OpStore %success %159 None
-               OpBranch %142
-        %144 = OpLabel
-        %160 = OpLoad %bool %success None
-               OpSelectionMerge %161 None
-               OpBranchConditional %160 %162 %163
-        %162 = OpLabel
-        %164 = OpCompositeExtract %float %dstColor 0
-        %165 = OpCompositeExtract %float %srcColor 0
-        %166 = OpFunctionCall %bool %aboutEqual %164 %165
-               OpBranch %161
-        %163 = OpLabel
-               OpBranch %161
-        %161 = OpLabel
-        %167 = OpPhi %bool %166 %162 %false %163
-               OpSelectionMerge %168 None
-               OpBranchConditional %167 %169 %170
-        %169 = OpLabel
-        %171 = OpCompositeExtract %float %dstColor 1
-        %172 = OpCompositeExtract %float %srcColor 1
-        %173 = OpFunctionCall %bool %aboutEqual %171 %172
-               OpBranch %168
-        %170 = OpLabel
-               OpBranch %168
+        %120 = OpAccessChain %_ptr_Uniform_v2uint %11 %uint_0 %uint_3
+        %121 = OpLoad %v2uint %120 None
+        %122 = OpISub %v2uint %dstTexCoord %121
+        %123 = OpAccessChain %_ptr_Uniform_v2uint %11 %uint_0 %uint_2
+        %125 = OpLoad %v2uint %123 None
+        %126 = OpIAdd %v2uint %122 %125
+               OpStore %srcTexCoord %126
+        %129 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_0
+        %130 = OpLoad %uint %129 None
+        %131 = OpIEqual %bool %130 %uint_1
+               OpSelectionMerge %132 None
+               OpBranchConditional %131 %133 %132
+        %133 = OpLabel
+        %134 = OpCompositeExtract %uint %srcSize 1
+        %135 = OpAccessChain %_ptr_Function_uint %srcTexCoord %uint_1
+        %137 = OpLoad %uint %135 None
+        %138 = OpISub %uint %134 %137
+        %139 = OpISub %uint %138 %uint_1
+        %140 = OpAccessChain %_ptr_Function_uint %srcTexCoord %uint_1
+               OpStore %140 %139 None
+               OpBranch %132
+        %132 = OpLabel
+        %141 = OpLoad %3 %src None
+        %142 = OpLoad %v2uint %srcTexCoord None
+        %143 = OpBitcast %v2int %142
+        %144 = OpImageQueryLevels %uint %141
+        %145 = OpISub %uint %144 %uint_1
+        %146 = OpBitcast %uint %int_0
+        %147 = OpExtInst %uint %27 UMin %146 %145
+        %148 = OpImageQuerySizeLod %v2uint %141 %147
+        %149 = OpISub %v2uint %148 %111
+        %150 = OpBitcast %v2uint %143
+        %151 = OpExtInst %v2uint %27 UMin %150 %149
+   %srcColor = OpImageFetch %v4float %141 %151 Lod %147
+        %153 = OpLoad %3 %dst None
+        %154 = OpBitcast %v2int %dstTexCoord
+        %155 = OpImageQueryLevels %uint %153
+        %156 = OpISub %uint %155 %uint_1
+        %157 = OpBitcast %uint %int_0
+        %158 = OpExtInst %uint %27 UMin %157 %156
+        %159 = OpImageQuerySizeLod %v2uint %153 %158
+        %160 = OpISub %v2uint %159 %111
+        %161 = OpBitcast %v2uint %154
+        %162 = OpExtInst %v2uint %27 UMin %161 %160
+   %dstColor = OpImageFetch %v4float %153 %162 Lod %158
+        %164 = OpAccessChain %_ptr_Uniform_uint %11 %uint_0 %uint_1
+        %165 = OpLoad %uint %164 None
+        %166 = OpIEqual %bool %165 %uint_2
+               OpSelectionMerge %167 None
+               OpBranchConditional %166 %168 %169
         %168 = OpLabel
-        %174 = OpPhi %bool %173 %169 %false %170
-               OpSelectionMerge %175 None
-               OpBranchConditional %174 %176 %177
-        %176 = OpLabel
-        %178 = OpCompositeExtract %float %dstColor 2
-        %179 = OpCompositeExtract %float %srcColor 2
-        %180 = OpFunctionCall %bool %aboutEqual %178 %179
-               OpBranch %175
-        %177 = OpLabel
-               OpBranch %175
-        %175 = OpLabel
-        %181 = OpPhi %bool %180 %176 %false %177
-               OpSelectionMerge %182 None
-               OpBranchConditional %181 %183 %184
-        %183 = OpLabel
-        %185 = OpCompositeExtract %float %dstColor 3
-        %186 = OpCompositeExtract %float %srcColor 3
-        %187 = OpFunctionCall %bool %aboutEqual %185 %186
-               OpBranch %182
-        %184 = OpLabel
-               OpBranch %182
-        %182 = OpLabel
-        %188 = OpPhi %bool %187 %183 %false %184
-               OpStore %success %188 None
-               OpBranch %142
-        %142 = OpLabel
+        %170 = OpLoad %bool %success None
+               OpSelectionMerge %171 None
+               OpBranchConditional %170 %172 %173
+        %172 = OpLabel
+        %174 = OpCompositeExtract %float %dstColor 0
+        %175 = OpCompositeExtract %float %srcColor 0
+        %176 = OpFunctionCall %bool %aboutEqual %174 %175
+               OpBranch %171
+        %173 = OpLabel
+               OpBranch %171
+        %171 = OpLabel
+        %177 = OpPhi %bool %176 %172 %false %173
+               OpSelectionMerge %178 None
+               OpBranchConditional %177 %179 %180
+        %179 = OpLabel
+        %181 = OpCompositeExtract %float %dstColor 1
+        %182 = OpCompositeExtract %float %srcColor 1
+        %183 = OpFunctionCall %bool %aboutEqual %181 %182
+               OpBranch %178
+        %180 = OpLabel
+               OpBranch %178
+        %178 = OpLabel
+        %184 = OpPhi %bool %183 %179 %false %180
+               OpStore %success %184 None
+               OpBranch %167
+        %169 = OpLabel
+        %185 = OpLoad %bool %success None
+               OpSelectionMerge %186 None
+               OpBranchConditional %185 %187 %188
+        %187 = OpLabel
+        %189 = OpCompositeExtract %float %dstColor 0
+        %190 = OpCompositeExtract %float %srcColor 0
+        %191 = OpFunctionCall %bool %aboutEqual %189 %190
+               OpBranch %186
+        %188 = OpLabel
+               OpBranch %186
+        %186 = OpLabel
+        %192 = OpPhi %bool %191 %187 %false %188
+               OpSelectionMerge %193 None
+               OpBranchConditional %192 %194 %195
+        %194 = OpLabel
+        %196 = OpCompositeExtract %float %dstColor 1
+        %197 = OpCompositeExtract %float %srcColor 1
+        %198 = OpFunctionCall %bool %aboutEqual %196 %197
+               OpBranch %193
+        %195 = OpLabel
+               OpBranch %193
+        %193 = OpLabel
+        %199 = OpPhi %bool %198 %194 %false %195
+               OpSelectionMerge %200 None
+               OpBranchConditional %199 %201 %202
+        %201 = OpLabel
+        %203 = OpCompositeExtract %float %dstColor 2
+        %204 = OpCompositeExtract %float %srcColor 2
+        %205 = OpFunctionCall %bool %aboutEqual %203 %204
+               OpBranch %200
+        %202 = OpLabel
+               OpBranch %200
+        %200 = OpLabel
+        %206 = OpPhi %bool %205 %201 %false %202
+               OpSelectionMerge %207 None
+               OpBranchConditional %206 %208 %209
+        %208 = OpLabel
+        %210 = OpCompositeExtract %float %dstColor 3
+        %211 = OpCompositeExtract %float %srcColor 3
+        %212 = OpFunctionCall %bool %aboutEqual %210 %211
+               OpBranch %207
+        %209 = OpLabel
+               OpBranch %207
+        %207 = OpLabel
+        %213 = OpPhi %bool %212 %208 %false %209
+               OpStore %success %213 None
+               OpBranch %167
+        %167 = OpLabel
                OpBranch %93
          %93 = OpLabel
-        %189 = OpCompositeExtract %uint %GlobalInvocationID 1
-        %190 = OpCompositeExtract %uint %dstSize 0
-        %191 = OpIMul %uint %189 %190
-        %192 = OpCompositeExtract %uint %GlobalInvocationID 0
-%outputIndex = OpIAdd %uint %191 %192
-        %194 = OpLoad %bool %success None
-               OpSelectionMerge %195 None
-               OpBranchConditional %194 %196 %197
-        %196 = OpLabel
-        %198 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %outputIndex
-               OpStore %198 %uint_1 None
-               OpBranch %195
-        %197 = OpLabel
-        %200 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %outputIndex
-               OpStore %200 %uint_0 None
-               OpBranch %195
-        %195 = OpLabel
+        %214 = OpCompositeExtract %uint %GlobalInvocationID 1
+        %215 = OpCompositeExtract %uint %dstSize 0
+        %216 = OpIMul %uint %214 %215
+        %217 = OpCompositeExtract %uint %GlobalInvocationID 0
+%outputIndex = OpIAdd %uint %216 %217
+        %219 = OpLoad %bool %success None
+               OpSelectionMerge %220 None
+               OpBranchConditional %219 %221 %222
+        %221 = OpLabel
+        %223 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %output %uint_0
+        %225 = OpArrayLength %uint %output 0
+        %226 = OpISub %uint %225 %uint_1
+        %227 = OpExtInst %uint %27 UMin %outputIndex %226
+        %228 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %227
+               OpStore %228 %uint_1 None
+               OpBranch %220
+        %222 = OpLabel
+        %230 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %output %uint_0
+        %231 = OpArrayLength %uint %output 0
+        %232 = OpISub %uint %231 %uint_1
+        %233 = OpExtInst %uint %27 UMin %outputIndex %232
+        %234 = OpAccessChain %_ptr_StorageBuffer_uint %output %uint_0 %233
+               OpStore %234 %uint_0 None
+               OpBranch %220
+        %220 = OpLabel
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %202
-        %203 = OpLabel
-        %204 = OpLoad %v3uint %main_global_invocation_id_Input None
-        %205 = OpFunctionCall %void %main_inner %204
+       %main = OpFunction %void None %236
+        %237 = OpLabel
+        %238 = OpLoad %v3uint %main_global_invocation_id_Input None
+        %239 = OpFunctionCall %void %main_inner %238
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl
index 08fa5a4..f54dbee 100644
--- a/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/914.wgsl.expected.dxc.hlsl
@@ -26,7 +26,10 @@
     tint_tmp = (col < uniforms[0].y);
   }
   if ((tint_tmp)) {
-    float result = asfloat(firstMatrix.Load((4u * ((row * uniforms[0].y) + col))));
+    uint tint_symbol_7 = 0u;
+    firstMatrix.GetDimensions(tint_symbol_7);
+    uint tint_symbol_8 = ((tint_symbol_7 - 0u) / 4u);
+    float result = asfloat(firstMatrix.Load((4u * min(((row * uniforms[0].y) + col), (tint_symbol_8 - 1u)))));
     return result;
   }
   return 0.0f;
@@ -38,7 +41,10 @@
     tint_tmp_1 = (col < uniforms[0].z);
   }
   if ((tint_tmp_1)) {
-    float result = asfloat(secondMatrix.Load((4u * ((row * uniforms[0].z) + col))));
+    uint tint_symbol_9 = 0u;
+    secondMatrix.GetDimensions(tint_symbol_9);
+    uint tint_symbol_10 = ((tint_symbol_9 - 0u) / 4u);
+    float result = asfloat(secondMatrix.Load((4u * min(((row * uniforms[0].z) + col), (tint_symbol_10 - 1u)))));
     return result;
   }
   return 0.0f;
@@ -50,8 +56,11 @@
     tint_tmp_2 = (col < uniforms[0].z);
   }
   if ((tint_tmp_2)) {
+    uint tint_symbol_12 = 0u;
+    resultMatrix.GetDimensions(tint_symbol_12);
+    uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 4u);
     uint index = (col + (row * uniforms[0].z));
-    resultMatrix.Store((4u * index), asuint(value));
+    resultMatrix.Store((4u * min(index, (tint_symbol_13 - 1u))), asuint(value));
   }
 }
 
@@ -77,7 +86,7 @@
   float BCached[4] = (float[4])0;
   {
     for(uint index = 0u; (index < 16u); index = (index + 1u)) {
-      acc[index] = 0.0f;
+      acc[min(index, 15u)] = 0.0f;
     }
   }
   uint ColPerThreadA = 4u;
@@ -94,7 +103,7 @@
               uint inputCol = (tileColA + innerCol);
               uint tint_symbol = inputRow;
               uint tint_symbol_1 = inputCol;
-              mm_Asub[tint_symbol][tint_symbol_1] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
+              mm_Asub[min(tint_symbol, 63u)][min(tint_symbol_1, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
             }
           }
         }
@@ -107,7 +116,7 @@
               uint inputCol = (tileCol + innerCol);
               uint tint_symbol_2 = innerCol;
               uint tint_symbol_3 = inputCol;
-              mm_Bsub[tint_symbol_2][tint_symbol_3] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
+              mm_Bsub[min(tint_symbol_2, 63u)][min(tint_symbol_3, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
             }
           }
         }
@@ -117,16 +126,16 @@
         for(uint k = 0u; (k < 64u); k = (k + 1u)) {
           {
             for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) {
-              BCached[inner] = mm_Bsub[k][(tileCol + inner)];
+              BCached[min(inner, 3u)] = mm_Bsub[min(k, 63u)][min((tileCol + inner), 63u)];
             }
           }
           {
             for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
-              ACached = mm_Asub[(tileRow + innerRow)][k];
+              ACached = mm_Asub[min((tileRow + innerRow), 63u)][min(k, 63u)];
               {
                 for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
                   uint index = ((innerRow * 4u) + innerCol);
-                  acc[index] = (acc[index] + (ACached * BCached[innerCol]));
+                  acc[min(index, 15u)] = (acc[min(index, 15u)] + (ACached * BCached[min(innerCol, 3u)]));
                 }
               }
             }
@@ -141,7 +150,7 @@
       {
         for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
           uint index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index]);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)]);
         }
       }
     }
diff --git a/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl
index 08fa5a4..f54dbee 100644
--- a/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/914.wgsl.expected.fxc.hlsl
@@ -26,7 +26,10 @@
     tint_tmp = (col < uniforms[0].y);
   }
   if ((tint_tmp)) {
-    float result = asfloat(firstMatrix.Load((4u * ((row * uniforms[0].y) + col))));
+    uint tint_symbol_7 = 0u;
+    firstMatrix.GetDimensions(tint_symbol_7);
+    uint tint_symbol_8 = ((tint_symbol_7 - 0u) / 4u);
+    float result = asfloat(firstMatrix.Load((4u * min(((row * uniforms[0].y) + col), (tint_symbol_8 - 1u)))));
     return result;
   }
   return 0.0f;
@@ -38,7 +41,10 @@
     tint_tmp_1 = (col < uniforms[0].z);
   }
   if ((tint_tmp_1)) {
-    float result = asfloat(secondMatrix.Load((4u * ((row * uniforms[0].z) + col))));
+    uint tint_symbol_9 = 0u;
+    secondMatrix.GetDimensions(tint_symbol_9);
+    uint tint_symbol_10 = ((tint_symbol_9 - 0u) / 4u);
+    float result = asfloat(secondMatrix.Load((4u * min(((row * uniforms[0].z) + col), (tint_symbol_10 - 1u)))));
     return result;
   }
   return 0.0f;
@@ -50,8 +56,11 @@
     tint_tmp_2 = (col < uniforms[0].z);
   }
   if ((tint_tmp_2)) {
+    uint tint_symbol_12 = 0u;
+    resultMatrix.GetDimensions(tint_symbol_12);
+    uint tint_symbol_13 = ((tint_symbol_12 - 0u) / 4u);
     uint index = (col + (row * uniforms[0].z));
-    resultMatrix.Store((4u * index), asuint(value));
+    resultMatrix.Store((4u * min(index, (tint_symbol_13 - 1u))), asuint(value));
   }
 }
 
@@ -77,7 +86,7 @@
   float BCached[4] = (float[4])0;
   {
     for(uint index = 0u; (index < 16u); index = (index + 1u)) {
-      acc[index] = 0.0f;
+      acc[min(index, 15u)] = 0.0f;
     }
   }
   uint ColPerThreadA = 4u;
@@ -94,7 +103,7 @@
               uint inputCol = (tileColA + innerCol);
               uint tint_symbol = inputRow;
               uint tint_symbol_1 = inputCol;
-              mm_Asub[tint_symbol][tint_symbol_1] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
+              mm_Asub[min(tint_symbol, 63u)][min(tint_symbol_1, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
             }
           }
         }
@@ -107,7 +116,7 @@
               uint inputCol = (tileCol + innerCol);
               uint tint_symbol_2 = innerCol;
               uint tint_symbol_3 = inputCol;
-              mm_Bsub[tint_symbol_2][tint_symbol_3] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
+              mm_Bsub[min(tint_symbol_2, 63u)][min(tint_symbol_3, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
             }
           }
         }
@@ -117,16 +126,16 @@
         for(uint k = 0u; (k < 64u); k = (k + 1u)) {
           {
             for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) {
-              BCached[inner] = mm_Bsub[k][(tileCol + inner)];
+              BCached[min(inner, 3u)] = mm_Bsub[min(k, 63u)][min((tileCol + inner), 63u)];
             }
           }
           {
             for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
-              ACached = mm_Asub[(tileRow + innerRow)][k];
+              ACached = mm_Asub[min((tileRow + innerRow), 63u)][min(k, 63u)];
               {
                 for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
                   uint index = ((innerRow * 4u) + innerCol);
-                  acc[index] = (acc[index] + (ACached * BCached[innerCol]));
+                  acc[min(index, 15u)] = (acc[min(index, 15u)] + (ACached * BCached[min(innerCol, 3u)]));
                 }
               }
             }
@@ -141,7 +150,7 @@
       {
         for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
           uint index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index]);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)]);
         }
       }
     }
diff --git a/test/tint/bug/tint/914.wgsl.expected.glsl b/test/tint/bug/tint/914.wgsl.expected.glsl
index dc1dead..b7ee4ba 100644
--- a/test/tint/bug/tint/914.wgsl.expected.glsl
+++ b/test/tint/bug/tint/914.wgsl.expected.glsl
@@ -34,35 +34,38 @@
   }
   if (v_1) {
     uint v_2 = ((row * v.inner.dimInner) + col);
-    float result = firstMatrix.numbers[v_2];
+    uint v_3 = min(v_2, (uint(firstMatrix.numbers.length()) - 1u));
+    float result = firstMatrix.numbers[v_3];
     return result;
   }
   return 0.0f;
 }
 float mm_readB(uint row, uint col) {
-  bool v_3 = false;
+  bool v_4 = false;
   if ((row < v.inner.dimInner)) {
-    v_3 = (col < v.inner.dimBOuter);
+    v_4 = (col < v.inner.dimBOuter);
   } else {
-    v_3 = false;
+    v_4 = false;
   }
-  if (v_3) {
-    uint v_4 = ((row * v.inner.dimBOuter) + col);
-    float result = secondMatrix.numbers[v_4];
+  if (v_4) {
+    uint v_5 = ((row * v.inner.dimBOuter) + col);
+    uint v_6 = min(v_5, (uint(secondMatrix.numbers.length()) - 1u));
+    float result = secondMatrix.numbers[v_6];
     return result;
   }
   return 0.0f;
 }
 void mm_write(uint row, uint col, float value) {
-  bool v_5 = false;
+  bool v_7 = false;
   if ((row < v.inner.dimAOuter)) {
-    v_5 = (col < v.inner.dimBOuter);
+    v_7 = (col < v.inner.dimBOuter);
   } else {
-    v_5 = false;
+    v_7 = false;
   }
-  if (v_5) {
+  if (v_7) {
     uint index = (col + (row * v.inner.dimBOuter));
-    resultMatrix.numbers[index] = value;
+    uint v_8 = min(index, (uint(resultMatrix.numbers.length()) - 1u));
+    resultMatrix.numbers[v_8] = value;
   }
 }
 uint tint_div_u32(uint lhs, uint rhs) {
@@ -70,17 +73,17 @@
 }
 void tint_symbol_inner(uvec3 local_id, uvec3 global_id, uint tint_local_index) {
   {
-    uint v_6 = 0u;
-    v_6 = tint_local_index;
+    uint v_9 = 0u;
+    v_9 = tint_local_index;
     while(true) {
-      uint v_7 = v_6;
-      if ((v_7 >= 4096u)) {
+      uint v_10 = v_9;
+      if ((v_10 >= 4096u)) {
         break;
       }
-      mm_Asub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
-      mm_Bsub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
+      mm_Asub[(v_10 / 64u)][(v_10 % 64u)] = 0.0f;
+      mm_Bsub[(v_10 / 64u)][(v_10 % 64u)] = 0.0f;
       {
-        v_6 = (v_7 + 256u);
+        v_9 = (v_10 + 256u);
       }
       continue;
     }
@@ -101,8 +104,8 @@
       } else {
         break;
       }
-      uint v_8 = index;
-      acc[v_8] = 0.0f;
+      uint v_11 = min(index, 15u);
+      acc[v_11] = 0.0f;
       {
         index = (index + 1u);
       }
@@ -136,7 +139,7 @@
               }
               uint inputRow = (tileRow + innerRow);
               uint inputCol = (tileColA + innerCol);
-              mm_Asub[inputRow][inputCol] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
+              mm_Asub[min(inputRow, 63u)][min(inputCol, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -165,8 +168,8 @@
               }
               uint inputRow = (tileRowB + innerRow);
               uint inputCol = (tileCol + innerCol);
-              uint v_9 = innerCol;
-              mm_Bsub[v_9][inputCol] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
+              uint v_12 = min(innerCol, 63u);
+              mm_Bsub[v_12][min(inputCol, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -194,10 +197,10 @@
               } else {
                 break;
               }
-              uint v_10 = inner;
-              uint v_11 = k;
-              uint v_12 = (tileCol + inner);
-              BCached[v_10] = mm_Bsub[v_11][v_12];
+              uint v_13 = min(inner, 3u);
+              uint v_14 = min(k, 63u);
+              uint v_15 = min((tileCol + inner), 63u);
+              BCached[v_13] = mm_Bsub[v_14][v_15];
               {
                 inner = (inner + 1u);
               }
@@ -211,9 +214,9 @@
               } else {
                 break;
               }
-              uint v_13 = (tileRow + innerRow);
-              uint v_14 = k;
-              ACached = mm_Asub[v_13][v_14];
+              uint v_16 = min((tileRow + innerRow), 63u);
+              uint v_17 = min(k, 63u);
+              ACached = mm_Asub[v_16][v_17];
               {
                 uint innerCol = 0u;
                 while(true) {
@@ -222,10 +225,10 @@
                     break;
                   }
                   uint index = ((innerRow * 4u) + innerCol);
-                  float v_15 = acc[index];
-                  float v_16 = ACached;
-                  uint v_17 = innerCol;
-                  acc[index] = (v_15 + (v_16 * BCached[v_17]));
+                  float v_18 = acc[min(index, 15u)];
+                  float v_19 = ACached;
+                  uint v_20 = min(innerCol, 3u);
+                  acc[min(index, 15u)] = (v_18 + (v_19 * BCached[v_20]));
                   {
                     innerCol = (innerCol + 1u);
                   }
@@ -266,7 +269,7 @@
             break;
           }
           uint index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index]);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)]);
           {
             innerCol = (innerCol + 1u);
           }
diff --git a/test/tint/bug/tint/914.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.ir.dxc.hlsl
index d1d7ff9..732303e 100644
--- a/test/tint/bug/tint/914.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/914.wgsl.expected.ir.dxc.hlsl
@@ -21,36 +21,42 @@
     v = false;
   }
   if (v) {
-    float result = asfloat(firstMatrix.Load((0u + (((row * uniforms[0u].y) + col) * 4u))));
+    uint v_1 = 0u;
+    firstMatrix.GetDimensions(v_1);
+    float result = asfloat(firstMatrix.Load((0u + (min(((row * uniforms[0u].y) + col), ((v_1 / 4u) - 1u)) * 4u))));
     return result;
   }
   return 0.0f;
 }
 
 float mm_readB(uint row, uint col) {
-  bool v_1 = false;
+  bool v_2 = false;
   if ((row < uniforms[0u].y)) {
-    v_1 = (col < uniforms[0u].z);
+    v_2 = (col < uniforms[0u].z);
   } else {
-    v_1 = false;
+    v_2 = false;
   }
-  if (v_1) {
-    float result = asfloat(secondMatrix.Load((0u + (((row * uniforms[0u].z) + col) * 4u))));
+  if (v_2) {
+    uint v_3 = 0u;
+    secondMatrix.GetDimensions(v_3);
+    float result = asfloat(secondMatrix.Load((0u + (min(((row * uniforms[0u].z) + col), ((v_3 / 4u) - 1u)) * 4u))));
     return result;
   }
   return 0.0f;
 }
 
 void mm_write(uint row, uint col, float value) {
-  bool v_2 = false;
+  bool v_4 = false;
   if ((row < uniforms[0u].x)) {
-    v_2 = (col < uniforms[0u].z);
+    v_4 = (col < uniforms[0u].z);
   } else {
-    v_2 = false;
+    v_4 = false;
   }
-  if (v_2) {
+  if (v_4) {
     uint index = (col + (row * uniforms[0u].z));
-    resultMatrix.Store((0u + (index * 4u)), asuint(value));
+    uint v_5 = 0u;
+    resultMatrix.GetDimensions(v_5);
+    resultMatrix.Store((0u + (min(index, ((v_5 / 4u) - 1u)) * 4u)), asuint(value));
   }
 }
 
@@ -60,17 +66,17 @@
 
 void main_inner(uint3 local_id, uint3 global_id, uint tint_local_index) {
   {
-    uint v_3 = 0u;
-    v_3 = tint_local_index;
+    uint v_6 = 0u;
+    v_6 = tint_local_index;
     while(true) {
-      uint v_4 = v_3;
-      if ((v_4 >= 4096u)) {
+      uint v_7 = v_6;
+      if ((v_7 >= 4096u)) {
         break;
       }
-      mm_Asub[(v_4 / 64u)][(v_4 % 64u)] = 0.0f;
-      mm_Bsub[(v_4 / 64u)][(v_4 % 64u)] = 0.0f;
+      mm_Asub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
+      mm_Bsub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
       {
-        v_3 = (v_4 + 256u);
+        v_6 = (v_7 + 256u);
       }
       continue;
     }
@@ -91,8 +97,8 @@
       } else {
         break;
       }
-      uint v_5 = index;
-      acc[v_5] = 0.0f;
+      uint v_8 = min(index, 15u);
+      acc[v_8] = 0.0f;
       {
         index = (index + 1u);
       }
@@ -126,7 +132,7 @@
               }
               uint inputRow = (tileRow + innerRow);
               uint inputCol = (tileColA + innerCol);
-              mm_Asub[inputRow][inputCol] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
+              mm_Asub[min(inputRow, 63u)][min(inputCol, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -155,8 +161,8 @@
               }
               uint inputRow = (tileRowB + innerRow);
               uint inputCol = (tileCol + innerCol);
-              uint v_6 = innerCol;
-              mm_Bsub[v_6][inputCol] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
+              uint v_9 = min(innerCol, 63u);
+              mm_Bsub[v_9][min(inputCol, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -184,10 +190,10 @@
               } else {
                 break;
               }
-              uint v_7 = inner;
-              uint v_8 = k;
-              uint v_9 = (tileCol + inner);
-              BCached[v_7] = mm_Bsub[v_8][v_9];
+              uint v_10 = min(inner, 3u);
+              uint v_11 = min(k, 63u);
+              uint v_12 = min((tileCol + inner), 63u);
+              BCached[v_10] = mm_Bsub[v_11][v_12];
               {
                 inner = (inner + 1u);
               }
@@ -201,9 +207,9 @@
               } else {
                 break;
               }
-              uint v_10 = (tileRow + innerRow);
-              uint v_11 = k;
-              ACached = mm_Asub[v_10][v_11];
+              uint v_13 = min((tileRow + innerRow), 63u);
+              uint v_14 = min(k, 63u);
+              ACached = mm_Asub[v_13][v_14];
               {
                 uint innerCol = 0u;
                 while(true) {
@@ -212,10 +218,10 @@
                     break;
                   }
                   uint index = ((innerRow * 4u) + innerCol);
-                  float v_12 = acc[index];
-                  float v_13 = ACached;
-                  uint v_14 = innerCol;
-                  acc[index] = (v_12 + (v_13 * BCached[v_14]));
+                  float v_15 = acc[min(index, 15u)];
+                  float v_16 = ACached;
+                  uint v_17 = min(innerCol, 3u);
+                  acc[min(index, 15u)] = (v_15 + (v_16 * BCached[v_17]));
                   {
                     innerCol = (innerCol + 1u);
                   }
@@ -256,7 +262,7 @@
             break;
           }
           uint index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index]);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)]);
           {
             innerCol = (innerCol + 1u);
           }
diff --git a/test/tint/bug/tint/914.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/914.wgsl.expected.ir.fxc.hlsl
index d1d7ff9..732303e 100644
--- a/test/tint/bug/tint/914.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/914.wgsl.expected.ir.fxc.hlsl
@@ -21,36 +21,42 @@
     v = false;
   }
   if (v) {
-    float result = asfloat(firstMatrix.Load((0u + (((row * uniforms[0u].y) + col) * 4u))));
+    uint v_1 = 0u;
+    firstMatrix.GetDimensions(v_1);
+    float result = asfloat(firstMatrix.Load((0u + (min(((row * uniforms[0u].y) + col), ((v_1 / 4u) - 1u)) * 4u))));
     return result;
   }
   return 0.0f;
 }
 
 float mm_readB(uint row, uint col) {
-  bool v_1 = false;
+  bool v_2 = false;
   if ((row < uniforms[0u].y)) {
-    v_1 = (col < uniforms[0u].z);
+    v_2 = (col < uniforms[0u].z);
   } else {
-    v_1 = false;
+    v_2 = false;
   }
-  if (v_1) {
-    float result = asfloat(secondMatrix.Load((0u + (((row * uniforms[0u].z) + col) * 4u))));
+  if (v_2) {
+    uint v_3 = 0u;
+    secondMatrix.GetDimensions(v_3);
+    float result = asfloat(secondMatrix.Load((0u + (min(((row * uniforms[0u].z) + col), ((v_3 / 4u) - 1u)) * 4u))));
     return result;
   }
   return 0.0f;
 }
 
 void mm_write(uint row, uint col, float value) {
-  bool v_2 = false;
+  bool v_4 = false;
   if ((row < uniforms[0u].x)) {
-    v_2 = (col < uniforms[0u].z);
+    v_4 = (col < uniforms[0u].z);
   } else {
-    v_2 = false;
+    v_4 = false;
   }
-  if (v_2) {
+  if (v_4) {
     uint index = (col + (row * uniforms[0u].z));
-    resultMatrix.Store((0u + (index * 4u)), asuint(value));
+    uint v_5 = 0u;
+    resultMatrix.GetDimensions(v_5);
+    resultMatrix.Store((0u + (min(index, ((v_5 / 4u) - 1u)) * 4u)), asuint(value));
   }
 }
 
@@ -60,17 +66,17 @@
 
 void main_inner(uint3 local_id, uint3 global_id, uint tint_local_index) {
   {
-    uint v_3 = 0u;
-    v_3 = tint_local_index;
+    uint v_6 = 0u;
+    v_6 = tint_local_index;
     while(true) {
-      uint v_4 = v_3;
-      if ((v_4 >= 4096u)) {
+      uint v_7 = v_6;
+      if ((v_7 >= 4096u)) {
         break;
       }
-      mm_Asub[(v_4 / 64u)][(v_4 % 64u)] = 0.0f;
-      mm_Bsub[(v_4 / 64u)][(v_4 % 64u)] = 0.0f;
+      mm_Asub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
+      mm_Bsub[(v_7 / 64u)][(v_7 % 64u)] = 0.0f;
       {
-        v_3 = (v_4 + 256u);
+        v_6 = (v_7 + 256u);
       }
       continue;
     }
@@ -91,8 +97,8 @@
       } else {
         break;
       }
-      uint v_5 = index;
-      acc[v_5] = 0.0f;
+      uint v_8 = min(index, 15u);
+      acc[v_8] = 0.0f;
       {
         index = (index + 1u);
       }
@@ -126,7 +132,7 @@
               }
               uint inputRow = (tileRow + innerRow);
               uint inputCol = (tileColA + innerCol);
-              mm_Asub[inputRow][inputCol] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
+              mm_Asub[min(inputRow, 63u)][min(inputCol, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -155,8 +161,8 @@
               }
               uint inputRow = (tileRowB + innerRow);
               uint inputCol = (tileCol + innerCol);
-              uint v_6 = innerCol;
-              mm_Bsub[v_6][inputCol] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
+              uint v_9 = min(innerCol, 63u);
+              mm_Bsub[v_9][min(inputCol, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol));
               {
                 innerCol = (innerCol + 1u);
               }
@@ -184,10 +190,10 @@
               } else {
                 break;
               }
-              uint v_7 = inner;
-              uint v_8 = k;
-              uint v_9 = (tileCol + inner);
-              BCached[v_7] = mm_Bsub[v_8][v_9];
+              uint v_10 = min(inner, 3u);
+              uint v_11 = min(k, 63u);
+              uint v_12 = min((tileCol + inner), 63u);
+              BCached[v_10] = mm_Bsub[v_11][v_12];
               {
                 inner = (inner + 1u);
               }
@@ -201,9 +207,9 @@
               } else {
                 break;
               }
-              uint v_10 = (tileRow + innerRow);
-              uint v_11 = k;
-              ACached = mm_Asub[v_10][v_11];
+              uint v_13 = min((tileRow + innerRow), 63u);
+              uint v_14 = min(k, 63u);
+              ACached = mm_Asub[v_13][v_14];
               {
                 uint innerCol = 0u;
                 while(true) {
@@ -212,10 +218,10 @@
                     break;
                   }
                   uint index = ((innerRow * 4u) + innerCol);
-                  float v_12 = acc[index];
-                  float v_13 = ACached;
-                  uint v_14 = innerCol;
-                  acc[index] = (v_12 + (v_13 * BCached[v_14]));
+                  float v_15 = acc[min(index, 15u)];
+                  float v_16 = ACached;
+                  uint v_17 = min(innerCol, 3u);
+                  acc[min(index, 15u)] = (v_15 + (v_16 * BCached[v_17]));
                   {
                     innerCol = (innerCol + 1u);
                   }
@@ -256,7 +262,7 @@
             break;
           }
           uint index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index]);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)]);
           {
             innerCol = (innerCol + 1u);
           }
diff --git a/test/tint/bug/tint/914.wgsl.expected.ir.msl b/test/tint/bug/tint/914.wgsl.expected.ir.msl
index 0745782..03ad930 100644
--- a/test/tint/bug/tint/914.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/914.wgsl.expected.ir.msl
@@ -30,8 +30,12 @@
   const constant Uniforms* uniforms;
   threadgroup tint_array<tint_array<float, 64>, 64>* mm_Asub;
   threadgroup tint_array<tint_array<float, 64>, 64>* mm_Bsub;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_3 {
   tint_array<tint_array<float, 64>, 64> tint_symbol_1;
   tint_array<tint_array<float, 64>, 64> tint_symbol_2;
@@ -45,7 +49,7 @@
     v = false;
   }
   if (v) {
-    float const result = (*tint_module_vars.firstMatrix).numbers[((row * (*tint_module_vars.uniforms).dimInner) + col)];
+    float const result = (*tint_module_vars.firstMatrix).numbers[min(((row * (*tint_module_vars.uniforms).dimInner) + col), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))];
     return result;
   }
   return 0.0f;
@@ -59,7 +63,7 @@
     v_1 = false;
   }
   if (v_1) {
-    float const result = (*tint_module_vars.secondMatrix).numbers[((row * (*tint_module_vars.uniforms).dimBOuter) + col)];
+    float const result = (*tint_module_vars.secondMatrix).numbers[min(((row * (*tint_module_vars.uniforms).dimBOuter) + col), ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][1u] - 0u) / 4u) - 1u))];
     return result;
   }
   return 0.0f;
@@ -74,7 +78,7 @@
   }
   if (v_2) {
     uint const index = (col + (row * (*tint_module_vars.uniforms).dimBOuter));
-    (*tint_module_vars.resultMatrix).numbers[index] = value;
+    (*tint_module_vars.resultMatrix).numbers[min(index, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][2u] - 0u) / 4u) - 1u))] = value;
   }
 }
 
@@ -87,6 +91,7 @@
     uint v_3 = 0u;
     v_3 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_4 = v_3;
       if ((v_4 >= 4096u)) {
         break;
@@ -115,7 +120,7 @@
       } else {
         break;
       }
-      acc[index] = 0.0f;
+      acc[min(index, 15u)] = 0.0f;
       {
         index = (index + 1u);
       }
@@ -149,7 +154,7 @@
               }
               uint const inputRow = (tileRow + innerRow);
               uint const inputCol = (tileColA + innerCol);
-              (*tint_module_vars.mm_Asub)[inputRow][inputCol] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_module_vars);
+              (*tint_module_vars.mm_Asub)[min(inputRow, 63u)][min(inputCol, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_module_vars);
               {
                 innerCol = (innerCol + 1u);
               }
@@ -178,7 +183,7 @@
               }
               uint const inputRow = (tileRowB + innerRow);
               uint const inputCol = (tileCol + innerCol);
-              threadgroup float* const v_5 = (&(*tint_module_vars.mm_Bsub)[innerCol][inputCol]);
+              threadgroup float* const v_5 = (&(*tint_module_vars.mm_Bsub)[min(innerCol, 63u)][min(inputCol, 63u)]);
               (*v_5) = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_module_vars);
               {
                 innerCol = (innerCol + 1u);
@@ -207,7 +212,7 @@
               } else {
                 break;
               }
-              BCached[inner] = (*tint_module_vars.mm_Bsub)[k][(tileCol + inner)];
+              BCached[min(inner, 3u)] = (*tint_module_vars.mm_Bsub)[min(k, 63u)][min((tileCol + inner), 63u)];
               {
                 inner = (inner + 1u);
               }
@@ -221,7 +226,7 @@
               } else {
                 break;
               }
-              ACached = (*tint_module_vars.mm_Asub)[(tileRow + innerRow)][k];
+              ACached = (*tint_module_vars.mm_Asub)[min((tileRow + innerRow), 63u)][min(k, 63u)];
               {
                 uint innerCol = 0u;
                 while(true) {
@@ -230,7 +235,7 @@
                     break;
                   }
                   uint const index = ((innerRow * 4u) + innerCol);
-                  acc[index] = (acc[index] + (ACached * BCached[innerCol]));
+                  acc[min(index, 15u)] = (acc[min(index, 15u)] + (ACached * BCached[min(innerCol, 3u)]));
                   {
                     innerCol = (innerCol + 1u);
                   }
@@ -271,7 +276,7 @@
             break;
           }
           uint const index = ((innerRow * 4u) + innerCol);
-          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_module_vars);
+          mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)], tint_module_vars);
           {
             innerCol = (innerCol + 1u);
           }
@@ -286,7 +291,7 @@
   }
 }
 
-kernel void tint_symbol(uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint tint_local_index [[thread_index_in_threadgroup]], const device Matrix* firstMatrix [[buffer(2)]], const device Matrix* secondMatrix [[buffer(3)]], device Matrix* resultMatrix [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]], threadgroup tint_symbol_3* v_6 [[threadgroup(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.firstMatrix=firstMatrix, .secondMatrix=secondMatrix, .resultMatrix=resultMatrix, .uniforms=uniforms, .mm_Asub=(&(*v_6).tint_symbol_1), .mm_Bsub=(&(*v_6).tint_symbol_2)};
+kernel void tint_symbol(uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint tint_local_index [[thread_index_in_threadgroup]], const device Matrix* firstMatrix [[buffer(2)]], const device Matrix* secondMatrix [[buffer(3)]], device Matrix* resultMatrix [[buffer(1)]], const constant Uniforms* uniforms [[buffer(0)]], threadgroup tint_symbol_3* v_6 [[threadgroup(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.firstMatrix=firstMatrix, .secondMatrix=secondMatrix, .resultMatrix=resultMatrix, .uniforms=uniforms, .mm_Asub=(&(*v_6).tint_symbol_1), .mm_Bsub=(&(*v_6).tint_symbol_2), .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(local_id, global_id, tint_local_index, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/914.wgsl.expected.msl b/test/tint/bug/tint/914.wgsl.expected.msl
index e267a94..459b88a 100644
--- a/test/tint/bug/tint/914.wgsl.expected.msl
+++ b/test/tint/bug/tint/914.wgsl.expected.msl
@@ -14,8 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_5, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_6) {
   for(uint idx = local_idx; (idx < 4096u); idx = (idx + 256u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx / 64u);
     uint const i_1 = (idx % 64u);
     (*(tint_symbol_5))[i][i_1] = 0.0f;
@@ -34,26 +42,26 @@
   /* 0x0000 */ tint_array<float, 1> numbers;
 };
 
-float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_7, const device Matrix* const tint_symbol_8) {
+float mm_readA(uint row, uint col, const constant Uniforms* const tint_symbol_7, const device Matrix* const tint_symbol_8, const constant TintArrayLengths* const tint_symbol_9) {
   if (((row < (*(tint_symbol_7)).dimAOuter) && (col < (*(tint_symbol_7)).dimInner))) {
-    float const result = (*(tint_symbol_8)).numbers[((row * (*(tint_symbol_7)).dimInner) + col)];
+    float const result = (*(tint_symbol_8)).numbers[min(((row * (*(tint_symbol_7)).dimInner) + col), ((((*(tint_symbol_9)).array_lengths[0u][0u] - 0u) / 4u) - 1u))];
     return result;
   }
   return 0.0f;
 }
 
-float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_9, const device Matrix* const tint_symbol_10) {
-  if (((row < (*(tint_symbol_9)).dimInner) && (col < (*(tint_symbol_9)).dimBOuter))) {
-    float const result = (*(tint_symbol_10)).numbers[((row * (*(tint_symbol_9)).dimBOuter) + col)];
+float mm_readB(uint row, uint col, const constant Uniforms* const tint_symbol_10, const device Matrix* const tint_symbol_11, const constant TintArrayLengths* const tint_symbol_12) {
+  if (((row < (*(tint_symbol_10)).dimInner) && (col < (*(tint_symbol_10)).dimBOuter))) {
+    float const result = (*(tint_symbol_11)).numbers[min(((row * (*(tint_symbol_10)).dimBOuter) + col), ((((*(tint_symbol_12)).array_lengths[0u][1u] - 0u) / 4u) - 1u))];
     return result;
   }
   return 0.0f;
 }
 
-void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_11, device Matrix* const tint_symbol_12) {
-  if (((row < (*(tint_symbol_11)).dimAOuter) && (col < (*(tint_symbol_11)).dimBOuter))) {
-    uint const index = (col + (row * (*(tint_symbol_11)).dimBOuter));
-    (*(tint_symbol_12)).numbers[index] = value;
+void mm_write(uint row, uint col, float value, const constant Uniforms* const tint_symbol_13, device Matrix* const tint_symbol_14, const constant TintArrayLengths* const tint_symbol_15) {
+  if (((row < (*(tint_symbol_13)).dimAOuter) && (col < (*(tint_symbol_13)).dimBOuter))) {
+    uint const index = (col + (row * (*(tint_symbol_13)).dimBOuter));
+    (*(tint_symbol_14)).numbers[min(index, ((((*(tint_symbol_15)).array_lengths[0u][2u] - 0u) / 4u) - 1u))] = value;
   }
 }
 
@@ -61,69 +69,81 @@
   return (lhs / select(rhs, 1u, (rhs == 0u)));
 }
 
-void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_13, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_14, const constant Uniforms* const tint_symbol_15, const device Matrix* const tint_symbol_16, const device Matrix* const tint_symbol_17, device Matrix* const tint_symbol_18) {
-  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_13, tint_symbol_14);
+void tint_symbol_inner(uint3 local_id, uint3 global_id, uint local_invocation_index, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_16, threadgroup tint_array<tint_array<float, 64>, 64>* const tint_symbol_17, const constant Uniforms* const tint_symbol_18, const device Matrix* const tint_symbol_19, const constant TintArrayLengths* const tint_symbol_20, const device Matrix* const tint_symbol_21, device Matrix* const tint_symbol_22) {
+  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_16, tint_symbol_17);
   uint const tileRow = (local_id[1] * 4u);
   uint const tileCol = (local_id[0] * 4u);
   uint const globalRow = (global_id[1] * 4u);
   uint const globalCol = (global_id[0] * 4u);
-  uint const numTiles = (tint_div(((*(tint_symbol_15)).dimInner - 1u), 64u) + 1u);
+  uint const numTiles = (tint_div(((*(tint_symbol_18)).dimInner - 1u), 64u) + 1u);
   tint_array<float, 16> acc = {};
   float ACached = 0.0f;
   tint_array<float, 4> BCached = {};
   for(uint index = 0u; (index < 16u); index = (index + 1u)) {
-    acc[index] = 0.0f;
+    TINT_ISOLATE_UB(tint_volatile_false_1);
+    acc[min(index, 15u)] = 0.0f;
   }
   uint const ColPerThreadA = 4u;
   uint const tileColA = (local_id[0] * ColPerThreadA);
   uint const RowPerThreadB = 4u;
   uint const tileRowB = (local_id[1] * RowPerThreadB);
   for(uint t = 0u; (t < numTiles); t = (t + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false_2);
     for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_3);
       for(uint innerCol = 0u; (innerCol < ColPerThreadA); innerCol = (innerCol + 1u)) {
+        TINT_ISOLATE_UB(tint_volatile_false_4);
         uint const inputRow = (tileRow + innerRow);
         uint const inputCol = (tileColA + innerCol);
         uint const tint_symbol_1 = inputRow;
         uint const tint_symbol_2 = inputCol;
-        (*(tint_symbol_13))[tint_symbol_1][tint_symbol_2] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_15, tint_symbol_16);
+        (*(tint_symbol_16))[min(tint_symbol_1, 63u)][min(tint_symbol_2, 63u)] = mm_readA((globalRow + innerRow), ((t * 64u) + inputCol), tint_symbol_18, tint_symbol_19, tint_symbol_20);
       }
     }
     for(uint innerRow = 0u; (innerRow < RowPerThreadB); innerRow = (innerRow + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_5);
       for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
+        TINT_ISOLATE_UB(tint_volatile_false_6);
         uint const inputRow = (tileRowB + innerRow);
         uint const inputCol = (tileCol + innerCol);
         uint const tint_symbol_3 = innerCol;
         uint const tint_symbol_4 = inputCol;
-        (*(tint_symbol_14))[tint_symbol_3][tint_symbol_4] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_15, tint_symbol_17);
+        (*(tint_symbol_17))[min(tint_symbol_3, 63u)][min(tint_symbol_4, 63u)] = mm_readB(((t * 64u) + inputRow), (globalCol + innerCol), tint_symbol_18, tint_symbol_21, tint_symbol_20);
       }
     }
     threadgroup_barrier(mem_flags::mem_threadgroup);
     for(uint k = 0u; (k < 64u); k = (k + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_7);
       for(uint inner = 0u; (inner < 4u); inner = (inner + 1u)) {
-        BCached[inner] = (*(tint_symbol_14))[k][(tileCol + inner)];
+        TINT_ISOLATE_UB(tint_volatile_false_8);
+        BCached[min(inner, 3u)] = (*(tint_symbol_17))[min(k, 63u)][min((tileCol + inner), 63u)];
       }
       for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
-        ACached = (*(tint_symbol_13))[(tileRow + innerRow)][k];
+        TINT_ISOLATE_UB(tint_volatile_false_9);
+        ACached = (*(tint_symbol_16))[min((tileRow + innerRow), 63u)][min(k, 63u)];
         for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
+          TINT_ISOLATE_UB(tint_volatile_false_10);
           uint const index = ((innerRow * 4u) + innerCol);
-          acc[index] = (acc[index] + (ACached * BCached[innerCol]));
+          acc[min(index, 15u)] = (acc[min(index, 15u)] + (ACached * BCached[min(innerCol, 3u)]));
         }
       }
     }
     threadgroup_barrier(mem_flags::mem_threadgroup);
   }
   for(uint innerRow = 0u; (innerRow < 4u); innerRow = (innerRow + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false_11);
     for(uint innerCol = 0u; (innerCol < 4u); innerCol = (innerCol + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_12);
       uint const index = ((innerRow * 4u) + innerCol);
-      mm_write((globalRow + innerRow), (globalCol + innerCol), acc[index], tint_symbol_15, tint_symbol_18);
+      mm_write((globalRow + innerRow), (globalCol + innerCol), acc[min(index, 15u)], tint_symbol_18, tint_symbol_22, tint_symbol_20);
     }
   }
 }
 
-kernel void tint_symbol(const constant Uniforms* tint_symbol_21 [[buffer(0)]], const device Matrix* tint_symbol_22 [[buffer(2)]], const device Matrix* tint_symbol_23 [[buffer(3)]], device Matrix* tint_symbol_24 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
-  threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_19;
-  threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_20;
-  tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_19), &(tint_symbol_20), tint_symbol_21, tint_symbol_22, tint_symbol_23, tint_symbol_24);
+kernel void tint_symbol(const constant Uniforms* tint_symbol_25 [[buffer(0)]], const device Matrix* tint_symbol_26 [[buffer(2)]], const constant TintArrayLengths* tint_symbol_27 [[buffer(30)]], const device Matrix* tint_symbol_28 [[buffer(3)]], device Matrix* tint_symbol_29 [[buffer(1)]], uint3 local_id [[thread_position_in_threadgroup]], uint3 global_id [[thread_position_in_grid]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
+  threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_23;
+  threadgroup tint_array<tint_array<float, 64>, 64> tint_symbol_24;
+  tint_symbol_inner(local_id, global_id, local_invocation_index, &(tint_symbol_23), &(tint_symbol_24), tint_symbol_25, tint_symbol_26, tint_symbol_27, tint_symbol_28, tint_symbol_29);
   return;
 }
 
diff --git a/test/tint/bug/tint/914.wgsl.expected.spvasm b/test/tint/bug/tint/914.wgsl.expected.spvasm
index f8e69eb..7400da8 100644
--- a/test/tint/bug/tint/914.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/914.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 398
+; Bound: 430
 ; Schema: 0
                OpCapability Shader
+         %63 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_id_Input %main_global_invocation_id_Input %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 16 16 1
@@ -140,13 +141,15 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
       %false = OpConstantFalse %bool
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
     %float_0 = OpConstant %float 0
      %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
-        %100 = OpTypeFunction %void %uint %uint %float
+        %110 = OpTypeFunction %void %uint %uint %float
+%_ptr_StorageBuffer__runtimearr_float_0 = OpTypePointer StorageBuffer %_runtimearr_float
 %_ptr_StorageBuffer_float_0 = OpTypePointer StorageBuffer %float
-        %124 = OpTypeFunction %void %v3uint %v3uint %uint
+        %139 = OpTypeFunction %void %v3uint %v3uint %uint
   %uint_4096 = OpConstant %uint 4096
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
    %uint_256 = OpConstant %uint 256
@@ -155,13 +158,16 @@
     %uint_16 = OpConstant %uint 16
 %_arr_float_uint_16 = OpTypeArray %float %uint_16
 %_ptr_Function__arr_float_uint_16 = OpTypePointer Function %_arr_float_uint_16
-        %166 = OpConstantNull %_arr_float_uint_16
+        %181 = OpConstantNull %_arr_float_uint_16
 %_arr_float_ColPerThreadA = OpTypeArray %float %ColPerThreadA
 %_ptr_Function__arr_float_ColPerThreadA = OpTypePointer Function %_arr_float_ColPerThreadA
-        %171 = OpConstantNull %_arr_float_ColPerThreadA
+        %186 = OpConstantNull %_arr_float_ColPerThreadA
 %_ptr_Function_uint = OpTypePointer Function %uint
-        %386 = OpTypeFunction %uint %uint %uint
-        %392 = OpTypeFunction %void
+    %uint_15 = OpConstant %uint 15
+    %uint_63 = OpConstant %uint 63
+     %uint_3 = OpConstant %uint 3
+        %418 = OpTypeFunction %uint %uint %uint
+        %424 = OpTypeFunction %void
    %mm_readA = OpFunction %float None %29
         %row = OpFunctionParameter %uint
         %col = OpFunctionParameter %uint
@@ -190,106 +196,118 @@
          %55 = OpLoad %uint %54 None
          %56 = OpIMul %uint %row %55
          %57 = OpIAdd %uint %56 %col
-         %58 = OpAccessChain %_ptr_StorageBuffer_float %firstMatrix %uint_0 %57
-     %result = OpLoad %float %58 None
+         %58 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %firstMatrix %uint_0
+         %60 = OpArrayLength %uint %firstMatrix 0
+         %61 = OpISub %uint %60 %uint_1
+         %62 = OpExtInst %uint %63 UMin %57 %61
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %firstMatrix %uint_0 %62
+     %result = OpLoad %float %64 None
                OpStore %continue_execution %false None
                OpStore %return_value %result None
                OpBranch %52
          %52 = OpLabel
-         %61 = OpLoad %bool %continue_execution None
-               OpSelectionMerge %62 None
-               OpBranchConditional %61 %63 %62
-         %63 = OpLabel
+         %67 = OpLoad %bool %continue_execution None
+               OpSelectionMerge %68 None
+               OpBranchConditional %67 %69 %68
+         %69 = OpLabel
                OpStore %return_value %float_0 None
-               OpBranch %62
-         %62 = OpLabel
-         %65 = OpLoad %float %return_value None
-               OpReturnValue %65
+               OpBranch %68
+         %68 = OpLabel
+         %71 = OpLoad %float %return_value None
+               OpReturnValue %71
                OpFunctionEnd
    %mm_readB = OpFunction %float None %29
       %row_0 = OpFunctionParameter %uint
       %col_0 = OpFunctionParameter %uint
-         %69 = OpLabel
+         %75 = OpLabel
 %return_value_0 = OpVariable %_ptr_Function_float Function %33
 %continue_execution_0 = OpVariable %_ptr_Function_bool Function
                OpStore %continue_execution_0 %true
-         %72 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_1
-         %73 = OpLoad %uint %72 None
-         %74 = OpULessThan %bool %row_0 %73
-               OpSelectionMerge %75 None
-               OpBranchConditional %74 %76 %77
-         %76 = OpLabel
-         %78 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
-         %80 = OpLoad %uint %78 None
-         %81 = OpULessThan %bool %col_0 %80
-               OpBranch %75
-         %77 = OpLabel
-               OpBranch %75
-         %75 = OpLabel
-         %82 = OpPhi %bool %81 %76 %false %77
-               OpSelectionMerge %83 None
-               OpBranchConditional %82 %84 %83
-         %84 = OpLabel
-         %85 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
-         %86 = OpLoad %uint %85 None
-         %87 = OpIMul %uint %row_0 %86
-         %88 = OpIAdd %uint %87 %col_0
-         %89 = OpAccessChain %_ptr_StorageBuffer_float %secondMatrix %uint_0 %88
-   %result_0 = OpLoad %float %89 None
+         %78 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_1
+         %79 = OpLoad %uint %78 None
+         %80 = OpULessThan %bool %row_0 %79
+               OpSelectionMerge %81 None
+               OpBranchConditional %80 %82 %83
+         %82 = OpLabel
+         %84 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
+         %86 = OpLoad %uint %84 None
+         %87 = OpULessThan %bool %col_0 %86
+               OpBranch %81
+         %83 = OpLabel
+               OpBranch %81
+         %81 = OpLabel
+         %88 = OpPhi %bool %87 %82 %false %83
+               OpSelectionMerge %89 None
+               OpBranchConditional %88 %90 %89
+         %90 = OpLabel
+         %91 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
+         %92 = OpLoad %uint %91 None
+         %93 = OpIMul %uint %row_0 %92
+         %94 = OpIAdd %uint %93 %col_0
+         %95 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %secondMatrix %uint_0
+         %96 = OpArrayLength %uint %secondMatrix 0
+         %97 = OpISub %uint %96 %uint_1
+         %98 = OpExtInst %uint %63 UMin %94 %97
+         %99 = OpAccessChain %_ptr_StorageBuffer_float %secondMatrix %uint_0 %98
+   %result_0 = OpLoad %float %99 None
                OpStore %continue_execution_0 %false None
                OpStore %return_value_0 %result_0 None
-               OpBranch %83
-         %83 = OpLabel
-         %91 = OpLoad %bool %continue_execution_0 None
-               OpSelectionMerge %92 None
-               OpBranchConditional %91 %93 %92
-         %93 = OpLabel
+               OpBranch %89
+         %89 = OpLabel
+        %101 = OpLoad %bool %continue_execution_0 None
+               OpSelectionMerge %102 None
+               OpBranchConditional %101 %103 %102
+        %103 = OpLabel
                OpStore %return_value_0 %float_0 None
-               OpBranch %92
-         %92 = OpLabel
-         %94 = OpLoad %float %return_value_0 None
-               OpReturnValue %94
+               OpBranch %102
+        %102 = OpLabel
+        %104 = OpLoad %float %return_value_0 None
+               OpReturnValue %104
                OpFunctionEnd
-   %mm_write = OpFunction %void None %100
+   %mm_write = OpFunction %void None %110
       %row_1 = OpFunctionParameter %uint
       %col_1 = OpFunctionParameter %uint
       %value = OpFunctionParameter %float
-        %101 = OpLabel
-        %102 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_0
-        %103 = OpLoad %uint %102 None
-        %104 = OpULessThan %bool %row_1 %103
-               OpSelectionMerge %105 None
-               OpBranchConditional %104 %106 %107
-        %106 = OpLabel
-        %108 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
-        %109 = OpLoad %uint %108 None
-        %110 = OpULessThan %bool %col_1 %109
-               OpBranch %105
-        %107 = OpLabel
-               OpBranch %105
-        %105 = OpLabel
-        %111 = OpPhi %bool %110 %106 %false %107
-               OpSelectionMerge %112 None
-               OpBranchConditional %111 %113 %112
-        %113 = OpLabel
-        %114 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
-        %115 = OpLoad %uint %114 None
-        %116 = OpIMul %uint %row_1 %115
-      %index = OpIAdd %uint %col_1 %116
-        %118 = OpAccessChain %_ptr_StorageBuffer_float_0 %resultMatrix %uint_0 %index
-               OpStore %118 %value None
-               OpBranch %112
-        %112 = OpLabel
+        %111 = OpLabel
+        %112 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_0
+        %113 = OpLoad %uint %112 None
+        %114 = OpULessThan %bool %row_1 %113
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %117
+        %116 = OpLabel
+        %118 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
+        %119 = OpLoad %uint %118 None
+        %120 = OpULessThan %bool %col_1 %119
+               OpBranch %115
+        %117 = OpLabel
+               OpBranch %115
+        %115 = OpLabel
+        %121 = OpPhi %bool %120 %116 %false %117
+               OpSelectionMerge %122 None
+               OpBranchConditional %121 %123 %122
+        %123 = OpLabel
+        %124 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_2
+        %125 = OpLoad %uint %124 None
+        %126 = OpIMul %uint %row_1 %125
+      %index = OpIAdd %uint %col_1 %126
+        %128 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float_0 %resultMatrix %uint_0
+        %130 = OpArrayLength %uint %resultMatrix 0
+        %131 = OpISub %uint %130 %uint_1
+        %132 = OpExtInst %uint %63 UMin %index %131
+        %133 = OpAccessChain %_ptr_StorageBuffer_float_0 %resultMatrix %uint_0 %132
+               OpStore %133 %value None
+               OpBranch %122
+        %122 = OpLabel
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %124
+ %main_inner = OpFunction %void None %139
    %local_id = OpFunctionParameter %v3uint
   %global_id = OpFunctionParameter %v3uint
 %tint_local_index = OpFunctionParameter %uint
-        %125 = OpLabel
-        %acc = OpVariable %_ptr_Function__arr_float_uint_16 Function %166
+        %140 = OpLabel
+        %acc = OpVariable %_ptr_Function__arr_float_uint_16 Function %181
     %ACached = OpVariable %_ptr_Function_float Function %33
-    %BCached = OpVariable %_ptr_Function__arr_float_ColPerThreadA Function %171
+    %BCached = OpVariable %_ptr_Function__arr_float_ColPerThreadA Function %186
     %index_0 = OpVariable %_ptr_Function_uint Function
           %t = OpVariable %_ptr_Function_uint Function
    %innerRow = OpVariable %_ptr_Function_uint Function
@@ -302,400 +320,414 @@
  %innerCol_1 = OpVariable %_ptr_Function_uint Function
  %innerRow_2 = OpVariable %_ptr_Function_uint Function
  %innerCol_2 = OpVariable %_ptr_Function_uint Function
-               OpBranch %126
-        %126 = OpLabel
-               OpBranch %129
-        %129 = OpLabel
-        %131 = OpPhi %uint %tint_local_index %126 %132 %128
-               OpLoopMerge %130 %128 None
-               OpBranch %127
-        %127 = OpLabel
-        %133 = OpUGreaterThanEqual %bool %131 %uint_4096
-               OpSelectionMerge %135 None
-               OpBranchConditional %133 %136 %135
-        %136 = OpLabel
-               OpBranch %130
-        %135 = OpLabel
-        %137 = OpUMod %uint %131 %uint_64
-        %138 = OpUDiv %uint %131 %uint_64
-        %139 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %138 %137
-               OpStore %139 %float_0 None
-        %141 = OpUMod %uint %131 %uint_64
-        %142 = OpUDiv %uint %131 %uint_64
-        %143 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %142 %141
-               OpStore %143 %float_0 None
-               OpBranch %128
-        %128 = OpLabel
-        %132 = OpIAdd %uint %131 %uint_256
-               OpBranch %129
-        %130 = OpLabel
+               OpBranch %141
+        %141 = OpLabel
+               OpBranch %144
+        %144 = OpLabel
+        %146 = OpPhi %uint %tint_local_index %141 %147 %143
+               OpLoopMerge %145 %143 None
+               OpBranch %142
+        %142 = OpLabel
+        %148 = OpUGreaterThanEqual %bool %146 %uint_4096
+               OpSelectionMerge %150 None
+               OpBranchConditional %148 %151 %150
+        %151 = OpLabel
+               OpBranch %145
+        %150 = OpLabel
+        %152 = OpUMod %uint %146 %uint_64
+        %153 = OpUDiv %uint %146 %uint_64
+        %154 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %153 %152
+               OpStore %154 %float_0 None
+        %156 = OpUMod %uint %146 %uint_64
+        %157 = OpUDiv %uint %146 %uint_64
+        %158 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %157 %156
+               OpStore %158 %float_0 None
+               OpBranch %143
+        %143 = OpLabel
+        %147 = OpIAdd %uint %146 %uint_256
+               OpBranch %144
+        %145 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-        %147 = OpCompositeExtract %uint %local_id 1
-    %tileRow = OpIMul %uint %147 %ColPerThreadA
-        %150 = OpCompositeExtract %uint %local_id 0
-    %tileCol = OpIMul %uint %150 %ColPerThreadA
-        %152 = OpCompositeExtract %uint %global_id 1
-  %globalRow = OpIMul %uint %152 %ColPerThreadA
-        %154 = OpCompositeExtract %uint %global_id 0
-  %globalCol = OpIMul %uint %154 %ColPerThreadA
-        %156 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_1
-        %157 = OpLoad %uint %156 None
-        %158 = OpISub %uint %157 %uint_1
-        %159 = OpFunctionCall %uint %tint_div_u32 %158 %uint_64
-   %numTiles = OpIAdd %uint %159 %uint_1
-               OpBranch %172
-        %172 = OpLabel
+        %162 = OpCompositeExtract %uint %local_id 1
+    %tileRow = OpIMul %uint %162 %ColPerThreadA
+        %165 = OpCompositeExtract %uint %local_id 0
+    %tileCol = OpIMul %uint %165 %ColPerThreadA
+        %167 = OpCompositeExtract %uint %global_id 1
+  %globalRow = OpIMul %uint %167 %ColPerThreadA
+        %169 = OpCompositeExtract %uint %global_id 0
+  %globalCol = OpIMul %uint %169 %ColPerThreadA
+        %171 = OpAccessChain %_ptr_Uniform_uint %9 %uint_0 %uint_1
+        %172 = OpLoad %uint %171 None
+        %173 = OpISub %uint %172 %uint_1
+        %174 = OpFunctionCall %uint %tint_div_u32 %173 %uint_64
+   %numTiles = OpIAdd %uint %174 %uint_1
+               OpBranch %187
+        %187 = OpLabel
                OpStore %index_0 %uint_0
-               OpBranch %175
-        %175 = OpLabel
-               OpLoopMerge %176 %174 None
-               OpBranch %173
-        %173 = OpLabel
-        %179 = OpLoad %uint %index_0 None
-        %180 = OpULessThan %bool %179 %uint_16
-               OpSelectionMerge %181 None
-               OpBranchConditional %180 %181 %182
-        %182 = OpLabel
-               OpBranch %176
-        %181 = OpLabel
-        %183 = OpLoad %uint %index_0 None
-        %184 = OpAccessChain %_ptr_Function_float %acc %183
-               OpStore %184 %float_0 None
-               OpBranch %174
-        %174 = OpLabel
-        %185 = OpLoad %uint %index_0 None
-        %186 = OpIAdd %uint %185 %uint_1
-               OpStore %index_0 %186 None
-               OpBranch %175
-        %176 = OpLabel
-        %187 = OpCompositeExtract %uint %local_id 0
-   %tileColA = OpIMul %uint %187 %ColPerThreadA
-        %189 = OpCompositeExtract %uint %local_id 1
-   %tileRowB = OpIMul %uint %189 %ColPerThreadA
+               OpBranch %190
+        %190 = OpLabel
+               OpLoopMerge %191 %189 None
+               OpBranch %188
+        %188 = OpLabel
+        %194 = OpLoad %uint %index_0 None
+        %195 = OpULessThan %bool %194 %uint_16
+               OpSelectionMerge %196 None
+               OpBranchConditional %195 %196 %197
+        %197 = OpLabel
                OpBranch %191
+        %196 = OpLabel
+        %198 = OpLoad %uint %index_0 None
+        %199 = OpExtInst %uint %63 UMin %198 %uint_15
+        %201 = OpAccessChain %_ptr_Function_float %acc %199
+               OpStore %201 %float_0 None
+               OpBranch %189
+        %189 = OpLabel
+        %202 = OpLoad %uint %index_0 None
+        %203 = OpIAdd %uint %202 %uint_1
+               OpStore %index_0 %203 None
+               OpBranch %190
         %191 = OpLabel
+        %204 = OpCompositeExtract %uint %local_id 0
+   %tileColA = OpIMul %uint %204 %ColPerThreadA
+        %206 = OpCompositeExtract %uint %local_id 1
+   %tileRowB = OpIMul %uint %206 %ColPerThreadA
+               OpBranch %208
+        %208 = OpLabel
                OpStore %t %uint_0
-               OpBranch %194
-        %194 = OpLabel
-               OpLoopMerge %195 %193 None
-               OpBranch %192
-        %192 = OpLabel
-        %197 = OpLoad %uint %t None
-        %198 = OpULessThan %bool %197 %numTiles
-               OpSelectionMerge %199 None
-               OpBranchConditional %198 %199 %200
-        %200 = OpLabel
-               OpBranch %195
-        %199 = OpLabel
-               OpBranch %201
-        %201 = OpLabel
-               OpStore %innerRow %uint_0
-               OpBranch %204
-        %204 = OpLabel
-               OpLoopMerge %205 %203 None
-               OpBranch %202
-        %202 = OpLabel
-        %207 = OpLoad %uint %innerRow None
-        %208 = OpULessThan %bool %207 %ColPerThreadA
-               OpSelectionMerge %209 None
-               OpBranchConditional %208 %209 %210
-        %210 = OpLabel
-               OpBranch %205
-        %209 = OpLabel
                OpBranch %211
         %211 = OpLabel
-               OpStore %innerCol %uint_0
-               OpBranch %214
-        %214 = OpLabel
-               OpLoopMerge %215 %213 None
+               OpLoopMerge %212 %210 None
+               OpBranch %209
+        %209 = OpLabel
+        %214 = OpLoad %uint %t None
+        %215 = OpULessThan %bool %214 %numTiles
+               OpSelectionMerge %216 None
+               OpBranchConditional %215 %216 %217
+        %217 = OpLabel
                OpBranch %212
-        %212 = OpLabel
-        %217 = OpLoad %uint %innerCol None
-        %218 = OpULessThan %bool %217 %ColPerThreadA
-               OpSelectionMerge %219 None
-               OpBranchConditional %218 %219 %220
-        %220 = OpLabel
-               OpBranch %215
+        %216 = OpLabel
+               OpBranch %218
+        %218 = OpLabel
+               OpStore %innerRow %uint_0
+               OpBranch %221
+        %221 = OpLabel
+               OpLoopMerge %222 %220 None
+               OpBranch %219
         %219 = OpLabel
-        %221 = OpLoad %uint %innerRow None
-   %inputRow = OpIAdd %uint %tileRow %221
-        %223 = OpLoad %uint %innerCol None
-   %inputCol = OpIAdd %uint %tileColA %223
-        %225 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %inputRow %inputCol
-        %226 = OpLoad %uint %innerRow None
-        %227 = OpIAdd %uint %globalRow %226
-        %228 = OpLoad %uint %t None
-        %229 = OpIMul %uint %228 %uint_64
-        %230 = OpIAdd %uint %229 %inputCol
-        %231 = OpFunctionCall %float %mm_readA %227 %230
-               OpStore %225 %231 None
-               OpBranch %213
-        %213 = OpLabel
-        %232 = OpLoad %uint %innerCol None
-        %233 = OpIAdd %uint %232 %uint_1
-               OpStore %innerCol %233 None
-               OpBranch %214
-        %215 = OpLabel
-               OpBranch %203
-        %203 = OpLabel
-        %234 = OpLoad %uint %innerRow None
-        %235 = OpIAdd %uint %234 %uint_1
-               OpStore %innerRow %235 None
-               OpBranch %204
-        %205 = OpLabel
-               OpBranch %236
-        %236 = OpLabel
-               OpStore %innerRow_0 %uint_0
-               OpBranch %239
-        %239 = OpLabel
-               OpLoopMerge %240 %238 None
-               OpBranch %237
+        %224 = OpLoad %uint %innerRow None
+        %225 = OpULessThan %bool %224 %ColPerThreadA
+               OpSelectionMerge %226 None
+               OpBranchConditional %225 %226 %227
+        %227 = OpLabel
+               OpBranch %222
+        %226 = OpLabel
+               OpBranch %228
+        %228 = OpLabel
+               OpStore %innerCol %uint_0
+               OpBranch %231
+        %231 = OpLabel
+               OpLoopMerge %232 %230 None
+               OpBranch %229
+        %229 = OpLabel
+        %234 = OpLoad %uint %innerCol None
+        %235 = OpULessThan %bool %234 %ColPerThreadA
+               OpSelectionMerge %236 None
+               OpBranchConditional %235 %236 %237
         %237 = OpLabel
-        %242 = OpLoad %uint %innerRow_0 None
-        %243 = OpULessThan %bool %242 %ColPerThreadA
-               OpSelectionMerge %244 None
-               OpBranchConditional %243 %244 %245
-        %245 = OpLabel
-               OpBranch %240
-        %244 = OpLabel
-               OpBranch %246
-        %246 = OpLabel
+               OpBranch %232
+        %236 = OpLabel
+        %238 = OpLoad %uint %innerRow None
+   %inputRow = OpIAdd %uint %tileRow %238
+        %240 = OpLoad %uint %innerCol None
+   %inputCol = OpIAdd %uint %tileColA %240
+        %242 = OpExtInst %uint %63 UMin %inputRow %uint_63
+        %244 = OpExtInst %uint %63 UMin %inputCol %uint_63
+        %245 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %242 %244
+        %246 = OpLoad %uint %innerRow None
+        %247 = OpIAdd %uint %globalRow %246
+        %248 = OpLoad %uint %t None
+        %249 = OpIMul %uint %248 %uint_64
+        %250 = OpIAdd %uint %249 %inputCol
+        %251 = OpFunctionCall %float %mm_readA %247 %250
+               OpStore %245 %251 None
+               OpBranch %230
+        %230 = OpLabel
+        %252 = OpLoad %uint %innerCol None
+        %253 = OpIAdd %uint %252 %uint_1
+               OpStore %innerCol %253 None
+               OpBranch %231
+        %232 = OpLabel
+               OpBranch %220
+        %220 = OpLabel
+        %254 = OpLoad %uint %innerRow None
+        %255 = OpIAdd %uint %254 %uint_1
+               OpStore %innerRow %255 None
+               OpBranch %221
+        %222 = OpLabel
+               OpBranch %256
+        %256 = OpLabel
+               OpStore %innerRow_0 %uint_0
+               OpBranch %259
+        %259 = OpLabel
+               OpLoopMerge %260 %258 None
+               OpBranch %257
+        %257 = OpLabel
+        %262 = OpLoad %uint %innerRow_0 None
+        %263 = OpULessThan %bool %262 %ColPerThreadA
+               OpSelectionMerge %264 None
+               OpBranchConditional %263 %264 %265
+        %265 = OpLabel
+               OpBranch %260
+        %264 = OpLabel
+               OpBranch %266
+        %266 = OpLabel
                OpStore %innerCol_0 %uint_0
-               OpBranch %249
-        %249 = OpLabel
-               OpLoopMerge %250 %248 None
-               OpBranch %247
-        %247 = OpLabel
-        %252 = OpLoad %uint %innerCol_0 None
-        %253 = OpULessThan %bool %252 %ColPerThreadA
-               OpSelectionMerge %254 None
-               OpBranchConditional %253 %254 %255
-        %255 = OpLabel
-               OpBranch %250
-        %254 = OpLabel
-        %256 = OpLoad %uint %innerRow_0 None
- %inputRow_0 = OpIAdd %uint %tileRowB %256
-        %258 = OpLoad %uint %innerCol_0 None
- %inputCol_0 = OpIAdd %uint %tileCol %258
-        %260 = OpLoad %uint %innerCol_0 None
-        %261 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %260 %inputCol_0
-        %262 = OpLoad %uint %t None
-        %263 = OpIMul %uint %262 %uint_64
-        %264 = OpIAdd %uint %263 %inputRow_0
-        %265 = OpLoad %uint %innerCol_0 None
-        %266 = OpIAdd %uint %globalCol %265
-        %267 = OpFunctionCall %float %mm_readB %264 %266
-               OpStore %261 %267 None
-               OpBranch %248
-        %248 = OpLabel
-        %268 = OpLoad %uint %innerCol_0 None
-        %269 = OpIAdd %uint %268 %uint_1
-               OpStore %innerCol_0 %269 None
-               OpBranch %249
-        %250 = OpLabel
-               OpBranch %238
-        %238 = OpLabel
-        %270 = OpLoad %uint %innerRow_0 None
-        %271 = OpIAdd %uint %270 %uint_1
-               OpStore %innerRow_0 %271 None
-               OpBranch %239
-        %240 = OpLabel
-               OpControlBarrier %uint_2 %uint_2 %uint_264
-               OpBranch %273
-        %273 = OpLabel
-               OpStore %k %uint_0
-               OpBranch %276
-        %276 = OpLabel
-               OpLoopMerge %277 %275 None
-               OpBranch %274
+               OpBranch %269
+        %269 = OpLabel
+               OpLoopMerge %270 %268 None
+               OpBranch %267
+        %267 = OpLabel
+        %272 = OpLoad %uint %innerCol_0 None
+        %273 = OpULessThan %bool %272 %ColPerThreadA
+               OpSelectionMerge %274 None
+               OpBranchConditional %273 %274 %275
+        %275 = OpLabel
+               OpBranch %270
         %274 = OpLabel
-        %279 = OpLoad %uint %k None
-        %280 = OpULessThan %bool %279 %uint_64
-               OpSelectionMerge %281 None
-               OpBranchConditional %280 %281 %282
-        %282 = OpLabel
-               OpBranch %277
-        %281 = OpLabel
-               OpBranch %283
-        %283 = OpLabel
-               OpStore %inner %uint_0
-               OpBranch %286
-        %286 = OpLabel
-               OpLoopMerge %287 %285 None
-               OpBranch %284
-        %284 = OpLabel
-        %289 = OpLoad %uint %inner None
-        %290 = OpULessThan %bool %289 %ColPerThreadA
-               OpSelectionMerge %291 None
-               OpBranchConditional %290 %291 %292
-        %292 = OpLabel
-               OpBranch %287
-        %291 = OpLabel
-        %293 = OpLoad %uint %inner None
-        %294 = OpAccessChain %_ptr_Function_float %BCached %293
-        %295 = OpLoad %uint %k None
-        %296 = OpLoad %uint %inner None
-        %297 = OpIAdd %uint %tileCol %296
-        %298 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %295 %297
-        %299 = OpLoad %float %298 None
-               OpStore %294 %299 None
-               OpBranch %285
-        %285 = OpLabel
-        %300 = OpLoad %uint %inner None
-        %301 = OpIAdd %uint %300 %uint_1
-               OpStore %inner %301 None
-               OpBranch %286
-        %287 = OpLabel
-               OpBranch %302
-        %302 = OpLabel
-               OpStore %innerRow_1 %uint_0
+        %276 = OpLoad %uint %innerRow_0 None
+ %inputRow_0 = OpIAdd %uint %tileRowB %276
+        %278 = OpLoad %uint %innerCol_0 None
+ %inputCol_0 = OpIAdd %uint %tileCol %278
+        %280 = OpLoad %uint %innerCol_0 None
+        %281 = OpExtInst %uint %63 UMin %280 %uint_63
+        %282 = OpExtInst %uint %63 UMin %inputCol_0 %uint_63
+        %283 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %281 %282
+        %284 = OpLoad %uint %t None
+        %285 = OpIMul %uint %284 %uint_64
+        %286 = OpIAdd %uint %285 %inputRow_0
+        %287 = OpLoad %uint %innerCol_0 None
+        %288 = OpIAdd %uint %globalCol %287
+        %289 = OpFunctionCall %float %mm_readB %286 %288
+               OpStore %283 %289 None
+               OpBranch %268
+        %268 = OpLabel
+        %290 = OpLoad %uint %innerCol_0 None
+        %291 = OpIAdd %uint %290 %uint_1
+               OpStore %innerCol_0 %291 None
+               OpBranch %269
+        %270 = OpLabel
+               OpBranch %258
+        %258 = OpLabel
+        %292 = OpLoad %uint %innerRow_0 None
+        %293 = OpIAdd %uint %292 %uint_1
+               OpStore %innerRow_0 %293 None
+               OpBranch %259
+        %260 = OpLabel
+               OpControlBarrier %uint_2 %uint_2 %uint_264
+               OpBranch %295
+        %295 = OpLabel
+               OpStore %k %uint_0
+               OpBranch %298
+        %298 = OpLabel
+               OpLoopMerge %299 %297 None
+               OpBranch %296
+        %296 = OpLabel
+        %301 = OpLoad %uint %k None
+        %302 = OpULessThan %bool %301 %uint_64
+               OpSelectionMerge %303 None
+               OpBranchConditional %302 %303 %304
+        %304 = OpLabel
+               OpBranch %299
+        %303 = OpLabel
                OpBranch %305
         %305 = OpLabel
-               OpLoopMerge %306 %304 None
-               OpBranch %303
-        %303 = OpLabel
-        %308 = OpLoad %uint %innerRow_1 None
-        %309 = OpULessThan %bool %308 %ColPerThreadA
-               OpSelectionMerge %310 None
-               OpBranchConditional %309 %310 %311
-        %311 = OpLabel
+               OpStore %inner %uint_0
+               OpBranch %308
+        %308 = OpLabel
+               OpLoopMerge %309 %307 None
                OpBranch %306
-        %310 = OpLabel
-        %312 = OpLoad %uint %innerRow_1 None
-        %313 = OpIAdd %uint %tileRow %312
-        %314 = OpLoad %uint %k None
-        %315 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %313 %314
-        %316 = OpLoad %float %315 None
-               OpStore %ACached %316 None
-               OpBranch %317
-        %317 = OpLabel
-               OpStore %innerCol_1 %uint_0
-               OpBranch %320
-        %320 = OpLabel
-               OpLoopMerge %321 %319 None
-               OpBranch %318
-        %318 = OpLabel
-        %323 = OpLoad %uint %innerCol_1 None
-        %324 = OpULessThan %bool %323 %ColPerThreadA
-               OpSelectionMerge %325 None
-               OpBranchConditional %324 %325 %326
-        %326 = OpLabel
-               OpBranch %321
-        %325 = OpLabel
-        %327 = OpLoad %uint %innerRow_1 None
-        %328 = OpIMul %uint %327 %ColPerThreadA
-        %329 = OpLoad %uint %innerCol_1 None
-    %index_1 = OpIAdd %uint %328 %329
-        %331 = OpAccessChain %_ptr_Function_float %acc %index_1
-        %332 = OpAccessChain %_ptr_Function_float %acc %index_1
-        %333 = OpLoad %float %332 None
-        %334 = OpLoad %float %ACached None
-        %335 = OpLoad %uint %innerCol_1 None
-        %336 = OpAccessChain %_ptr_Function_float %BCached %335
-        %337 = OpLoad %float %336 None
-        %338 = OpFMul %float %334 %337
-        %339 = OpFAdd %float %333 %338
-               OpStore %331 %339 None
-               OpBranch %319
-        %319 = OpLabel
-        %340 = OpLoad %uint %innerCol_1 None
-        %341 = OpIAdd %uint %340 %uint_1
-               OpStore %innerCol_1 %341 None
-               OpBranch %320
-        %321 = OpLabel
-               OpBranch %304
-        %304 = OpLabel
-        %342 = OpLoad %uint %innerRow_1 None
-        %343 = OpIAdd %uint %342 %uint_1
-               OpStore %innerRow_1 %343 None
-               OpBranch %305
         %306 = OpLabel
-               OpBranch %275
-        %275 = OpLabel
-        %344 = OpLoad %uint %k None
-        %345 = OpIAdd %uint %344 %uint_1
-               OpStore %k %345 None
-               OpBranch %276
-        %277 = OpLabel
-               OpControlBarrier %uint_2 %uint_2 %uint_264
-               OpBranch %193
-        %193 = OpLabel
-        %347 = OpLoad %uint %t None
-        %348 = OpIAdd %uint %347 %uint_1
-               OpStore %t %348 None
-               OpBranch %194
-        %195 = OpLabel
+        %311 = OpLoad %uint %inner None
+        %312 = OpULessThan %bool %311 %ColPerThreadA
+               OpSelectionMerge %313 None
+               OpBranchConditional %312 %313 %314
+        %314 = OpLabel
+               OpBranch %309
+        %313 = OpLabel
+        %315 = OpLoad %uint %inner None
+        %316 = OpExtInst %uint %63 UMin %315 %uint_3
+        %318 = OpAccessChain %_ptr_Function_float %BCached %316
+        %319 = OpLoad %uint %k None
+        %320 = OpLoad %uint %inner None
+        %321 = OpIAdd %uint %tileCol %320
+        %322 = OpExtInst %uint %63 UMin %319 %uint_63
+        %323 = OpExtInst %uint %63 UMin %321 %uint_63
+        %324 = OpAccessChain %_ptr_Workgroup_float %mm_Bsub %322 %323
+        %325 = OpLoad %float %324 None
+               OpStore %318 %325 None
+               OpBranch %307
+        %307 = OpLabel
+        %326 = OpLoad %uint %inner None
+        %327 = OpIAdd %uint %326 %uint_1
+               OpStore %inner %327 None
+               OpBranch %308
+        %309 = OpLabel
+               OpBranch %328
+        %328 = OpLabel
+               OpStore %innerRow_1 %uint_0
+               OpBranch %331
+        %331 = OpLabel
+               OpLoopMerge %332 %330 None
+               OpBranch %329
+        %329 = OpLabel
+        %334 = OpLoad %uint %innerRow_1 None
+        %335 = OpULessThan %bool %334 %ColPerThreadA
+               OpSelectionMerge %336 None
+               OpBranchConditional %335 %336 %337
+        %337 = OpLabel
+               OpBranch %332
+        %336 = OpLabel
+        %338 = OpLoad %uint %innerRow_1 None
+        %339 = OpIAdd %uint %tileRow %338
+        %340 = OpLoad %uint %k None
+        %341 = OpExtInst %uint %63 UMin %339 %uint_63
+        %342 = OpExtInst %uint %63 UMin %340 %uint_63
+        %343 = OpAccessChain %_ptr_Workgroup_float %mm_Asub %341 %342
+        %344 = OpLoad %float %343 None
+               OpStore %ACached %344 None
+               OpBranch %345
+        %345 = OpLabel
+               OpStore %innerCol_1 %uint_0
+               OpBranch %348
+        %348 = OpLabel
+               OpLoopMerge %349 %347 None
+               OpBranch %346
+        %346 = OpLabel
+        %351 = OpLoad %uint %innerCol_1 None
+        %352 = OpULessThan %bool %351 %ColPerThreadA
+               OpSelectionMerge %353 None
+               OpBranchConditional %352 %353 %354
+        %354 = OpLabel
                OpBranch %349
-        %349 = OpLabel
-               OpStore %innerRow_2 %uint_0
-               OpBranch %352
-        %352 = OpLabel
-               OpLoopMerge %353 %351 None
-               OpBranch %350
-        %350 = OpLabel
-        %355 = OpLoad %uint %innerRow_2 None
-        %356 = OpULessThan %bool %355 %ColPerThreadA
-               OpSelectionMerge %357 None
-               OpBranchConditional %356 %357 %358
-        %358 = OpLabel
-               OpBranch %353
-        %357 = OpLabel
-               OpBranch %359
-        %359 = OpLabel
-               OpStore %innerCol_2 %uint_0
-               OpBranch %362
-        %362 = OpLabel
-               OpLoopMerge %363 %361 None
-               OpBranch %360
-        %360 = OpLabel
-        %365 = OpLoad %uint %innerCol_2 None
-        %366 = OpULessThan %bool %365 %ColPerThreadA
-               OpSelectionMerge %367 None
-               OpBranchConditional %366 %367 %368
-        %368 = OpLabel
-               OpBranch %363
-        %367 = OpLabel
-        %369 = OpLoad %uint %innerRow_2 None
-        %370 = OpIMul %uint %369 %ColPerThreadA
-        %371 = OpLoad %uint %innerCol_2 None
-    %index_2 = OpIAdd %uint %370 %371
-        %373 = OpLoad %uint %innerRow_2 None
-        %374 = OpIAdd %uint %globalRow %373
-        %375 = OpLoad %uint %innerCol_2 None
-        %376 = OpIAdd %uint %globalCol %375
-        %377 = OpAccessChain %_ptr_Function_float %acc %index_2
-        %378 = OpLoad %float %377 None
-        %379 = OpFunctionCall %void %mm_write %374 %376 %378
-               OpBranch %361
-        %361 = OpLabel
-        %380 = OpLoad %uint %innerCol_2 None
-        %381 = OpIAdd %uint %380 %uint_1
-               OpStore %innerCol_2 %381 None
-               OpBranch %362
-        %363 = OpLabel
-               OpBranch %351
-        %351 = OpLabel
-        %382 = OpLoad %uint %innerRow_2 None
-        %383 = OpIAdd %uint %382 %uint_1
-               OpStore %innerRow_2 %383 None
-               OpBranch %352
         %353 = OpLabel
+        %355 = OpLoad %uint %innerRow_1 None
+        %356 = OpIMul %uint %355 %ColPerThreadA
+        %357 = OpLoad %uint %innerCol_1 None
+    %index_1 = OpIAdd %uint %356 %357
+        %359 = OpExtInst %uint %63 UMin %index_1 %uint_15
+        %360 = OpAccessChain %_ptr_Function_float %acc %359
+        %361 = OpExtInst %uint %63 UMin %index_1 %uint_15
+        %362 = OpAccessChain %_ptr_Function_float %acc %361
+        %363 = OpLoad %float %362 None
+        %364 = OpLoad %float %ACached None
+        %365 = OpLoad %uint %innerCol_1 None
+        %366 = OpExtInst %uint %63 UMin %365 %uint_3
+        %367 = OpAccessChain %_ptr_Function_float %BCached %366
+        %368 = OpLoad %float %367 None
+        %369 = OpFMul %float %364 %368
+        %370 = OpFAdd %float %363 %369
+               OpStore %360 %370 None
+               OpBranch %347
+        %347 = OpLabel
+        %371 = OpLoad %uint %innerCol_1 None
+        %372 = OpIAdd %uint %371 %uint_1
+               OpStore %innerCol_1 %372 None
+               OpBranch %348
+        %349 = OpLabel
+               OpBranch %330
+        %330 = OpLabel
+        %373 = OpLoad %uint %innerRow_1 None
+        %374 = OpIAdd %uint %373 %uint_1
+               OpStore %innerRow_1 %374 None
+               OpBranch %331
+        %332 = OpLabel
+               OpBranch %297
+        %297 = OpLabel
+        %375 = OpLoad %uint %k None
+        %376 = OpIAdd %uint %375 %uint_1
+               OpStore %k %376 None
+               OpBranch %298
+        %299 = OpLabel
+               OpControlBarrier %uint_2 %uint_2 %uint_264
+               OpBranch %210
+        %210 = OpLabel
+        %378 = OpLoad %uint %t None
+        %379 = OpIAdd %uint %378 %uint_1
+               OpStore %t %379 None
+               OpBranch %211
+        %212 = OpLabel
+               OpBranch %380
+        %380 = OpLabel
+               OpStore %innerRow_2 %uint_0
+               OpBranch %383
+        %383 = OpLabel
+               OpLoopMerge %384 %382 None
+               OpBranch %381
+        %381 = OpLabel
+        %386 = OpLoad %uint %innerRow_2 None
+        %387 = OpULessThan %bool %386 %ColPerThreadA
+               OpSelectionMerge %388 None
+               OpBranchConditional %387 %388 %389
+        %389 = OpLabel
+               OpBranch %384
+        %388 = OpLabel
+               OpBranch %390
+        %390 = OpLabel
+               OpStore %innerCol_2 %uint_0
+               OpBranch %393
+        %393 = OpLabel
+               OpLoopMerge %394 %392 None
+               OpBranch %391
+        %391 = OpLabel
+        %396 = OpLoad %uint %innerCol_2 None
+        %397 = OpULessThan %bool %396 %ColPerThreadA
+               OpSelectionMerge %398 None
+               OpBranchConditional %397 %398 %399
+        %399 = OpLabel
+               OpBranch %394
+        %398 = OpLabel
+        %400 = OpLoad %uint %innerRow_2 None
+        %401 = OpIMul %uint %400 %ColPerThreadA
+        %402 = OpLoad %uint %innerCol_2 None
+    %index_2 = OpIAdd %uint %401 %402
+        %404 = OpLoad %uint %innerRow_2 None
+        %405 = OpIAdd %uint %globalRow %404
+        %406 = OpLoad %uint %innerCol_2 None
+        %407 = OpIAdd %uint %globalCol %406
+        %408 = OpExtInst %uint %63 UMin %index_2 %uint_15
+        %409 = OpAccessChain %_ptr_Function_float %acc %408
+        %410 = OpLoad %float %409 None
+        %411 = OpFunctionCall %void %mm_write %405 %407 %410
+               OpBranch %392
+        %392 = OpLabel
+        %412 = OpLoad %uint %innerCol_2 None
+        %413 = OpIAdd %uint %412 %uint_1
+               OpStore %innerCol_2 %413 None
+               OpBranch %393
+        %394 = OpLabel
+               OpBranch %382
+        %382 = OpLabel
+        %414 = OpLoad %uint %innerRow_2 None
+        %415 = OpIAdd %uint %414 %uint_1
+               OpStore %innerRow_2 %415 None
+               OpBranch %383
+        %384 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_div_u32 = OpFunction %uint None %386
+%tint_div_u32 = OpFunction %uint None %418
         %lhs = OpFunctionParameter %uint
         %rhs = OpFunctionParameter %uint
-        %387 = OpLabel
-        %388 = OpIEqual %bool %rhs %uint_0
-        %389 = OpSelect %uint %388 %uint_1 %rhs
-        %390 = OpUDiv %uint %lhs %389
-               OpReturnValue %390
+        %419 = OpLabel
+        %420 = OpIEqual %bool %rhs %uint_0
+        %421 = OpSelect %uint %420 %uint_1 %rhs
+        %422 = OpUDiv %uint %lhs %421
+               OpReturnValue %422
                OpFunctionEnd
-       %main = OpFunction %void None %392
-        %393 = OpLabel
-        %394 = OpLoad %v3uint %main_local_invocation_id_Input None
-        %395 = OpLoad %v3uint %main_global_invocation_id_Input None
-        %396 = OpLoad %uint %main_local_invocation_index_Input None
-        %397 = OpFunctionCall %void %main_inner %394 %395 %396
+       %main = OpFunction %void None %424
+        %425 = OpLabel
+        %426 = OpLoad %v3uint %main_local_invocation_id_Input None
+        %427 = OpLoad %v3uint %main_global_invocation_id_Input None
+        %428 = OpLoad %uint %main_local_invocation_index_Input None
+        %429 = OpFunctionCall %void %main_inner %426 %427 %428
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/922.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/922.wgsl.expected.dxc.hlsl
index 08f4aac..60352c6 100644
--- a/test/tint/bug/tint/922.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/922.wgsl.expected.dxc.hlsl
@@ -241,7 +241,7 @@
   Mat4x3_ t_PosMtx = (Mat4x3_)0;
   float2 t_TexSpaceCoord = float2(0.0f, 0.0f);
   float x_e15 = a_PosMtxIdx1;
-  Mat4x3_ x_e18 = global2_load((48u * uint(tint_ftoi(x_e15))));
+  Mat4x3_ x_e18 = global2_load((48u * min(uint(tint_ftoi(x_e15)), 31u)));
   t_PosMtx = x_e18;
   Mat4x3_ x_e23 = t_PosMtx;
   Mat4x4_ x_e24 = x_Mat4x4_1(x_e23);
diff --git a/test/tint/bug/tint/922.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/922.wgsl.expected.fxc.hlsl
index 08f4aac..60352c6 100644
--- a/test/tint/bug/tint/922.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/922.wgsl.expected.fxc.hlsl
@@ -241,7 +241,7 @@
   Mat4x3_ t_PosMtx = (Mat4x3_)0;
   float2 t_TexSpaceCoord = float2(0.0f, 0.0f);
   float x_e15 = a_PosMtxIdx1;
-  Mat4x3_ x_e18 = global2_load((48u * uint(tint_ftoi(x_e15))));
+  Mat4x3_ x_e18 = global2_load((48u * min(uint(tint_ftoi(x_e15)), 31u)));
   t_PosMtx = x_e18;
   Mat4x3_ x_e23 = t_PosMtx;
   Mat4x4_ x_e24 = x_Mat4x4_1(x_e23);
diff --git a/test/tint/bug/tint/922.wgsl.expected.glsl b/test/tint/bug/tint/922.wgsl.expected.glsl
index f89e5ed..095e05c 100644
--- a/test/tint/bug/tint/922.wgsl.expected.glsl
+++ b/test/tint/bug/tint/922.wgsl.expected.glsl
@@ -128,7 +128,7 @@
   Mat4x3_ t_PosMtx = Mat4x3_(vec4(0.0f), vec4(0.0f), vec4(0.0f));
   vec2 t_TexSpaceCoord = vec2(0.0f);
   float x_e15 = a_PosMtxIdx1;
-  int v_4 = tint_f32_to_i32(x_e15);
+  uint v_4 = min(uint(tint_f32_to_i32(x_e15)), 31u);
   Mat4x3_ x_e18 = v_3.inner.u_PosMtx[v_4];
   t_PosMtx = x_e18;
   Mat4x3_ x_e23 = t_PosMtx;
@@ -153,14 +153,14 @@
   vec4 x_e52 = v_2.inner.u_Misc0_;
   if ((x_e52[0u] == 2.0f)) {
     vec3 x_e59 = a_Normal1;
-    Mat4x2_ x_e64 = v_2.inner.u_TexMtx[0];
+    Mat4x2_ x_e64 = v_2.inner.u_TexMtx[0u];
     vec3 x_e65 = a_Normal1;
     vec2 x_e68 = Mul2(x_e64, vec4(x_e65, 1.0f));
     v_TexCoord = x_e68.xy;
     return;
   } else {
     vec2 x_e73 = a_UV1;
-    Mat4x2_ x_e79 = v_2.inner.u_TexMtx[0];
+    Mat4x2_ x_e79 = v_2.inner.u_TexMtx[0u];
     vec2 x_e80 = a_UV1;
     vec2 x_e84 = Mul2(x_e79, vec4(x_e80, 1.0f, 1.0f));
     v_TexCoord = x_e84.xy;
diff --git a/test/tint/bug/tint/922.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/922.wgsl.expected.ir.dxc.hlsl
index 8c06533..e042792 100644
--- a/test/tint/bug/tint/922.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/922.wgsl.expected.ir.dxc.hlsl
@@ -249,7 +249,7 @@
   Mat4x3_ t_PosMtx = (Mat4x3_)0;
   float2 t_TexSpaceCoord = (0.0f).xx;
   float x_e15 = a_PosMtxIdx1;
-  Mat4x3_ x_e18 = v_5((48u * uint(tint_f32_to_i32(x_e15))));
+  Mat4x3_ x_e18 = v_5((48u * uint(min(uint(tint_f32_to_i32(x_e15)), 31u))));
   t_PosMtx = x_e18;
   Mat4x3_ x_e23 = t_PosMtx;
   Mat4x4_ x_e24 = x_Mat4x4_1(x_e23);
diff --git a/test/tint/bug/tint/922.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/922.wgsl.expected.ir.fxc.hlsl
index 8c06533..e042792 100644
--- a/test/tint/bug/tint/922.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/922.wgsl.expected.ir.fxc.hlsl
@@ -249,7 +249,7 @@
   Mat4x3_ t_PosMtx = (Mat4x3_)0;
   float2 t_TexSpaceCoord = (0.0f).xx;
   float x_e15 = a_PosMtxIdx1;
-  Mat4x3_ x_e18 = v_5((48u * uint(tint_f32_to_i32(x_e15))));
+  Mat4x3_ x_e18 = v_5((48u * uint(min(uint(tint_f32_to_i32(x_e15)), 31u))));
   t_PosMtx = x_e18;
   Mat4x3_ x_e23 = t_PosMtx;
   Mat4x4_ x_e24 = x_Mat4x4_1(x_e23);
diff --git a/test/tint/bug/tint/922.wgsl.expected.ir.msl b/test/tint/bug/tint/922.wgsl.expected.ir.msl
index 8e1b919..3730074 100644
--- a/test/tint/bug/tint/922.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/922.wgsl.expected.ir.msl
@@ -258,7 +258,7 @@
   Mat4x3_ t_PosMtx = {};
   float2 t_TexSpaceCoord = 0.0f;
   float const x_e15 = (*tint_module_vars.a_PosMtxIdx1);
-  Mat4x3_ const x_e18 = (*tint_module_vars.global2).u_PosMtx[tint_f32_to_i32(x_e15)];
+  Mat4x3_ const x_e18 = (*tint_module_vars.global2).u_PosMtx[min(uint(tint_f32_to_i32(x_e15)), 31u)];
   t_PosMtx = x_e18;
   Mat4x3_ const x_e23 = t_PosMtx;
   Mat4x4_ const x_e24 = x_Mat4x4_1(x_e23);
@@ -282,14 +282,14 @@
   float4 const x_e52 = (*tint_module_vars.global1).u_Misc0_;
   if ((x_e52[0u] == 2.0f)) {
     float3 const x_e59 = (*tint_module_vars.a_Normal1);
-    Mat4x2_ const x_e64 = (*tint_module_vars.global1).u_TexMtx[0];
+    Mat4x2_ const x_e64 = (*tint_module_vars.global1).u_TexMtx[0u];
     float3 const x_e65 = (*tint_module_vars.a_Normal1);
     float2 const x_e68 = Mul2(x_e64, float4(x_e65, 1.0f));
     (*tint_module_vars.v_TexCoord) = x_e68.xy;
     return;
   } else {
     float2 const x_e73 = (*tint_module_vars.a_UV1);
-    Mat4x2_ const x_e79 = (*tint_module_vars.global1).u_TexMtx[0];
+    Mat4x2_ const x_e79 = (*tint_module_vars.global1).u_TexMtx[0u];
     float2 const x_e80 = (*tint_module_vars.a_UV1);
     float2 const x_e84 = Mul2(x_e79, float4(x_e80, 1.0f, 1.0f));
     (*tint_module_vars.v_TexCoord) = x_e84.xy;
diff --git a/test/tint/bug/tint/922.wgsl.expected.msl b/test/tint/bug/tint/922.wgsl.expected.msl
index e00ab45..591a0a3 100644
--- a/test/tint/bug/tint/922.wgsl.expected.msl
+++ b/test/tint/bug/tint/922.wgsl.expected.msl
@@ -242,7 +242,7 @@
   Mat4x3_ t_PosMtx = {};
   float2 t_TexSpaceCoord = 0.0f;
   float const x_e15 = (*(tint_private_vars)).a_PosMtxIdx1;
-  Mat4x3_ const x_e18 = (*(tint_symbol_5)).u_PosMtx[tint_ftoi(x_e15)];
+  Mat4x3_ const x_e18 = (*(tint_symbol_5)).u_PosMtx[min(uint(tint_ftoi(x_e15)), 31u)];
   t_PosMtx = x_e18;
   Mat4x3_ const x_e23 = t_PosMtx;
   Mat4x4_ const x_e24 = x_Mat4x4_1(x_e23);
diff --git a/test/tint/bug/tint/922.wgsl.expected.spvasm b/test/tint/bug/tint/922.wgsl.expected.spvasm
index b0f38eb..1da11eb 100644
--- a/test/tint/bug/tint/922.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/922.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 380
+; Bound: 383
 ; Schema: 0
                OpCapability Shader
+        %295 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %main "main" %main_loc0_Input %main_loc1_Input %main_loc2_Input %main_loc3_Input %main_loc4_Input %main_loc0_Output %main_loc1_Output %main_position_Output %main___point_size_Output
                OpMemberName %Mat4x4_ 0 "mx"
@@ -337,16 +338,16 @@
         %284 = OpTypeFunction %void
 %_ptr_Function_v2float = OpTypePointer Function %v2float
         %int = OpTypeInt 32 1
+    %uint_31 = OpConstant %uint 31
 %_ptr_Uniform_Mat4x3_ = OpTypePointer Uniform %Mat4x3_
 %_ptr_Uniform_Mat4x4_ = OpTypePointer Uniform %Mat4x4_
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
     %float_2 = OpConstant %float 2
        %bool = OpTypeBool
 %_ptr_Uniform_Mat4x2_ = OpTypePointer Uniform %Mat4x2_
-      %int_0 = OpConstant %int 0
 %VertexOutput = OpTypeStruct %v4float %v2float %v4float
-        %350 = OpTypeFunction %VertexOutput %v3float %v2float %v4float %v3float %float
-        %358 = OpTypeFunction %int %float
+        %353 = OpTypeFunction %VertexOutput %v3float %v2float %v4float %v3float %float
+        %361 = OpTypeFunction %int %float
 %float_n2_14748365e_09 = OpConstant %float -2.14748365e+09
 %int_n2147483648 = OpConstant %int -2147483648
 %float_2_14748352e_09 = OpConstant %float 2.14748352e+09
@@ -618,8 +619,10 @@
 %t_TexSpaceCoord = OpVariable %_ptr_Function_v2float Function %30
     %x_e15_1 = OpLoad %float %a_PosMtxIdx1 None
         %290 = OpFunctionCall %int %tint_f32_to_i32 %x_e15_1
-        %293 = OpAccessChain %_ptr_Uniform_Mat4x3_ %16 %uint_0 %uint_0 %290
-    %x_e18_2 = OpLoad %Mat4x3_ %293 None
+        %293 = OpBitcast %uint %290
+        %294 = OpExtInst %uint %295 UMin %293 %uint_31
+        %297 = OpAccessChain %_ptr_Uniform_Mat4x3_ %16 %uint_0 %uint_0 %294
+    %x_e18_2 = OpLoad %Mat4x3_ %297 None
                OpStore %t_PosMtx %x_e18_2 None
       %x_e23 = OpLoad %Mat4x3_ %t_PosMtx None
       %x_e24 = OpFunctionCall %Mat4x4_ %x_Mat4x4_1 %x_e23
@@ -627,94 +630,94 @@
       %x_e29 = OpLoad %Mat4x3_ %t_PosMtx None
       %x_e30 = OpFunctionCall %Mat4x4_ %x_Mat4x4_1 %x_e29
       %x_e31 = OpLoad %v3float %a_Position1 None
-        %302 = OpCompositeConstruct %v4float %x_e31 %float_1
-      %x_e34 = OpFunctionCall %v4float %Mul %x_e30 %302
-        %304 = OpAccessChain %_ptr_Uniform_Mat4x4_ %1 %uint_0 %uint_0
-      %x_e35 = OpLoad %Mat4x4_ %304 None
+        %306 = OpCompositeConstruct %v4float %x_e31 %float_1
+      %x_e34 = OpFunctionCall %v4float %Mul %x_e30 %306
+        %308 = OpAccessChain %_ptr_Uniform_Mat4x4_ %1 %uint_0 %uint_0
+      %x_e35 = OpLoad %Mat4x4_ %308 None
       %x_e37 = OpLoad %Mat4x3_ %t_PosMtx None
       %x_e38 = OpFunctionCall %Mat4x4_ %x_Mat4x4_1 %x_e37
       %x_e39 = OpLoad %v3float %a_Position1 None
       %x_e43 = OpLoad %Mat4x3_ %t_PosMtx None
       %x_e44 = OpFunctionCall %Mat4x4_ %x_Mat4x4_1 %x_e43
       %x_e45 = OpLoad %v3float %a_Position1 None
-        %313 = OpCompositeConstruct %v4float %x_e45 %float_1
-      %x_e48 = OpFunctionCall %v4float %Mul %x_e44 %313
+        %317 = OpCompositeConstruct %v4float %x_e45 %float_1
+      %x_e48 = OpFunctionCall %v4float %Mul %x_e44 %317
       %x_e49 = OpFunctionCall %v4float %Mul %x_e35 %x_e48
                OpStore %gl_Position %x_e49 None
       %x_e50 = OpLoad %v4float %a_Color1 None
                OpStore %v_Color %x_e50 None
-        %317 = OpAccessChain %_ptr_Uniform_v4float %8 %uint_0 %uint_1
-      %x_e52 = OpLoad %v4float %317 None
-        %320 = OpCompositeExtract %float %x_e52 0
-        %321 = OpFOrdEqual %bool %320 %float_2
-               OpSelectionMerge %324 None
-               OpBranchConditional %321 %325 %326
-        %325 = OpLabel
+        %321 = OpAccessChain %_ptr_Uniform_v4float %8 %uint_0 %uint_1
+      %x_e52 = OpLoad %v4float %321 None
+        %324 = OpCompositeExtract %float %x_e52 0
+        %325 = OpFOrdEqual %bool %324 %float_2
+               OpSelectionMerge %328 None
+               OpBranchConditional %325 %329 %330
+        %329 = OpLabel
       %x_e59 = OpLoad %v3float %a_Normal1 None
-        %328 = OpAccessChain %_ptr_Uniform_Mat4x2_ %8 %uint_0 %uint_0 %int_0
-      %x_e64 = OpLoad %Mat4x2_ %328 None
+        %332 = OpAccessChain %_ptr_Uniform_Mat4x2_ %8 %uint_0 %uint_0 %uint_0
+      %x_e64 = OpLoad %Mat4x2_ %332 None
       %x_e65 = OpLoad %v3float %a_Normal1 None
-        %333 = OpCompositeConstruct %v4float %x_e65 %float_1
-      %x_e68 = OpFunctionCall %v2float %Mul2 %x_e64 %333
-        %335 = OpVectorShuffle %v2float %x_e68 %x_e68 0 1
-               OpStore %v_TexCoord %335 None
-               OpBranch %324
-        %326 = OpLabel
+        %336 = OpCompositeConstruct %v4float %x_e65 %float_1
+      %x_e68 = OpFunctionCall %v2float %Mul2 %x_e64 %336
+        %338 = OpVectorShuffle %v2float %x_e68 %x_e68 0 1
+               OpStore %v_TexCoord %338 None
+               OpBranch %328
+        %330 = OpLabel
       %x_e73 = OpLoad %v2float %a_UV1 None
-        %337 = OpAccessChain %_ptr_Uniform_Mat4x2_ %8 %uint_0 %uint_0 %int_0
-      %x_e79 = OpLoad %Mat4x2_ %337 None
+        %340 = OpAccessChain %_ptr_Uniform_Mat4x2_ %8 %uint_0 %uint_0 %uint_0
+      %x_e79 = OpLoad %Mat4x2_ %340 None
       %x_e80 = OpLoad %v2float %a_UV1 None
-        %340 = OpCompositeConstruct %v4float %x_e80 %float_1 %float_1
-      %x_e84 = OpFunctionCall %v2float %Mul2 %x_e79 %340
-        %342 = OpVectorShuffle %v2float %x_e84 %x_e84 0 1
-               OpStore %v_TexCoord %342 None
-               OpBranch %324
-        %324 = OpLabel
+        %343 = OpCompositeConstruct %v4float %x_e80 %float_1 %float_1
+      %x_e84 = OpFunctionCall %v2float %Mul2 %x_e79 %343
+        %345 = OpVectorShuffle %v2float %x_e84 %x_e84 0 1
+               OpStore %v_TexCoord %345 None
+               OpBranch %328
+        %328 = OpLabel
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %VertexOutput None %350
+ %main_inner = OpFunction %VertexOutput None %353
  %a_Position = OpFunctionParameter %v3float
        %a_UV = OpFunctionParameter %v2float
     %a_Color = OpFunctionParameter %v4float
    %a_Normal = OpFunctionParameter %v3float
 %a_PosMtxIdx = OpFunctionParameter %float
-        %351 = OpLabel
+        %354 = OpLabel
                OpStore %a_Position1 %a_Position None
                OpStore %a_UV1 %a_UV None
                OpStore %a_Color1 %a_Color None
                OpStore %a_Normal1 %a_Normal None
                OpStore %a_PosMtxIdx1 %a_PosMtxIdx None
-        %352 = OpFunctionCall %void %main1
+        %355 = OpFunctionCall %void %main1
     %x_e11_2 = OpLoad %v4float %v_Color None
     %x_e13_0 = OpLoad %v2float %v_TexCoord None
     %x_e15_2 = OpLoad %v4float %gl_Position None
-        %356 = OpCompositeConstruct %VertexOutput %x_e11_2 %x_e13_0 %x_e15_2
-               OpReturnValue %356
+        %359 = OpCompositeConstruct %VertexOutput %x_e11_2 %x_e13_0 %x_e15_2
+               OpReturnValue %359
                OpFunctionEnd
-%tint_f32_to_i32 = OpFunction %int None %358
+%tint_f32_to_i32 = OpFunction %int None %361
       %value = OpFunctionParameter %float
-        %359 = OpLabel
-        %360 = OpConvertFToS %int %value
-        %361 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
-        %363 = OpSelect %int %361 %360 %int_n2147483648
-        %365 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
-        %367 = OpSelect %int %365 %363 %int_2147483647
-               OpReturnValue %367
+        %362 = OpLabel
+        %363 = OpConvertFToS %int %value
+        %364 = OpFOrdGreaterThanEqual %bool %value %float_n2_14748365e_09
+        %366 = OpSelect %int %364 %363 %int_n2147483648
+        %368 = OpFOrdLessThanEqual %bool %value %float_2_14748352e_09
+        %370 = OpSelect %int %368 %366 %int_2147483647
+               OpReturnValue %370
                OpFunctionEnd
        %main = OpFunction %void None %284
-        %370 = OpLabel
-        %371 = OpLoad %v3float %main_loc0_Input None
-        %372 = OpLoad %v2float %main_loc1_Input None
-        %373 = OpLoad %v4float %main_loc2_Input None
-        %374 = OpLoad %v3float %main_loc3_Input None
-        %375 = OpLoad %float %main_loc4_Input None
-        %376 = OpFunctionCall %VertexOutput %main_inner %371 %372 %373 %374 %375
-        %377 = OpCompositeExtract %v4float %376 0
-               OpStore %main_loc0_Output %377 None
-        %378 = OpCompositeExtract %v2float %376 1
-               OpStore %main_loc1_Output %378 None
-        %379 = OpCompositeExtract %v4float %376 2
-               OpStore %main_position_Output %379 None
+        %373 = OpLabel
+        %374 = OpLoad %v3float %main_loc0_Input None
+        %375 = OpLoad %v2float %main_loc1_Input None
+        %376 = OpLoad %v4float %main_loc2_Input None
+        %377 = OpLoad %v3float %main_loc3_Input None
+        %378 = OpLoad %float %main_loc4_Input None
+        %379 = OpFunctionCall %VertexOutput %main_inner %374 %375 %376 %377 %378
+        %380 = OpCompositeExtract %v4float %379 0
+               OpStore %main_loc0_Output %380 None
+        %381 = OpCompositeExtract %v2float %379 1
+               OpStore %main_loc1_Output %381 None
+        %382 = OpCompositeExtract %v4float %379 2
+               OpStore %main_position_Output %382 None
                OpStore %main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl
index 6060519..4188234 100644
--- a/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/942.wgsl.expected.dxc.hlsl
@@ -47,7 +47,7 @@
           if ((flip[0].x != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          tile[r][((4u * LocalInvocationID.x) + c)] = inputTex.SampleLevel(samp, ((float2(loadIndex) + (0.25f).xx) / float2(dims)), 0.0f).rgb;
+          tile[min(r, 3u)][min(((4u * LocalInvocationID.x) + c), 255u)] = inputTex.SampleLevel(samp, ((float2(loadIndex) + (0.25f).xx) / float2(dims)), 0.0f).rgb;
         }
       }
     }
@@ -75,7 +75,7 @@
             {
               for(uint f = 0u; (f < params[0].x); f = (f + 1u)) {
                 uint i = ((center + f) - filterOffset);
-                acc = (acc + ((1.0f / float(params[0].x)) * tile[r][i]));
+                acc = (acc + ((1.0f / float(params[0].x)) * tile[min(r, 3u)][min(i, 255u)]));
               }
             }
             outputTex[writeIndex] = float4(acc, 1.0f);
diff --git a/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl
index 6060519..4188234 100644
--- a/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/942.wgsl.expected.fxc.hlsl
@@ -47,7 +47,7 @@
           if ((flip[0].x != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          tile[r][((4u * LocalInvocationID.x) + c)] = inputTex.SampleLevel(samp, ((float2(loadIndex) + (0.25f).xx) / float2(dims)), 0.0f).rgb;
+          tile[min(r, 3u)][min(((4u * LocalInvocationID.x) + c), 255u)] = inputTex.SampleLevel(samp, ((float2(loadIndex) + (0.25f).xx) / float2(dims)), 0.0f).rgb;
         }
       }
     }
@@ -75,7 +75,7 @@
             {
               for(uint f = 0u; (f < params[0].x); f = (f + 1u)) {
                 uint i = ((center + f) - filterOffset);
-                acc = (acc + ((1.0f / float(params[0].x)) * tile[r][i]));
+                acc = (acc + ((1.0f / float(params[0].x)) * tile[min(r, 3u)][min(i, 255u)]));
               }
             }
             outputTex[writeIndex] = float4(acc, 1.0f);
diff --git a/test/tint/bug/tint/942.wgsl.expected.glsl b/test/tint/bug/tint/942.wgsl.expected.glsl
index a83b0a8..e1f75b6 100644
--- a/test/tint/bug/tint/942.wgsl.expected.glsl
+++ b/test/tint/bug/tint/942.wgsl.expected.glsl
@@ -10,6 +10,11 @@
   uint value;
 };
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+};
+
 layout(binding = 1, std140)
 uniform params_block_1_ubo {
   Params inner;
@@ -20,31 +25,36 @@
   Flip inner;
 } v_1;
 shared vec3 tile[4][256];
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_2;
 uniform highp sampler2D inputTex_samp;
 uint tint_div_u32(uint lhs, uint rhs) {
   return (lhs / mix(rhs, 1u, (rhs == 0u)));
 }
 void tint_symbol_inner(uvec3 WorkGroupID, uvec3 LocalInvocationID, uint tint_local_index) {
   {
-    uint v_2 = 0u;
-    v_2 = tint_local_index;
+    uint v_3 = 0u;
+    v_3 = tint_local_index;
     while(true) {
-      uint v_3 = v_2;
-      if ((v_3 >= 1024u)) {
+      uint v_4 = v_3;
+      if ((v_4 >= 1024u)) {
         break;
       }
-      tile[(v_3 / 256u)][(v_3 % 256u)] = vec3(0.0f);
+      tile[(v_4 / 256u)][(v_4 % 256u)] = vec3(0.0f);
       {
-        v_2 = (v_3 + 64u);
+        v_3 = (v_4 + 64u);
       }
       continue;
     }
   }
   barrier();
   uint filterOffset = tint_div_u32((v.inner.filterDim - 1u), 2u);
-  uvec2 dims = uvec2(textureSize(inputTex_samp, 0));
-  uvec2 v_4 = ((WorkGroupID.xy * uvec2(v.inner.blockDim, 4u)) + (LocalInvocationID.xy * uvec2(4u, 1u)));
-  uvec2 baseIndex = (v_4 - uvec2(filterOffset, 0u));
+  uint v_5 = (v_2.inner.tint_builtin_value_0 - 1u);
+  uvec2 dims = uvec2(textureSize(inputTex_samp, int(min(uint(0), v_5))));
+  uvec2 v_6 = ((WorkGroupID.xy * uvec2(v.inner.blockDim, 4u)) + (LocalInvocationID.xy * uvec2(4u, 1u)));
+  uvec2 baseIndex = (v_6 - uvec2(filterOffset, 0u));
   {
     uint r = 0u;
     while(true) {
@@ -63,11 +73,11 @@
           if ((v_1.inner.value != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          uint v_5 = r;
-          uint v_6 = ((4u * LocalInvocationID[0u]) + c);
-          vec2 v_7 = (vec2(loadIndex) + vec2(0.25f));
-          vec2 v_8 = (v_7 / vec2(dims));
-          tile[v_5][v_6] = textureLod(inputTex_samp, v_8, float(0.0f)).xyz;
+          uint v_7 = min(r, 3u);
+          uint v_8 = min(((4u * LocalInvocationID[0u]) + c), 255u);
+          vec2 v_9 = (vec2(loadIndex) + vec2(0.25f));
+          vec2 v_10 = (v_9 / vec2(dims));
+          tile[v_7][v_8] = textureLod(inputTex_samp, v_10, float(0.0f)).xyz;
           {
             c = (c + 1u);
           }
@@ -100,19 +110,19 @@
             writeIndex = writeIndex.yx;
           }
           uint center = ((4u * LocalInvocationID[0u]) + c);
-          bool v_9 = false;
+          bool v_11 = false;
           if ((center >= filterOffset)) {
-            v_9 = (center < (256u - filterOffset));
+            v_11 = (center < (256u - filterOffset));
           } else {
-            v_9 = false;
+            v_11 = false;
           }
-          bool v_10 = false;
-          if (v_9) {
-            v_10 = all(lessThan(writeIndex, dims));
+          bool v_12 = false;
+          if (v_11) {
+            v_12 = all(lessThan(writeIndex, dims));
           } else {
-            v_10 = false;
+            v_12 = false;
           }
-          if (v_10) {
+          if (v_12) {
             vec3 acc = vec3(0.0f);
             {
               uint f = 0u;
@@ -122,20 +132,20 @@
                   break;
                 }
                 uint i = ((center + f) - filterOffset);
-                vec3 v_11 = acc;
-                float v_12 = (1.0f / float(v.inner.filterDim));
-                uint v_13 = r;
-                uint v_14 = i;
-                acc = (v_11 + (v_12 * tile[v_13][v_14]));
+                vec3 v_13 = acc;
+                float v_14 = (1.0f / float(v.inner.filterDim));
+                uint v_15 = min(r, 3u);
+                uint v_16 = min(i, 255u);
+                acc = (v_13 + (v_14 * tile[v_15][v_16]));
                 {
                   f = (f + 1u);
                 }
                 continue;
               }
             }
-            uvec2 v_15 = writeIndex;
-            vec4 v_16 = vec4(acc, 1.0f);
-            imageStore(outputTex, ivec2(v_15), v_16);
+            uvec2 v_17 = writeIndex;
+            vec4 v_18 = vec4(acc, 1.0f);
+            imageStore(outputTex, ivec2(v_17), v_18);
           }
           {
             c = (c + 1u);
diff --git a/test/tint/bug/tint/942.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.ir.dxc.hlsl
index ab1e98b..165210c 100644
--- a/test/tint/bug/tint/942.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/942.wgsl.expected.ir.dxc.hlsl
@@ -38,10 +38,12 @@
   GroupMemoryBarrierWithGroupSync();
   uint filterOffset = tint_div_u32((params[0u].x - 1u), 2u);
   uint3 v_2 = (0u).xxx;
-  inputTex.GetDimensions(uint(int(0)), v_2.x, v_2.y, v_2.z);
-  uint2 dims = v_2.xy;
-  uint2 v_3 = ((WorkGroupID.xy * uint2(params[0u].y, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u)));
-  uint2 baseIndex = (v_3 - uint2(filterOffset, 0u));
+  inputTex.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  inputTex.GetDimensions(uint(min(uint(int(0)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 dims = v_3.xy;
+  uint2 v_4 = ((WorkGroupID.xy * uint2(params[0u].y, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u)));
+  uint2 baseIndex = (v_4 - uint2(filterOffset, 0u));
   {
     uint r = 0u;
     while(true) {
@@ -60,11 +62,11 @@
           if ((flip[0u].x != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          uint v_4 = r;
-          uint v_5 = ((4u * LocalInvocationID.x) + c);
-          float2 v_6 = (float2(loadIndex) + (0.25f).xx);
-          float2 v_7 = (v_6 / float2(dims));
-          tile[v_4][v_5] = inputTex.SampleLevel(samp, v_7, float(0.0f)).xyz;
+          uint v_5 = min(r, 3u);
+          uint v_6 = min(((4u * LocalInvocationID.x) + c), 255u);
+          float2 v_7 = (float2(loadIndex) + (0.25f).xx);
+          float2 v_8 = (v_7 / float2(dims));
+          tile[v_5][v_6] = inputTex.SampleLevel(samp, v_8, float(0.0f)).xyz;
           {
             c = (c + 1u);
           }
@@ -97,19 +99,19 @@
             writeIndex = writeIndex.yx;
           }
           uint center = ((4u * LocalInvocationID.x) + c);
-          bool v_8 = false;
-          if ((center >= filterOffset)) {
-            v_8 = (center < (256u - filterOffset));
-          } else {
-            v_8 = false;
-          }
           bool v_9 = false;
-          if (v_8) {
-            v_9 = all((writeIndex < dims));
+          if ((center >= filterOffset)) {
+            v_9 = (center < (256u - filterOffset));
           } else {
             v_9 = false;
           }
+          bool v_10 = false;
           if (v_9) {
+            v_10 = all((writeIndex < dims));
+          } else {
+            v_10 = false;
+          }
+          if (v_10) {
             float3 acc = (0.0f).xxx;
             {
               uint f = 0u;
@@ -119,19 +121,19 @@
                   break;
                 }
                 uint i = ((center + f) - filterOffset);
-                float3 v_10 = acc;
-                float v_11 = (1.0f / float(params[0u].x));
-                uint v_12 = r;
-                uint v_13 = i;
-                acc = (v_10 + (v_11 * tile[v_12][v_13]));
+                float3 v_11 = acc;
+                float v_12 = (1.0f / float(params[0u].x));
+                uint v_13 = min(r, 3u);
+                uint v_14 = min(i, 255u);
+                acc = (v_11 + (v_12 * tile[v_13][v_14]));
                 {
                   f = (f + 1u);
                 }
                 continue;
               }
             }
-            uint2 v_14 = writeIndex;
-            outputTex[v_14] = float4(acc, 1.0f);
+            uint2 v_15 = writeIndex;
+            outputTex[v_15] = float4(acc, 1.0f);
           }
           {
             c = (c + 1u);
diff --git a/test/tint/bug/tint/942.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/942.wgsl.expected.ir.fxc.hlsl
index ab1e98b..165210c 100644
--- a/test/tint/bug/tint/942.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/942.wgsl.expected.ir.fxc.hlsl
@@ -38,10 +38,12 @@
   GroupMemoryBarrierWithGroupSync();
   uint filterOffset = tint_div_u32((params[0u].x - 1u), 2u);
   uint3 v_2 = (0u).xxx;
-  inputTex.GetDimensions(uint(int(0)), v_2.x, v_2.y, v_2.z);
-  uint2 dims = v_2.xy;
-  uint2 v_3 = ((WorkGroupID.xy * uint2(params[0u].y, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u)));
-  uint2 baseIndex = (v_3 - uint2(filterOffset, 0u));
+  inputTex.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  inputTex.GetDimensions(uint(min(uint(int(0)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 dims = v_3.xy;
+  uint2 v_4 = ((WorkGroupID.xy * uint2(params[0u].y, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u)));
+  uint2 baseIndex = (v_4 - uint2(filterOffset, 0u));
   {
     uint r = 0u;
     while(true) {
@@ -60,11 +62,11 @@
           if ((flip[0u].x != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          uint v_4 = r;
-          uint v_5 = ((4u * LocalInvocationID.x) + c);
-          float2 v_6 = (float2(loadIndex) + (0.25f).xx);
-          float2 v_7 = (v_6 / float2(dims));
-          tile[v_4][v_5] = inputTex.SampleLevel(samp, v_7, float(0.0f)).xyz;
+          uint v_5 = min(r, 3u);
+          uint v_6 = min(((4u * LocalInvocationID.x) + c), 255u);
+          float2 v_7 = (float2(loadIndex) + (0.25f).xx);
+          float2 v_8 = (v_7 / float2(dims));
+          tile[v_5][v_6] = inputTex.SampleLevel(samp, v_8, float(0.0f)).xyz;
           {
             c = (c + 1u);
           }
@@ -97,19 +99,19 @@
             writeIndex = writeIndex.yx;
           }
           uint center = ((4u * LocalInvocationID.x) + c);
-          bool v_8 = false;
-          if ((center >= filterOffset)) {
-            v_8 = (center < (256u - filterOffset));
-          } else {
-            v_8 = false;
-          }
           bool v_9 = false;
-          if (v_8) {
-            v_9 = all((writeIndex < dims));
+          if ((center >= filterOffset)) {
+            v_9 = (center < (256u - filterOffset));
           } else {
             v_9 = false;
           }
+          bool v_10 = false;
           if (v_9) {
+            v_10 = all((writeIndex < dims));
+          } else {
+            v_10 = false;
+          }
+          if (v_10) {
             float3 acc = (0.0f).xxx;
             {
               uint f = 0u;
@@ -119,19 +121,19 @@
                   break;
                 }
                 uint i = ((center + f) - filterOffset);
-                float3 v_10 = acc;
-                float v_11 = (1.0f / float(params[0u].x));
-                uint v_12 = r;
-                uint v_13 = i;
-                acc = (v_10 + (v_11 * tile[v_12][v_13]));
+                float3 v_11 = acc;
+                float v_12 = (1.0f / float(params[0u].x));
+                uint v_13 = min(r, 3u);
+                uint v_14 = min(i, 255u);
+                acc = (v_11 + (v_12 * tile[v_13][v_14]));
                 {
                   f = (f + 1u);
                 }
                 continue;
               }
             }
-            uint2 v_14 = writeIndex;
-            outputTex[v_14] = float4(acc, 1.0f);
+            uint2 v_15 = writeIndex;
+            outputTex[v_15] = float4(acc, 1.0f);
           }
           {
             c = (c + 1u);
diff --git a/test/tint/bug/tint/942.wgsl.expected.ir.msl b/test/tint/bug/tint/942.wgsl.expected.ir.msl
index e0dc07f..ffcf190 100644
--- a/test/tint/bug/tint/942.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/942.wgsl.expected.ir.msl
@@ -35,6 +35,9 @@
   threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 256>, 4>* tile;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<tint_array<tint_packed_vec3_f32_array_element, 256>, 4> tint_symbol_1;
 };
@@ -48,6 +51,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 1024u)) {
         break;
@@ -61,7 +65,7 @@
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   uint const filterOffset = tint_div_u32(((*tint_module_vars.params).filterDim - 1u), 2u);
-  uint const v_2 = uint(0);
+  uint const v_2 = min(uint(0), (tint_module_vars.inputTex.get_num_mip_levels() - 1u));
   uint2 const dims = uint2(tint_module_vars.inputTex.get_width(v_2), tint_module_vars.inputTex.get_height(v_2));
   uint2 const v_3 = ((WorkGroupID.xy * uint2((*tint_module_vars.params).blockDim, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u)));
   uint2 const baseIndex = (v_3 - uint2(filterOffset, 0u));
@@ -83,7 +87,7 @@
           if (((*tint_module_vars.flip).value != 0u)) {
             loadIndex = loadIndex.yx;
           }
-          threadgroup packed_float3* const v_4 = (&(*tint_module_vars.tile)[r][((4u * LocalInvocationID[0u]) + c)].packed);
+          threadgroup packed_float3* const v_4 = (&(*tint_module_vars.tile)[min(r, 3u)][min(((4u * LocalInvocationID[0u]) + c), 255u)].packed);
           float2 const v_5 = (float2(loadIndex) + float2(0.25f));
           float2 const v_6 = (v_5 / float2(dims));
           (*v_4) = packed_float3(tint_module_vars.inputTex.sample(tint_module_vars.samp, v_6, level(0.0f)).xyz);
@@ -136,6 +140,7 @@
             {
               uint f = 0u;
               while(true) {
+                TINT_ISOLATE_UB(tint_volatile_false_1)
                 if ((f < (*tint_module_vars.params).filterDim)) {
                 } else {
                   break;
@@ -143,7 +148,7 @@
                 uint i = ((center + f) - filterOffset);
                 float3 const v_9 = acc;
                 float const v_10 = (1.0f / float((*tint_module_vars.params).filterDim));
-                acc = (v_9 + (v_10 * float3((*tint_module_vars.tile)[r][i].packed)));
+                acc = (v_9 + (v_10 * float3((*tint_module_vars.tile)[min(r, 3u)][min(i, 255u)].packed)));
                 {
                   f = (f + 1u);
                 }
diff --git a/test/tint/bug/tint/942.wgsl.expected.msl b/test/tint/bug/tint/942.wgsl.expected.msl
index 97a2c6f..4df2321 100644
--- a/test/tint/bug/tint/942.wgsl.expected.msl
+++ b/test/tint/bug/tint/942.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_packed_vec3_f32_array_element {
   packed_float3 elements;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 256>, 4>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 1024u); idx = (idx + 64u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i_1 = (idx / 256u);
     uint const i_2 = (idx % 256u);
     (*(tint_symbol_1))[i_1][i_2].elements = packed_float3(0.0f);
@@ -43,20 +47,25 @@
 void tint_symbol_inner(uint3 WorkGroupID, uint3 LocalInvocationID, uint local_invocation_index, threadgroup tint_array<tint_array<tint_packed_vec3_f32_array_element, 256>, 4>* const tint_symbol_2, const constant Params* const tint_symbol_3, texture2d<float, access::sample> tint_symbol_4, const constant Flip* const tint_symbol_5, sampler tint_symbol_6, texture2d<float, access::write> tint_symbol_7) {
   tint_zero_workgroup_memory(local_invocation_index, tint_symbol_2);
   uint const filterOffset = tint_div(((*(tint_symbol_3)).filterDim - 1u), 2u);
-  uint2 const dims = uint2(tint_symbol_4.get_width(0), tint_symbol_4.get_height(0));
+  uint const level_idx = min(0u, (tint_symbol_4.get_num_mip_levels() - 1u));
+  uint2 const dims = uint2(tint_symbol_4.get_width(level_idx), tint_symbol_4.get_height(level_idx));
   uint2 const baseIndex = (((WorkGroupID.xy * uint2((*(tint_symbol_3)).blockDim, 4u)) + (LocalInvocationID.xy * uint2(4u, 1u))) - uint2(filterOffset, 0u));
   for(uint r = 0u; (r < 4u); r = (r + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     for(uint c = 0u; (c < 4u); c = (c + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_2);
       uint2 loadIndex = (baseIndex + uint2(c, r));
       if (((*(tint_symbol_5)).value != 0u)) {
         loadIndex = loadIndex.yx;
       }
-      (*(tint_symbol_2))[r][((4u * LocalInvocationID[0]) + c)].elements = packed_float3(tint_symbol_4.sample(tint_symbol_6, ((float2(loadIndex) + float2(0.25f)) / float2(dims)), level(0.0f)).rgb);
+      (*(tint_symbol_2))[min(r, 3u)][min(((4u * LocalInvocationID[0]) + c), 255u)].elements = packed_float3(tint_symbol_4.sample(tint_symbol_6, ((float2(loadIndex) + float2(0.25f)) / float2(dims)), level(0.0f)).rgb);
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
   for(uint r = 0u; (r < 4u); r = (r + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false_3);
     for(uint c = 0u; (c < 4u); c = (c + 1u)) {
+      TINT_ISOLATE_UB(tint_volatile_false_4);
       uint2 writeIndex = (baseIndex + uint2(c, r));
       if (((*(tint_symbol_5)).value != 0u)) {
         writeIndex = writeIndex.yx;
@@ -65,8 +74,9 @@
       if ((((center >= filterOffset) && (center < (256u - filterOffset))) && all((writeIndex < dims)))) {
         float3 acc = float3(0.0f);
         for(uint f = 0u; (f < (*(tint_symbol_3)).filterDim); f = (f + 1u)) {
+          TINT_ISOLATE_UB(tint_volatile_false_5);
           uint i = ((center + f) - filterOffset);
-          acc = (acc + ((1.0f / float((*(tint_symbol_3)).filterDim)) * float3((*(tint_symbol_2))[r][i].elements)));
+          acc = (acc + ((1.0f / float((*(tint_symbol_3)).filterDim)) * float3((*(tint_symbol_2))[min(r, 3u)][min(i, 255u)].elements)));
         }
         tint_symbol_7.write(float4(acc, 1.0f), uint2(writeIndex));
       }
diff --git a/test/tint/bug/tint/942.wgsl.expected.spvasm b/test/tint/bug/tint/942.wgsl.expected.spvasm
index fd2a95a..2d006e2 100644
--- a/test/tint/bug/tint/942.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/942.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 255
+; Bound: 266
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %76 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_workgroup_id_Input %main_local_invocation_id_Input %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 64 1 1
@@ -114,24 +115,26 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-     %v2uint = OpTypeVector %uint 2
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
-         %81 = OpConstantComposite %v2uint %uint_4 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %86 = OpConstantComposite %v2uint %uint_4 %uint_1
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
+     %uint_3 = OpConstant %uint 3
+   %uint_255 = OpConstant %uint 255
     %v2float = OpTypeVector %float 2
  %float_0_25 = OpConstant %float 0.25
-        %131 = OpConstantComposite %v2float %float_0_25 %float_0_25
-        %136 = OpTypeSampledImage %11
+        %140 = OpConstantComposite %v2float %float_0_25 %float_0_25
+        %145 = OpTypeSampledImage %11
     %v4float = OpTypeVector %float 4
     %float_0 = OpConstant %float 0
       %false = OpConstantFalse %bool
      %v2bool = OpTypeVector %bool 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
     %float_1 = OpConstant %float 1
-        %243 = OpTypeFunction %uint %uint %uint
-        %249 = OpTypeFunction %void
+        %254 = OpTypeFunction %uint %uint %uint
+        %260 = OpTypeFunction %void
  %main_inner = OpFunction %void None %38
 %WorkGroupID = OpFunctionParameter %v3uint
 %LocalInvocationID = OpFunctionParameter %v3uint
@@ -175,248 +178,256 @@
          %65 = OpISub %uint %64 %uint_1
 %filterOffset = OpFunctionCall %uint %tint_div_u32 %65 %uint_2
          %69 = OpLoad %11 %inputTex None
-       %dims = OpImageQuerySizeLod %v2uint %69 %int_0
-         %74 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1
-         %75 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_1
-         %76 = OpLoad %uint %75 None
-         %77 = OpCompositeConstruct %v2uint %76 %uint_4
-         %78 = OpIMul %v2uint %74 %77
-         %79 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1
-         %80 = OpIMul %v2uint %79 %81
-         %82 = OpIAdd %v2uint %78 %80
-         %83 = OpCompositeConstruct %v2uint %filterOffset %uint_0
-  %baseIndex = OpISub %v2uint %82 %83
-               OpBranch %85
-         %85 = OpLabel
+         %70 = OpImageQueryLevels %uint %69
+         %71 = OpISub %uint %70 %uint_1
+         %72 = OpBitcast %uint %int_0
+         %75 = OpExtInst %uint %76 UMin %72 %71
+       %dims = OpImageQuerySizeLod %v2uint %69 %75
+         %79 = OpVectorShuffle %v2uint %WorkGroupID %WorkGroupID 0 1
+         %80 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_1
+         %81 = OpLoad %uint %80 None
+         %82 = OpCompositeConstruct %v2uint %81 %uint_4
+         %83 = OpIMul %v2uint %79 %82
+         %84 = OpVectorShuffle %v2uint %LocalInvocationID %LocalInvocationID 0 1
+         %85 = OpIMul %v2uint %84 %86
+         %87 = OpIAdd %v2uint %83 %85
+         %88 = OpCompositeConstruct %v2uint %filterOffset %uint_0
+  %baseIndex = OpISub %v2uint %87 %88
+               OpBranch %90
+         %90 = OpLabel
                OpStore %r %uint_0
-               OpBranch %88
-         %88 = OpLabel
-               OpLoopMerge %89 %87 None
-               OpBranch %86
-         %86 = OpLabel
-         %92 = OpLoad %uint %r None
-         %93 = OpULessThan %bool %92 %uint_4
-               OpSelectionMerge %94 None
-               OpBranchConditional %93 %94 %95
-         %95 = OpLabel
-               OpBranch %89
-         %94 = OpLabel
-               OpBranch %96
-         %96 = OpLabel
-               OpStore %c %uint_0
-               OpBranch %99
-         %99 = OpLabel
-               OpLoopMerge %100 %98 None
-               OpBranch %97
-         %97 = OpLabel
-        %102 = OpLoad %uint %c None
-        %103 = OpULessThan %bool %102 %uint_4
-               OpSelectionMerge %104 None
-               OpBranchConditional %103 %104 %105
-        %105 = OpLabel
-               OpBranch %100
-        %104 = OpLabel
-        %106 = OpLoad %uint %c None
-        %107 = OpLoad %uint %r None
-        %108 = OpCompositeConstruct %v2uint %106 %107
-        %109 = OpIAdd %v2uint %baseIndex %108
-               OpStore %loadIndex %109
-        %112 = OpAccessChain %_ptr_Uniform_uint %16 %uint_0 %uint_0
-        %113 = OpLoad %uint %112 None
-        %114 = OpINotEqual %bool %113 %uint_0
-               OpSelectionMerge %115 None
-               OpBranchConditional %114 %116 %115
-        %116 = OpLabel
-        %117 = OpLoad %v2uint %loadIndex None
-        %118 = OpVectorShuffle %v2uint %117 %117 1 0
-               OpStore %loadIndex %118 None
-               OpBranch %115
-        %115 = OpLabel
-        %119 = OpLoad %uint %r None
-        %120 = OpCompositeExtract %uint %LocalInvocationID 0
-        %121 = OpIMul %uint %uint_4 %120
-        %122 = OpLoad %uint %c None
-        %123 = OpIAdd %uint %121 %122
-        %124 = OpAccessChain %_ptr_Workgroup_v3float %tile %119 %123
-        %125 = OpLoad %11 %inputTex None
-        %126 = OpLoad %3 %samp None
-        %127 = OpLoad %v2uint %loadIndex None
-        %129 = OpConvertUToF %v2float %127
-        %130 = OpFAdd %v2float %129 %131
-        %133 = OpConvertUToF %v2float %dims
-        %134 = OpFDiv %v2float %130 %133
-        %135 = OpSampledImage %136 %125 %126
-        %137 = OpImageSampleExplicitLod %v4float %135 %134 Lod %float_0
-        %140 = OpVectorShuffle %v3float %137 %137 0 1 2
-               OpStore %124 %140 None
-               OpBranch %98
-         %98 = OpLabel
-        %141 = OpLoad %uint %c None
-        %142 = OpIAdd %uint %141 %uint_1
-               OpStore %c %142 None
-               OpBranch %99
+               OpBranch %93
+         %93 = OpLabel
+               OpLoopMerge %94 %92 None
+               OpBranch %91
+         %91 = OpLabel
+         %97 = OpLoad %uint %r None
+         %98 = OpULessThan %bool %97 %uint_4
+               OpSelectionMerge %99 None
+               OpBranchConditional %98 %99 %100
         %100 = OpLabel
-               OpBranch %87
-         %87 = OpLabel
-        %143 = OpLoad %uint %r None
-        %144 = OpIAdd %uint %143 %uint_1
-               OpStore %r %144 None
-               OpBranch %88
-         %89 = OpLabel
+               OpBranch %94
+         %99 = OpLabel
+               OpBranch %101
+        %101 = OpLabel
+               OpStore %c %uint_0
+               OpBranch %104
+        %104 = OpLabel
+               OpLoopMerge %105 %103 None
+               OpBranch %102
+        %102 = OpLabel
+        %107 = OpLoad %uint %c None
+        %108 = OpULessThan %bool %107 %uint_4
+               OpSelectionMerge %109 None
+               OpBranchConditional %108 %109 %110
+        %110 = OpLabel
+               OpBranch %105
+        %109 = OpLabel
+        %111 = OpLoad %uint %c None
+        %112 = OpLoad %uint %r None
+        %113 = OpCompositeConstruct %v2uint %111 %112
+        %114 = OpIAdd %v2uint %baseIndex %113
+               OpStore %loadIndex %114
+        %117 = OpAccessChain %_ptr_Uniform_uint %16 %uint_0 %uint_0
+        %118 = OpLoad %uint %117 None
+        %119 = OpINotEqual %bool %118 %uint_0
+               OpSelectionMerge %120 None
+               OpBranchConditional %119 %121 %120
+        %121 = OpLabel
+        %122 = OpLoad %v2uint %loadIndex None
+        %123 = OpVectorShuffle %v2uint %122 %122 1 0
+               OpStore %loadIndex %123 None
+               OpBranch %120
+        %120 = OpLabel
+        %124 = OpLoad %uint %r None
+        %125 = OpCompositeExtract %uint %LocalInvocationID 0
+        %126 = OpIMul %uint %uint_4 %125
+        %127 = OpLoad %uint %c None
+        %128 = OpIAdd %uint %126 %127
+        %129 = OpExtInst %uint %76 UMin %124 %uint_3
+        %131 = OpExtInst %uint %76 UMin %128 %uint_255
+        %133 = OpAccessChain %_ptr_Workgroup_v3float %tile %129 %131
+        %134 = OpLoad %11 %inputTex None
+        %135 = OpLoad %3 %samp None
+        %136 = OpLoad %v2uint %loadIndex None
+        %138 = OpConvertUToF %v2float %136
+        %139 = OpFAdd %v2float %138 %140
+        %142 = OpConvertUToF %v2float %dims
+        %143 = OpFDiv %v2float %139 %142
+        %144 = OpSampledImage %145 %134 %135
+        %146 = OpImageSampleExplicitLod %v4float %144 %143 Lod %float_0
+        %149 = OpVectorShuffle %v3float %146 %146 0 1 2
+               OpStore %133 %149 None
+               OpBranch %103
+        %103 = OpLabel
+        %150 = OpLoad %uint %c None
+        %151 = OpIAdd %uint %150 %uint_1
+               OpStore %c %151 None
+               OpBranch %104
+        %105 = OpLabel
+               OpBranch %92
+         %92 = OpLabel
+        %152 = OpLoad %uint %r None
+        %153 = OpIAdd %uint %152 %uint_1
+               OpStore %r %153 None
+               OpBranch %93
+         %94 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-               OpBranch %146
-        %146 = OpLabel
-               OpStore %r_0 %uint_0
-               OpBranch %149
-        %149 = OpLabel
-               OpLoopMerge %150 %148 None
-               OpBranch %147
-        %147 = OpLabel
-        %152 = OpLoad %uint %r_0 None
-        %153 = OpULessThan %bool %152 %uint_4
-               OpSelectionMerge %154 None
-               OpBranchConditional %153 %154 %155
+               OpBranch %155
         %155 = OpLabel
-               OpBranch %150
-        %154 = OpLabel
-               OpBranch %156
-        %156 = OpLabel
-               OpStore %c_0 %uint_0
-               OpBranch %159
-        %159 = OpLabel
-               OpLoopMerge %160 %158 None
-               OpBranch %157
-        %157 = OpLabel
-        %162 = OpLoad %uint %c_0 None
-        %163 = OpULessThan %bool %162 %uint_4
-               OpSelectionMerge %164 None
-               OpBranchConditional %163 %164 %165
-        %165 = OpLabel
-               OpBranch %160
-        %164 = OpLabel
-        %166 = OpLoad %uint %c_0 None
-        %167 = OpLoad %uint %r_0 None
-        %168 = OpCompositeConstruct %v2uint %166 %167
-        %169 = OpIAdd %v2uint %baseIndex %168
-               OpStore %writeIndex %169
-        %171 = OpAccessChain %_ptr_Uniform_uint %16 %uint_0 %uint_0
-        %172 = OpLoad %uint %171 None
-        %173 = OpINotEqual %bool %172 %uint_0
-               OpSelectionMerge %174 None
-               OpBranchConditional %173 %175 %174
-        %175 = OpLabel
-        %176 = OpLoad %v2uint %writeIndex None
-        %177 = OpVectorShuffle %v2uint %176 %176 1 0
-               OpStore %writeIndex %177 None
-               OpBranch %174
-        %174 = OpLabel
-        %178 = OpCompositeExtract %uint %LocalInvocationID 0
-        %179 = OpIMul %uint %uint_4 %178
-        %180 = OpLoad %uint %c_0 None
-     %center = OpIAdd %uint %179 %180
-        %182 = OpUGreaterThanEqual %bool %center %filterOffset
-               OpSelectionMerge %183 None
-               OpBranchConditional %182 %184 %185
-        %184 = OpLabel
-        %186 = OpISub %uint %uint_256 %filterOffset
-        %187 = OpULessThan %bool %center %186
-               OpBranch %183
-        %185 = OpLabel
-               OpBranch %183
-        %183 = OpLabel
-        %188 = OpPhi %bool %187 %184 %false %185
-               OpSelectionMerge %190 None
-               OpBranchConditional %188 %191 %192
-        %191 = OpLabel
-        %193 = OpLoad %v2uint %writeIndex None
-        %194 = OpULessThan %v2bool %193 %dims
-        %196 = OpAll %bool %194
-               OpBranch %190
-        %192 = OpLabel
-               OpBranch %190
-        %190 = OpLabel
-        %197 = OpPhi %bool %196 %191 %false %192
-               OpSelectionMerge %198 None
-               OpBranchConditional %197 %199 %198
-        %199 = OpLabel
-               OpStore %acc %56
-               OpBranch %202
-        %202 = OpLabel
-               OpStore %f %uint_0
-               OpBranch %205
-        %205 = OpLabel
-               OpLoopMerge %206 %204 None
-               OpBranch %203
-        %203 = OpLabel
-        %208 = OpLoad %uint %f None
-        %209 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_0
-        %210 = OpLoad %uint %209 None
-        %211 = OpULessThan %bool %208 %210
-               OpSelectionMerge %212 None
-               OpBranchConditional %211 %212 %213
-        %213 = OpLabel
-               OpBranch %206
-        %212 = OpLabel
-        %214 = OpLoad %uint %f None
-        %215 = OpIAdd %uint %center %214
-        %216 = OpISub %uint %215 %filterOffset
-               OpStore %i %216
-        %218 = OpLoad %v3float %acc None
-        %219 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_0
-        %220 = OpLoad %uint %219 None
-        %221 = OpConvertUToF %float %220
-        %222 = OpFDiv %float %float_1 %221
-        %224 = OpLoad %uint %r_0 None
-        %225 = OpLoad %uint %i None
-        %226 = OpAccessChain %_ptr_Workgroup_v3float %tile %224 %225
-        %227 = OpLoad %v3float %226 None
-        %228 = OpVectorTimesScalar %v3float %227 %222
-        %229 = OpFAdd %v3float %218 %228
-               OpStore %acc %229 None
-               OpBranch %204
-        %204 = OpLabel
-        %230 = OpLoad %uint %f None
-        %231 = OpIAdd %uint %230 %uint_1
-               OpStore %f %231 None
-               OpBranch %205
-        %206 = OpLabel
-        %232 = OpLoad %15 %outputTex None
-        %233 = OpLoad %v2uint %writeIndex None
-        %234 = OpLoad %v3float %acc None
-        %235 = OpCompositeConstruct %v4float %234 %float_1
-               OpImageWrite %232 %233 %235 None
-               OpBranch %198
-        %198 = OpLabel
+               OpStore %r_0 %uint_0
                OpBranch %158
         %158 = OpLabel
-        %237 = OpLoad %uint %c_0 None
-        %238 = OpIAdd %uint %237 %uint_1
-               OpStore %c_0 %238 None
+               OpLoopMerge %159 %157 None
+               OpBranch %156
+        %156 = OpLabel
+        %161 = OpLoad %uint %r_0 None
+        %162 = OpULessThan %bool %161 %uint_4
+               OpSelectionMerge %163 None
+               OpBranchConditional %162 %163 %164
+        %164 = OpLabel
                OpBranch %159
-        %160 = OpLabel
-               OpBranch %148
-        %148 = OpLabel
-        %239 = OpLoad %uint %r_0 None
-        %240 = OpIAdd %uint %239 %uint_1
-               OpStore %r_0 %240 None
-               OpBranch %149
-        %150 = OpLabel
+        %163 = OpLabel
+               OpBranch %165
+        %165 = OpLabel
+               OpStore %c_0 %uint_0
+               OpBranch %168
+        %168 = OpLabel
+               OpLoopMerge %169 %167 None
+               OpBranch %166
+        %166 = OpLabel
+        %171 = OpLoad %uint %c_0 None
+        %172 = OpULessThan %bool %171 %uint_4
+               OpSelectionMerge %173 None
+               OpBranchConditional %172 %173 %174
+        %174 = OpLabel
+               OpBranch %169
+        %173 = OpLabel
+        %175 = OpLoad %uint %c_0 None
+        %176 = OpLoad %uint %r_0 None
+        %177 = OpCompositeConstruct %v2uint %175 %176
+        %178 = OpIAdd %v2uint %baseIndex %177
+               OpStore %writeIndex %178
+        %180 = OpAccessChain %_ptr_Uniform_uint %16 %uint_0 %uint_0
+        %181 = OpLoad %uint %180 None
+        %182 = OpINotEqual %bool %181 %uint_0
+               OpSelectionMerge %183 None
+               OpBranchConditional %182 %184 %183
+        %184 = OpLabel
+        %185 = OpLoad %v2uint %writeIndex None
+        %186 = OpVectorShuffle %v2uint %185 %185 1 0
+               OpStore %writeIndex %186 None
+               OpBranch %183
+        %183 = OpLabel
+        %187 = OpCompositeExtract %uint %LocalInvocationID 0
+        %188 = OpIMul %uint %uint_4 %187
+        %189 = OpLoad %uint %c_0 None
+     %center = OpIAdd %uint %188 %189
+        %191 = OpUGreaterThanEqual %bool %center %filterOffset
+               OpSelectionMerge %192 None
+               OpBranchConditional %191 %193 %194
+        %193 = OpLabel
+        %195 = OpISub %uint %uint_256 %filterOffset
+        %196 = OpULessThan %bool %center %195
+               OpBranch %192
+        %194 = OpLabel
+               OpBranch %192
+        %192 = OpLabel
+        %197 = OpPhi %bool %196 %193 %false %194
+               OpSelectionMerge %199 None
+               OpBranchConditional %197 %200 %201
+        %200 = OpLabel
+        %202 = OpLoad %v2uint %writeIndex None
+        %203 = OpULessThan %v2bool %202 %dims
+        %205 = OpAll %bool %203
+               OpBranch %199
+        %201 = OpLabel
+               OpBranch %199
+        %199 = OpLabel
+        %206 = OpPhi %bool %205 %200 %false %201
+               OpSelectionMerge %207 None
+               OpBranchConditional %206 %208 %207
+        %208 = OpLabel
+               OpStore %acc %56
+               OpBranch %211
+        %211 = OpLabel
+               OpStore %f %uint_0
+               OpBranch %214
+        %214 = OpLabel
+               OpLoopMerge %215 %213 None
+               OpBranch %212
+        %212 = OpLabel
+        %217 = OpLoad %uint %f None
+        %218 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_0
+        %219 = OpLoad %uint %218 None
+        %220 = OpULessThan %bool %217 %219
+               OpSelectionMerge %221 None
+               OpBranchConditional %220 %221 %222
+        %222 = OpLabel
+               OpBranch %215
+        %221 = OpLabel
+        %223 = OpLoad %uint %f None
+        %224 = OpIAdd %uint %center %223
+        %225 = OpISub %uint %224 %filterOffset
+               OpStore %i %225
+        %227 = OpLoad %v3float %acc None
+        %228 = OpAccessChain %_ptr_Uniform_uint %4 %uint_0 %uint_0
+        %229 = OpLoad %uint %228 None
+        %230 = OpConvertUToF %float %229
+        %231 = OpFDiv %float %float_1 %230
+        %233 = OpLoad %uint %r_0 None
+        %234 = OpLoad %uint %i None
+        %235 = OpExtInst %uint %76 UMin %233 %uint_3
+        %236 = OpExtInst %uint %76 UMin %234 %uint_255
+        %237 = OpAccessChain %_ptr_Workgroup_v3float %tile %235 %236
+        %238 = OpLoad %v3float %237 None
+        %239 = OpVectorTimesScalar %v3float %238 %231
+        %240 = OpFAdd %v3float %227 %239
+               OpStore %acc %240 None
+               OpBranch %213
+        %213 = OpLabel
+        %241 = OpLoad %uint %f None
+        %242 = OpIAdd %uint %241 %uint_1
+               OpStore %f %242 None
+               OpBranch %214
+        %215 = OpLabel
+        %243 = OpLoad %15 %outputTex None
+        %244 = OpLoad %v2uint %writeIndex None
+        %245 = OpLoad %v3float %acc None
+        %246 = OpCompositeConstruct %v4float %245 %float_1
+               OpImageWrite %243 %244 %246 None
+               OpBranch %207
+        %207 = OpLabel
+               OpBranch %167
+        %167 = OpLabel
+        %248 = OpLoad %uint %c_0 None
+        %249 = OpIAdd %uint %248 %uint_1
+               OpStore %c_0 %249 None
+               OpBranch %168
+        %169 = OpLabel
+               OpBranch %157
+        %157 = OpLabel
+        %250 = OpLoad %uint %r_0 None
+        %251 = OpIAdd %uint %250 %uint_1
+               OpStore %r_0 %251 None
+               OpBranch %158
+        %159 = OpLabel
                OpReturn
                OpFunctionEnd
-%tint_div_u32 = OpFunction %uint None %243
+%tint_div_u32 = OpFunction %uint None %254
         %lhs = OpFunctionParameter %uint
         %rhs = OpFunctionParameter %uint
-        %244 = OpLabel
-        %245 = OpIEqual %bool %rhs %uint_0
-        %246 = OpSelect %uint %245 %uint_1 %rhs
-        %247 = OpUDiv %uint %lhs %246
-               OpReturnValue %247
+        %255 = OpLabel
+        %256 = OpIEqual %bool %rhs %uint_0
+        %257 = OpSelect %uint %256 %uint_1 %rhs
+        %258 = OpUDiv %uint %lhs %257
+               OpReturnValue %258
                OpFunctionEnd
-       %main = OpFunction %void None %249
-        %250 = OpLabel
-        %251 = OpLoad %v3uint %main_workgroup_id_Input None
-        %252 = OpLoad %v3uint %main_local_invocation_id_Input None
-        %253 = OpLoad %uint %main_local_invocation_index_Input None
-        %254 = OpFunctionCall %void %main_inner %251 %252 %253
+       %main = OpFunction %void None %260
+        %261 = OpLabel
+        %262 = OpLoad %v3uint %main_workgroup_id_Input None
+        %263 = OpLoad %v3uint %main_local_invocation_id_Input None
+        %264 = OpLoad %uint %main_local_invocation_index_Input None
+        %265 = OpFunctionCall %void %main_inner %262 %263 %264
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/948.wgsl.expected.glsl b/test/tint/bug/tint/948.wgsl.expected.glsl
index b6c9dd3..c44767d 100644
--- a/test/tint/bug/tint/948.wgsl.expected.glsl
+++ b/test/tint/bug/tint/948.wgsl.expected.glsl
@@ -168,17 +168,17 @@
       param = (x_222 + 0.5f);
       mat4 x_225 = getFrameData_f1_(param);
       frameData = x_225;
-      vec4 x_228 = frameData[0];
+      vec4 x_228 = frameData[0u];
       vec2 x_231 = v.inner.spriteMapSize;
       frameSize = (vec2(x_228[3u], x_228[2u]) / x_231);
-      vec4 x_235 = frameData[0];
+      vec4 x_235 = frameData[0u];
       vec2 x_237 = sheetUnits;
       offset_1 = (vec2(x_235[0u], x_235[1u]) * x_237);
-      vec4 x_241 = frameData[2];
-      vec4 x_244 = frameData[0];
+      vec4 x_241 = frameData[2u];
+      vec4 x_244 = frameData[0u];
       vec2 v_3 = vec2(x_241[0u], x_241[1u]);
       ratio = (v_3 / vec2(x_244[3u], x_244[2u]));
-      float x_248 = frameData[2].z;
+      float x_248 = frameData[2u].z;
       if ((x_248 == 1.0f)) {
         vec2 x_252 = tileUV;
         tileUV = vec2(x_252[1u], x_252[0u]);
diff --git a/test/tint/bug/tint/948.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.ir.dxc.hlsl
index a053f0b..c8230dc 100644
--- a/test/tint/bug/tint/948.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.ir.dxc.hlsl
@@ -157,17 +157,17 @@
       param = (x_222 + 0.5f);
       float4x4 x_225 = getFrameData_f1_(param);
       frameData = x_225;
-      float4 x_228 = frameData[int(0)];
+      float4 x_228 = frameData[0u];
       float2 x_231 = asfloat(x_20[6u].xy);
       frameSize = (float2(x_228.w, x_228.z) / x_231);
-      float4 x_235 = frameData[int(0)];
+      float4 x_235 = frameData[0u];
       float2 x_237 = sheetUnits;
       offset_1 = (float2(x_235.x, x_235.y) * x_237);
-      float4 x_241 = frameData[int(2)];
-      float4 x_244 = frameData[int(0)];
+      float4 x_241 = frameData[2u];
+      float4 x_244 = frameData[0u];
       float2 v_3 = float2(x_241.x, x_241.y);
       ratio = (v_3 / float2(x_244.w, x_244.z));
-      float x_248 = frameData[int(2)].z;
+      float x_248 = frameData[2u].z;
       if ((x_248 == 1.0f)) {
         float2 x_252 = tileUV;
         tileUV = float2(x_252.y, x_252.x);
diff --git a/test/tint/bug/tint/948.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/948.wgsl.expected.ir.fxc.hlsl
index a053f0b..c8230dc 100644
--- a/test/tint/bug/tint/948.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/948.wgsl.expected.ir.fxc.hlsl
@@ -157,17 +157,17 @@
       param = (x_222 + 0.5f);
       float4x4 x_225 = getFrameData_f1_(param);
       frameData = x_225;
-      float4 x_228 = frameData[int(0)];
+      float4 x_228 = frameData[0u];
       float2 x_231 = asfloat(x_20[6u].xy);
       frameSize = (float2(x_228.w, x_228.z) / x_231);
-      float4 x_235 = frameData[int(0)];
+      float4 x_235 = frameData[0u];
       float2 x_237 = sheetUnits;
       offset_1 = (float2(x_235.x, x_235.y) * x_237);
-      float4 x_241 = frameData[int(2)];
-      float4 x_244 = frameData[int(0)];
+      float4 x_241 = frameData[2u];
+      float4 x_244 = frameData[0u];
       float2 v_3 = float2(x_241.x, x_241.y);
       ratio = (v_3 / float2(x_244.w, x_244.z));
-      float x_248 = frameData[int(2)].z;
+      float x_248 = frameData[2u].z;
       if ((x_248 == 1.0f)) {
         float2 x_252 = tileUV;
         tileUV = float2(x_252.y, x_252.x);
diff --git a/test/tint/bug/tint/948.wgsl.expected.ir.msl b/test/tint/bug/tint/948.wgsl.expected.ir.msl
index 0c8c8da..83a8e5c 100644
--- a/test/tint/bug/tint/948.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/948.wgsl.expected.ir.msl
@@ -48,6 +48,9 @@
   thread float2* vUV;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct main_out {
   float4 glFragColor_1;
 };
@@ -119,6 +122,7 @@
   i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       int const x_122 = i;
       if ((x_122 < 2)) {
       } else {
@@ -160,6 +164,7 @@
         f = 0.0f;
         {
           while(true) {
+            TINT_ISOLATE_UB(tint_volatile_false_1)
             float const x_193 = f;
             if ((x_193 < 8.0f)) {
             } else {
@@ -189,17 +194,17 @@
       param = (x_222 + 0.5f);
       float4x4 const x_225 = getFrameData_f1_((&param), tint_module_vars);
       frameData = x_225;
-      float4 const x_228 = frameData[0];
+      float4 const x_228 = frameData[0u];
       float2 const x_231 = (*tint_module_vars.x_20).spriteMapSize;
       frameSize = (float2(x_228[3u], x_228[2u]) / x_231);
-      float4 const x_235 = frameData[0];
+      float4 const x_235 = frameData[0u];
       float2 const x_237 = sheetUnits;
       offset_1 = (float2(x_235[0u], x_235[1u]) * x_237);
-      float4 const x_241 = frameData[2];
-      float4 const x_244 = frameData[0];
+      float4 const x_241 = frameData[2u];
+      float4 const x_244 = frameData[0u];
       float2 const v_6 = float2(x_241[0u], x_241[1u]);
       ratio = (v_6 / float2(x_244[3u], x_244[2u]));
-      float const x_248 = frameData[2][2u];
+      float const x_248 = frameData[2u][2u];
       if ((x_248 == 1.0f)) {
         float2 const x_252 = tileUV;
         tileUV = float2(x_252[1u], x_252[0u]);
diff --git a/test/tint/bug/tint/948.wgsl.expected.msl b/test/tint/bug/tint/948.wgsl.expected.msl
index 86e2ef0..ea9a7a3 100644
--- a/test/tint/bug/tint/948.wgsl.expected.msl
+++ b/test/tint/bug/tint/948.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   float2 tUV;
   float mt;
@@ -99,6 +102,7 @@
   stageUnits = (float2(1.0f) / x_111);
   i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     int const x_122 = i;
     if ((x_122 < 2)) {
     } else {
@@ -135,6 +139,7 @@
       (*(tint_private_vars)).mt = fmod((x_181 * x_184), 1.0f);
       f = 0.0f;
       while(true) {
+        TINT_ISOLATE_UB(tint_volatile_false_1);
         float const x_193 = f;
         if ((x_193 < 8.0f)) {
         } else {
diff --git a/test/tint/bug/tint/948.wgsl.expected.spvasm b/test/tint/bug/tint/948.wgsl.expected.spvasm
index b4ff42a..790ea15 100644
--- a/test/tint/bug/tint/948.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/948.wgsl.expected.spvasm
@@ -483,7 +483,7 @@
                OpStore %param %246 None
       %x_225 = OpFunctionCall %mat4v4float %getFrameData_f1_ %param
                OpStore %frameData %x_225 None
-        %248 = OpAccessChain %_ptr_Function_v4float %frameData %int_0
+        %248 = OpAccessChain %_ptr_Function_v4float %frameData %uint_0
       %x_228 = OpLoad %v4float %248 None
         %250 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0 %uint_5
       %x_231 = OpLoad %v2float %250 None
@@ -492,7 +492,7 @@
         %254 = OpCompositeConstruct %v2float %252 %253
         %255 = OpFDiv %v2float %254 %x_231
                OpStore %frameSize %255 None
-        %256 = OpAccessChain %_ptr_Function_v4float %frameData %int_0
+        %256 = OpAccessChain %_ptr_Function_v4float %frameData %uint_0
       %x_235 = OpLoad %v4float %256 None
       %x_237 = OpLoad %v2float %sheetUnits None
         %259 = OpCompositeExtract %float %x_235 0
@@ -500,9 +500,9 @@
         %261 = OpCompositeConstruct %v2float %259 %260
         %262 = OpFMul %v2float %261 %x_237
                OpStore %offset_1 %262 None
-        %263 = OpAccessChain %_ptr_Function_v4float %frameData %int_2
+        %263 = OpAccessChain %_ptr_Function_v4float %frameData %uint_2
       %x_241 = OpLoad %v4float %263 None
-        %265 = OpAccessChain %_ptr_Function_v4float %frameData %int_0
+        %265 = OpAccessChain %_ptr_Function_v4float %frameData %uint_0
       %x_244 = OpLoad %v4float %265 None
         %267 = OpCompositeExtract %float %x_241 0
         %268 = OpCompositeExtract %float %x_241 1
@@ -512,7 +512,7 @@
         %272 = OpCompositeConstruct %v2float %270 %271
         %273 = OpFDiv %v2float %269 %272
                OpStore %ratio %273 None
-        %274 = OpAccessChain %_ptr_Function_v4float %frameData %int_2
+        %274 = OpAccessChain %_ptr_Function_v4float %frameData %uint_2
         %275 = OpAccessChain %_ptr_Function_float %274 %uint_2
       %x_248 = OpLoad %float %275 None
         %277 = OpFOrdEqual %bool %x_248 %float_1
diff --git a/test/tint/bug/tint/949.wgsl.expected.glsl b/test/tint/bug/tint/949.wgsl.expected.glsl
index 38ede54..625c368 100644
--- a/test/tint/bug/tint/949.wgsl.expected.glsl
+++ b/test/tint/bug/tint/949.wgsl.expected.glsl
@@ -122,11 +122,11 @@
   vec3 i1 = vec3(0.0f);
   vec3 i2 = vec3(0.0f);
   mat3 outMatrix = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
-  vec3 x_60 = inMatrix[0];
+  vec3 x_60 = inMatrix[0u];
   i0 = x_60;
-  vec3 x_64 = inMatrix[1];
+  vec3 x_64 = inMatrix[1u];
   i1 = x_64;
-  vec3 x_68 = inMatrix[2];
+  vec3 x_68 = inMatrix[2u];
   i2 = x_68;
   float x_73 = i0.x;
   float x_75 = i1.x;
diff --git a/test/tint/bug/tint/949.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/949.wgsl.expected.ir.dxc.hlsl
index 250e00b..b03e9f5 100644
--- a/test/tint/bug/tint/949.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/949.wgsl.expected.ir.dxc.hlsl
@@ -102,11 +102,11 @@
   float3 i1 = (0.0f).xxx;
   float3 i2 = (0.0f).xxx;
   float3x3 outMatrix = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float3 x_60 = inMatrix[int(0)];
+  float3 x_60 = inMatrix[0u];
   i0 = x_60;
-  float3 x_64 = inMatrix[int(1)];
+  float3 x_64 = inMatrix[1u];
   i1 = x_64;
-  float3 x_68 = inMatrix[int(2)];
+  float3 x_68 = inMatrix[2u];
   i2 = x_68;
   float x_73 = i0.x;
   float x_75 = i1.x;
diff --git a/test/tint/bug/tint/949.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/949.wgsl.expected.ir.fxc.hlsl
index 250e00b..b03e9f5 100644
--- a/test/tint/bug/tint/949.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/949.wgsl.expected.ir.fxc.hlsl
@@ -102,11 +102,11 @@
   float3 i1 = (0.0f).xxx;
   float3 i2 = (0.0f).xxx;
   float3x3 outMatrix = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
-  float3 x_60 = inMatrix[int(0)];
+  float3 x_60 = inMatrix[0u];
   i0 = x_60;
-  float3 x_64 = inMatrix[int(1)];
+  float3 x_64 = inMatrix[1u];
   i1 = x_64;
-  float3 x_68 = inMatrix[int(2)];
+  float3 x_68 = inMatrix[2u];
   i2 = x_68;
   float x_73 = i0.x;
   float x_75 = i1.x;
diff --git a/test/tint/bug/tint/949.wgsl.expected.ir.msl b/test/tint/bug/tint/949.wgsl.expected.ir.msl
index d3dd1a1..4ba6055 100644
--- a/test/tint/bug/tint/949.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/949.wgsl.expected.ir.msl
@@ -61,6 +61,9 @@
   texture2d<float, access::sample> bumpSamplerTexture;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct main_out {
   float4 glFragColor_1;
 };
@@ -138,11 +141,11 @@
   float3 i1 = 0.0f;
   float3 i2 = 0.0f;
   float3x3 outMatrix = float3x3(0.0f);
-  float3 const x_60 = (*inMatrix)[0];
+  float3 const x_60 = (*inMatrix)[0u];
   i0 = x_60;
-  float3 const x_64 = (*inMatrix)[1];
+  float3 const x_64 = (*inMatrix)[1u];
   i1 = x_64;
-  float3 const x_68 = (*inMatrix)[2];
+  float3 const x_68 = (*inMatrix)[2u];
   i2 = x_68;
   float const x_73 = i0[0u];
   float const x_75 = i1[0u];
@@ -336,6 +339,7 @@
   i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       int const x_388 = i;
       if ((x_388 < 15)) {
       } else {
diff --git a/test/tint/bug/tint/949.wgsl.expected.msl b/test/tint/bug/tint/949.wgsl.expected.msl
index afac36f..b3a792d 100644
--- a/test/tint/bug/tint/949.wgsl.expected.msl
+++ b/test/tint/bug/tint/949.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   float u_Float;
   float3 u_Color;
@@ -331,6 +334,7 @@
   currSampledHeight = 1.0f;
   i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     int const x_388 = i;
     if ((x_388 < 15)) {
     } else {
diff --git a/test/tint/bug/tint/949.wgsl.expected.spvasm b/test/tint/bug/tint/949.wgsl.expected.spvasm
index 71af069..d837ce4 100644
--- a/test/tint/bug/tint/949.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/949.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 624
+; Bound: 623
 ; Schema: 0
                OpCapability Shader
          %85 = OpExtInstImport "GLSL.std.450"
@@ -441,29 +441,26 @@
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
         %148 = OpTypeFunction %mat3v3float %_ptr_Function_mat3v3float
         %154 = OpConstantNull %mat3v3float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
-      %int_2 = OpConstant %int 2
      %uint_2 = OpConstant %uint 2
-        %205 = OpTypeFunction %v3float %_ptr_Function_mat3v3float %_ptr_Function_v3float %_ptr_Function_float
+        %201 = OpTypeFunction %v3float %_ptr_Function_mat3v3float %_ptr_Function_v3float %_ptr_Function_float
     %float_2 = OpConstant %float 2
     %float_1 = OpConstant %float 1
-        %224 = OpConstantComposite %v3float %float_1 %float_1 %float_1
+        %220 = OpConstantComposite %v3float %float_1 %float_1 %float_1
 %lightingInfo = OpTypeStruct %v3float %v3float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-        %238 = OpTypeFunction %lightingInfo %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_v4float %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_float
+        %234 = OpTypeFunction %lightingInfo %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_v4float %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_v3float %_ptr_Function_float
 %_ptr_Function_lightingInfo = OpTypePointer Function %lightingInfo
-        %243 = OpConstantNull %lightingInfo
+        %239 = OpConstantNull %lightingInfo
   %float_0_5 = OpConstant %float 0.5
     %float_0 = OpConstant %float 0
        %void = OpTypeVoid
-        %286 = OpTypeFunction %void
+        %282 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
-        %315 = OpConstantNull %int
+        %312 = OpConstantNull %int
   %float_100 = OpConstant %float 100
-        %344 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
-        %349 = OpTypeSampledImage %11
+        %341 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
+        %346 = OpTypeSampledImage %11
 %_ptr_Uniform_float = OpTypePointer Uniform %float
      %uint_6 = OpConstant %uint 6
 %_ptr_Uniform_v3float = OpTypePointer Uniform %v3float
@@ -473,11 +470,13 @@
      %uint_5 = OpConstant %uint 5
   %float_n11 = OpConstant %float -11
    %float_15 = OpConstant %float 15
+      %int_0 = OpConstant %int 0
      %int_15 = OpConstant %int 15
+      %int_1 = OpConstant %int 1
 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
      %uint_3 = OpConstant %uint 3
    %main_out = OpTypeStruct %v4float
-        %610 = OpTypeFunction %main_out %v2float %v4float %bool %v2float %v4float
+        %609 = OpTypeFunction %main_out %v2float %v4float %bool %v2float %v4float
 %cotangent_frame_vf3_vf3_vf2_vf2_ = OpFunction %mat3v3float None %62
 %normal_1_root = OpFunctionParameter %_ptr_Function_v3float
      %p_root = OpFunctionParameter %_ptr_Function_v3float
@@ -581,84 +580,84 @@
          %i1 = OpVariable %_ptr_Function_v3float Function %8
          %i2 = OpVariable %_ptr_Function_v3float Function %8
   %outMatrix = OpVariable %_ptr_Function_mat3v3float Function %154
-        %155 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %int_0
+        %155 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %uint_0
        %x_60 = OpLoad %v3float %155 None
                OpStore %i0 %x_60 None
-        %159 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %int_1
-       %x_64 = OpLoad %v3float %159 None
+        %157 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %uint_1
+       %x_64 = OpLoad %v3float %157 None
                OpStore %i1 %x_64 None
-        %162 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %int_2
-       %x_68 = OpLoad %v3float %162 None
+        %159 = OpAccessChain %_ptr_Function_v3float %inMatrix_root %uint_2
+       %x_68 = OpLoad %v3float %159 None
                OpStore %i2 %x_68 None
-        %165 = OpAccessChain %_ptr_Function_float %i0 %uint_0
-       %x_73 = OpLoad %float %165 None
-        %167 = OpAccessChain %_ptr_Function_float %i1 %uint_0
-       %x_75 = OpLoad %float %167 None
-        %169 = OpAccessChain %_ptr_Function_float %i2 %uint_0
-       %x_77 = OpLoad %float %169 None
+        %162 = OpAccessChain %_ptr_Function_float %i0 %uint_0
+       %x_73 = OpLoad %float %162 None
+        %164 = OpAccessChain %_ptr_Function_float %i1 %uint_0
+       %x_75 = OpLoad %float %164 None
+        %166 = OpAccessChain %_ptr_Function_float %i2 %uint_0
+       %x_77 = OpLoad %float %166 None
        %x_78 = OpCompositeConstruct %v3float %x_73 %x_75 %x_77
-        %172 = OpAccessChain %_ptr_Function_float %i0 %uint_1
-       %x_81 = OpLoad %float %172 None
-        %174 = OpAccessChain %_ptr_Function_float %i1 %uint_1
-       %x_83 = OpLoad %float %174 None
-        %176 = OpAccessChain %_ptr_Function_float %i2 %uint_1
-       %x_85 = OpLoad %float %176 None
+        %169 = OpAccessChain %_ptr_Function_float %i0 %uint_1
+       %x_81 = OpLoad %float %169 None
+        %171 = OpAccessChain %_ptr_Function_float %i1 %uint_1
+       %x_83 = OpLoad %float %171 None
+        %173 = OpAccessChain %_ptr_Function_float %i2 %uint_1
+       %x_85 = OpLoad %float %173 None
        %x_86 = OpCompositeConstruct %v3float %x_81 %x_83 %x_85
-        %179 = OpAccessChain %_ptr_Function_float %i0 %uint_2
-       %x_89 = OpLoad %float %179 None
-        %182 = OpAccessChain %_ptr_Function_float %i1 %uint_2
-       %x_91 = OpLoad %float %182 None
-        %184 = OpAccessChain %_ptr_Function_float %i2 %uint_2
-       %x_93 = OpLoad %float %184 None
+        %176 = OpAccessChain %_ptr_Function_float %i0 %uint_2
+       %x_89 = OpLoad %float %176 None
+        %178 = OpAccessChain %_ptr_Function_float %i1 %uint_2
+       %x_91 = OpLoad %float %178 None
+        %180 = OpAccessChain %_ptr_Function_float %i2 %uint_2
+       %x_93 = OpLoad %float %180 None
        %x_94 = OpCompositeConstruct %v3float %x_89 %x_91 %x_93
-        %187 = OpCompositeExtract %float %x_78 0
-        %188 = OpCompositeExtract %float %x_78 1
-        %189 = OpCompositeExtract %float %x_78 2
+        %183 = OpCompositeExtract %float %x_78 0
+        %184 = OpCompositeExtract %float %x_78 1
+        %185 = OpCompositeExtract %float %x_78 2
+        %186 = OpCompositeConstruct %v3float %183 %184 %185
+        %187 = OpCompositeExtract %float %x_86 0
+        %188 = OpCompositeExtract %float %x_86 1
+        %189 = OpCompositeExtract %float %x_86 2
         %190 = OpCompositeConstruct %v3float %187 %188 %189
-        %191 = OpCompositeExtract %float %x_86 0
-        %192 = OpCompositeExtract %float %x_86 1
-        %193 = OpCompositeExtract %float %x_86 2
+        %191 = OpCompositeExtract %float %x_94 0
+        %192 = OpCompositeExtract %float %x_94 1
+        %193 = OpCompositeExtract %float %x_94 2
         %194 = OpCompositeConstruct %v3float %191 %192 %193
-        %195 = OpCompositeExtract %float %x_94 0
-        %196 = OpCompositeExtract %float %x_94 1
-        %197 = OpCompositeExtract %float %x_94 2
-        %198 = OpCompositeConstruct %v3float %195 %196 %197
-        %199 = OpCompositeConstruct %mat3v3float %190 %194 %198
-               OpStore %outMatrix %199 None
+        %195 = OpCompositeConstruct %mat3v3float %186 %190 %194
+               OpStore %outMatrix %195 None
       %x_110 = OpLoad %mat3v3float %outMatrix None
                OpReturnValue %x_110
                OpFunctionEnd
-%perturbNormalBase_mf33_vf3_f1_ = OpFunction %v3float None %205
+%perturbNormalBase_mf33_vf3_f1_ = OpFunction %v3float None %201
 %cotangentFrame_root = OpFunctionParameter %_ptr_Function_mat3v3float
 %normal_root = OpFunctionParameter %_ptr_Function_v3float
  %scale_root = OpFunctionParameter %_ptr_Function_float
-        %206 = OpLabel
+        %202 = OpLabel
       %x_113 = OpLoad %mat3v3float %cotangentFrame_root None
       %x_114 = OpLoad %v3float %normal_root None
-        %209 = OpMatrixTimesVector %v3float %x_113 %x_114
-        %210 = OpExtInst %v3float %85 Normalize %209
-               OpReturnValue %210
+        %205 = OpMatrixTimesVector %v3float %x_113 %x_114
+        %206 = OpExtInst %v3float %85 Normalize %205
+               OpReturnValue %206
                OpFunctionEnd
-%perturbNormal_mf33_vf3_f1_ = OpFunction %v3float None %205
+%perturbNormal_mf33_vf3_f1_ = OpFunction %v3float None %201
 %cotangentFrame_1_root = OpFunctionParameter %_ptr_Function_mat3v3float
 %textureSample_root = OpFunctionParameter %_ptr_Function_v3float
 %scale_1_root = OpFunctionParameter %_ptr_Function_float
-        %215 = OpLabel
+        %211 = OpLabel
       %param = OpVariable %_ptr_Function_mat3v3float Function %154
     %param_1 = OpVariable %_ptr_Function_v3float Function %8
     %param_2 = OpVariable %_ptr_Function_float Function %4
       %x_119 = OpLoad %v3float %textureSample_root None
       %x_125 = OpLoad %mat3v3float %cotangentFrame_1_root None
                OpStore %param %x_125 None
-        %221 = OpVectorTimesScalar %v3float %x_119 %float_2
-        %223 = OpFSub %v3float %221 %224
-               OpStore %param_1 %223 None
+        %217 = OpVectorTimesScalar %v3float %x_119 %float_2
+        %219 = OpFSub %v3float %217 %220
+               OpStore %param_1 %219 None
       %x_128 = OpLoad %float %scale_1_root None
                OpStore %param_2 %x_128 None
       %x_129 = OpFunctionCall %v3float %perturbNormalBase_mf33_vf3_f1_ %param %param_1 %param_2
                OpReturnValue %x_129
                OpFunctionEnd
-%computeHemisphericLighting_vf3_vf3_vf4_vf3_vf3_vf3_f1_ = OpFunction %lightingInfo None %238
+%computeHemisphericLighting_vf3_vf3_vf4_vf3_vf3_vf3_f1_ = OpFunction %lightingInfo None %234
 %viewDirectionW_root = OpFunctionParameter %_ptr_Function_v3float
 %vNormal_root = OpFunctionParameter %_ptr_Function_v3float
 %lightData_root = OpFunctionParameter %_ptr_Function_v4float
@@ -666,57 +665,57 @@
 %specularColor_root = OpFunctionParameter %_ptr_Function_v3float
 %groundColor_root = OpFunctionParameter %_ptr_Function_v3float
 %glossiness_root = OpFunctionParameter %_ptr_Function_float
-        %239 = OpLabel
+        %235 = OpLabel
         %ndl = OpVariable %_ptr_Function_float Function %4
-     %result = OpVariable %_ptr_Function_lightingInfo Function %243
+     %result = OpVariable %_ptr_Function_lightingInfo Function %239
      %angleW = OpVariable %_ptr_Function_v3float Function %8
    %specComp = OpVariable %_ptr_Function_float Function %4
       %x_212 = OpLoad %v3float %vNormal_root None
       %x_213 = OpLoad %v4float %lightData_root None
-        %248 = OpCompositeExtract %float %x_213 0
-        %249 = OpCompositeExtract %float %x_213 1
-        %250 = OpCompositeExtract %float %x_213 2
-        %251 = OpCompositeConstruct %v3float %248 %249 %250
-        %252 = OpDot %float %x_212 %251
-        %253 = OpFMul %float %252 %float_0_5
-        %255 = OpFAdd %float %253 %float_0_5
-               OpStore %ndl %255 None
+        %244 = OpCompositeExtract %float %x_213 0
+        %245 = OpCompositeExtract %float %x_213 1
+        %246 = OpCompositeExtract %float %x_213 2
+        %247 = OpCompositeConstruct %v3float %244 %245 %246
+        %248 = OpDot %float %x_212 %247
+        %249 = OpFMul %float %248 %float_0_5
+        %251 = OpFAdd %float %249 %float_0_5
+               OpStore %ndl %251 None
       %x_220 = OpLoad %v3float %groundColor_root None
       %x_221 = OpLoad %v3float %diffuseColor_root None
       %x_222 = OpLoad %float %ndl None
-        %259 = OpAccessChain %_ptr_Function_v3float %result %uint_0
-        %260 = OpCompositeConstruct %v3float %x_222 %x_222 %x_222
-        %261 = OpExtInst %v3float %85 FMix %x_220 %x_221 %260
-               OpStore %259 %261 None
+        %255 = OpAccessChain %_ptr_Function_v3float %result %uint_0
+        %256 = OpCompositeConstruct %v3float %x_222 %x_222 %x_222
+        %257 = OpExtInst %v3float %85 FMix %x_220 %x_221 %256
+               OpStore %255 %257 None
       %x_227 = OpLoad %v3float %viewDirectionW_root None
       %x_228 = OpLoad %v4float %lightData_root None
-        %264 = OpCompositeExtract %float %x_228 0
-        %265 = OpCompositeExtract %float %x_228 1
-        %266 = OpCompositeExtract %float %x_228 2
-        %267 = OpCompositeConstruct %v3float %264 %265 %266
-        %268 = OpFAdd %v3float %x_227 %267
-        %269 = OpExtInst %v3float %85 Normalize %268
-               OpStore %angleW %269 None
+        %260 = OpCompositeExtract %float %x_228 0
+        %261 = OpCompositeExtract %float %x_228 1
+        %262 = OpCompositeExtract %float %x_228 2
+        %263 = OpCompositeConstruct %v3float %260 %261 %262
+        %264 = OpFAdd %v3float %x_227 %263
+        %265 = OpExtInst %v3float %85 Normalize %264
+               OpStore %angleW %265 None
       %x_233 = OpLoad %v3float %vNormal_root None
       %x_234 = OpLoad %v3float %angleW None
-        %272 = OpDot %float %x_233 %x_234
-        %273 = OpExtInst %float %85 FMax %float_0 %272
-               OpStore %specComp %273 None
+        %268 = OpDot %float %x_233 %x_234
+        %269 = OpExtInst %float %85 FMax %float_0 %268
+               OpStore %specComp %269 None
       %x_237 = OpLoad %float %specComp None
       %x_238 = OpLoad %float %glossiness_root None
-        %277 = OpExtInst %float %85 FMax %float_1 %x_238
-        %278 = OpExtInst %float %85 Pow %x_237 %277
-               OpStore %specComp %278 None
+        %273 = OpExtInst %float %85 FMax %float_1 %x_238
+        %274 = OpExtInst %float %85 Pow %x_237 %273
+               OpStore %specComp %274 None
       %x_241 = OpLoad %float %specComp None
       %x_242 = OpLoad %v3float %specularColor_root None
-        %281 = OpAccessChain %_ptr_Function_v3float %result %uint_1
-        %282 = OpVectorTimesScalar %v3float %x_242 %x_241
-               OpStore %281 %282 None
+        %277 = OpAccessChain %_ptr_Function_v3float %result %uint_1
+        %278 = OpVectorTimesScalar %v3float %x_242 %x_241
+               OpStore %277 %278 None
       %x_245 = OpLoad %lightingInfo %result None
                OpReturnValue %x_245
                OpFunctionEnd
-     %main_1 = OpFunction %void None %286
-        %287 = OpLabel
+     %main_1 = OpFunction %void None %282
+        %283 = OpLabel
 %tempTextureRead = OpVariable %_ptr_Function_v4float Function %x_397
         %rgb = OpVariable %_ptr_Function_v3float Function %8
     %output5 = OpVariable %_ptr_Function_v3float Function %8
@@ -742,7 +741,7 @@
 %vLastOffset = OpVariable %_ptr_Function_v2float Function %18
 %lastSampledHeight = OpVariable %_ptr_Function_float Function %4
 %currSampledHeight = OpVariable %_ptr_Function_float Function %4
-          %i = OpVariable %_ptr_Function_int Function %315
+          %i = OpVariable %_ptr_Function_int Function %312
      %delta1 = OpVariable %_ptr_Function_float Function %4
      %delta2 = OpVariable %_ptr_Function_float Function %4
       %ratio = OpVariable %_ptr_Function_float Function %4
@@ -759,7 +758,7 @@
 %diffuseBase = OpVariable %_ptr_Function_v3float Function %8
 %specularBase = OpVariable %_ptr_Function_v3float Function %8
     %normalW = OpVariable %_ptr_Function_v3float Function %8
-       %info = OpVariable %_ptr_Function_lightingInfo Function %243
+       %info = OpVariable %_ptr_Function_lightingInfo Function %239
    %param_11 = OpVariable %_ptr_Function_v3float Function %8
    %param_12 = OpVariable %_ptr_Function_v3float Function %8
    %param_13 = OpVariable %_ptr_Function_v4float Function %x_397
@@ -771,71 +770,71 @@
 %specularOutput = OpVariable %_ptr_Function_v3float Function %8
     %output3 = OpVariable %_ptr_Function_v3float Function %8
                OpStore %u_Float %float_100 None
-               OpStore %u_Color %344 None
+               OpStore %u_Color %341 None
       %x_261 = OpLoad %v2float %vMainuv None
-        %346 = OpLoad %11 %TextureSamplerTexture None
-        %347 = OpLoad %14 %TextureSamplerSampler None
-        %348 = OpSampledImage %349 %346 %347
-      %x_262 = OpImageSampleImplicitLod %v4float %348 %x_261 None
+        %343 = OpLoad %11 %TextureSamplerTexture None
+        %344 = OpLoad %14 %TextureSamplerSampler None
+        %345 = OpSampledImage %346 %343 %344
+      %x_262 = OpImageSampleImplicitLod %v4float %345 %x_261 None
                OpStore %tempTextureRead %x_262 None
       %x_264 = OpLoad %v4float %tempTextureRead None
-        %352 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_6
-      %x_273 = OpLoad %float %352 None
-        %356 = OpCompositeExtract %float %x_264 0
-        %357 = OpCompositeExtract %float %x_264 1
-        %358 = OpCompositeExtract %float %x_264 2
-        %359 = OpCompositeConstruct %v3float %356 %357 %358
-        %360 = OpVectorTimesScalar %v3float %359 %x_273
-               OpStore %rgb %360 None
-        %361 = OpAccessChain %_ptr_Uniform_v3float %19 %uint_0 %uint_4
-      %x_279 = OpLoad %v3float %361 None
+        %349 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_6
+      %x_273 = OpLoad %float %349 None
+        %353 = OpCompositeExtract %float %x_264 0
+        %354 = OpCompositeExtract %float %x_264 1
+        %355 = OpCompositeExtract %float %x_264 2
+        %356 = OpCompositeConstruct %v3float %353 %354 %355
+        %357 = OpVectorTimesScalar %v3float %356 %x_273
+               OpStore %rgb %357 None
+        %358 = OpAccessChain %_ptr_Uniform_v3float %19 %uint_0 %uint_4
+      %x_279 = OpLoad %v3float %358 None
       %x_282 = OpLoad %v4float %v_output1 None
-        %366 = OpCompositeExtract %float %x_282 0
-        %367 = OpCompositeExtract %float %x_282 1
-        %368 = OpCompositeExtract %float %x_282 2
-        %369 = OpCompositeConstruct %v3float %366 %367 %368
-        %370 = OpFSub %v3float %x_279 %369
-        %371 = OpExtInst %v3float %85 Normalize %370
-               OpStore %output5 %371 None
+        %363 = OpCompositeExtract %float %x_282 0
+        %364 = OpCompositeExtract %float %x_282 1
+        %365 = OpCompositeExtract %float %x_282 2
+        %366 = OpCompositeConstruct %v3float %363 %364 %365
+        %367 = OpFSub %v3float %x_279 %366
+        %368 = OpExtInst %v3float %85 Normalize %367
+               OpStore %output5 %368 None
                OpStore %output4 %x_397 None
                OpStore %uvOffset %18 None
-        %372 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_2
-      %x_292 = OpLoad %float %372 None
-        %374 = OpFDiv %float %float_1 %x_292
-               OpStore %normalScale %374 None
+        %369 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_2
+      %x_292 = OpLoad %float %369 None
+        %371 = OpFDiv %float %float_1 %x_292
+               OpStore %normalScale %371 None
       %x_298 = OpLoad %bool %gl_FrontFacing None
-               OpSelectionMerge %376 None
-               OpBranchConditional %x_298 %377 %378
-        %377 = OpLabel
+               OpSelectionMerge %373 None
+               OpBranchConditional %x_298 %374 %375
+        %374 = OpLabel
       %x_303 = OpLoad %v2float %v_uv None
                OpStore %x_299 %x_303 None
-               OpBranch %376
-        %378 = OpLabel
+               OpBranch %373
+        %375 = OpLabel
       %x_305 = OpLoad %v2float %v_uv None
-        %381 = OpFNegate %v2float %x_305
-               OpStore %x_299 %381 None
-               OpBranch %376
-        %376 = OpLabel
+        %378 = OpFNegate %v2float %x_305
+               OpStore %x_299 %378 None
+               OpBranch %373
+        %373 = OpLabel
       %x_307 = OpLoad %v2float %x_299 None
                OpStore %TBNUV %x_307 None
       %x_310 = OpLoad %v4float %v_output2 None
       %x_312 = OpLoad %float %normalScale None
-        %385 = OpCompositeExtract %float %x_310 0
-        %386 = OpCompositeExtract %float %x_310 1
-        %387 = OpCompositeExtract %float %x_310 2
-        %388 = OpCompositeConstruct %v3float %385 %386 %387
-        %389 = OpVectorTimesScalar %v3float %388 %x_312
-               OpStore %param_3 %389 None
+        %382 = OpCompositeExtract %float %x_310 0
+        %383 = OpCompositeExtract %float %x_310 1
+        %384 = OpCompositeExtract %float %x_310 2
+        %385 = OpCompositeConstruct %v3float %382 %383 %384
+        %386 = OpVectorTimesScalar %v3float %385 %x_312
+               OpStore %param_3 %386 None
       %x_317 = OpLoad %v4float %v_output1 None
-        %391 = OpCompositeExtract %float %x_317 0
-        %392 = OpCompositeExtract %float %x_317 1
-        %393 = OpCompositeExtract %float %x_317 2
-        %394 = OpCompositeConstruct %v3float %391 %392 %393
-               OpStore %param_4 %394 None
+        %388 = OpCompositeExtract %float %x_317 0
+        %389 = OpCompositeExtract %float %x_317 1
+        %390 = OpCompositeExtract %float %x_317 2
+        %391 = OpCompositeConstruct %v3float %388 %389 %390
+               OpStore %param_4 %391 None
       %x_320 = OpLoad %v2float %TBNUV None
                OpStore %param_5 %x_320 None
-        %396 = OpAccessChain %_ptr_Uniform_v2float %19 %uint_0 %uint_8
-      %x_324 = OpLoad %v2float %396 None
+        %393 = OpAccessChain %_ptr_Uniform_v2float %19 %uint_0 %uint_8
+      %x_324 = OpLoad %v2float %393 None
                OpStore %param_6 %x_324 None
       %x_325 = OpFunctionCall %mat3v3float %cotangent_frame_vf3_vf3_vf2_vf2_ %param_3 %param_4 %param_5 %param_6
                OpStore %TBN %x_325 None
@@ -845,290 +844,290 @@
                OpStore %invTBN %x_329 None
       %x_331 = OpLoad %mat3v3float %invTBN None
       %x_332 = OpLoad %v3float %output5 None
-        %405 = OpFNegate %v3float %x_332
-      %x_334 = OpMatrixTimesVector %v3float %x_331 %405
+        %402 = OpFNegate %v3float %x_332
+      %x_334 = OpMatrixTimesVector %v3float %x_331 %402
       %x_337 = OpLoad %mat3v3float %invTBN None
       %x_338 = OpLoad %v3float %output5 None
-        %409 = OpCompositeExtract %float %x_334 0
-        %410 = OpCompositeExtract %float %x_334 1
-        %411 = OpCompositeConstruct %v2float %409 %410
-        %412 = OpExtInst %float %85 Length %411
-        %413 = OpFNegate %v3float %x_338
-        %414 = OpMatrixTimesVector %v3float %x_337 %413
-        %415 = OpCompositeExtract %float %414 2
-        %416 = OpFDiv %float %412 %415
-               OpStore %parallaxLimit %416 None
-        %417 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_5
-      %x_345 = OpLoad %float %417 None
+        %406 = OpCompositeExtract %float %x_334 0
+        %407 = OpCompositeExtract %float %x_334 1
+        %408 = OpCompositeConstruct %v2float %406 %407
+        %409 = OpExtInst %float %85 Length %408
+        %410 = OpFNegate %v3float %x_338
+        %411 = OpMatrixTimesVector %v3float %x_337 %410
+        %412 = OpCompositeExtract %float %411 2
+        %413 = OpFDiv %float %409 %412
+               OpStore %parallaxLimit %413 None
+        %414 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_5
+      %x_345 = OpLoad %float %414 None
       %x_346 = OpLoad %float %parallaxLimit None
-        %421 = OpFMul %float %x_346 %x_345
-               OpStore %parallaxLimit %421 None
+        %418 = OpFMul %float %x_346 %x_345
+               OpStore %parallaxLimit %418 None
       %x_349 = OpLoad %mat3v3float %invTBN None
       %x_350 = OpLoad %v3float %output5 None
-        %424 = OpFNegate %v3float %x_350
-      %x_352 = OpMatrixTimesVector %v3float %x_349 %424
-        %426 = OpCompositeExtract %float %x_352 0
-        %427 = OpCompositeExtract %float %x_352 1
-        %428 = OpCompositeConstruct %v2float %426 %427
-        %429 = OpExtInst %v2float %85 Normalize %428
-               OpStore %vOffsetDir %429 None
+        %421 = OpFNegate %v3float %x_350
+      %x_352 = OpMatrixTimesVector %v3float %x_349 %421
+        %423 = OpCompositeExtract %float %x_352 0
+        %424 = OpCompositeExtract %float %x_352 1
+        %425 = OpCompositeConstruct %v2float %423 %424
+        %426 = OpExtInst %v2float %85 Normalize %425
+               OpStore %vOffsetDir %426 None
       %x_356 = OpLoad %v2float %vOffsetDir None
       %x_357 = OpLoad %float %parallaxLimit None
-        %432 = OpVectorTimesScalar %v2float %x_356 %x_357
-               OpStore %vMaxOffset %432 None
+        %429 = OpVectorTimesScalar %v2float %x_356 %x_357
+               OpStore %vMaxOffset %429 None
       %x_361 = OpLoad %mat3v3float %invTBN None
       %x_362 = OpLoad %v3float %output5 None
       %x_365 = OpLoad %mat3v3float %invTBN None
       %x_366 = OpLoad %v4float %v_output2 None
-        %437 = OpFNegate %v3float %x_362
-        %438 = OpMatrixTimesVector %v3float %x_361 %437
-        %439 = OpCompositeExtract %float %x_366 0
-        %440 = OpCompositeExtract %float %x_366 1
-        %441 = OpCompositeExtract %float %x_366 2
-        %442 = OpCompositeConstruct %v3float %439 %440 %441
-        %443 = OpMatrixTimesVector %v3float %x_365 %442
-        %444 = OpDot %float %438 %443
-        %445 = OpFMul %float %444 %float_n11
-        %447 = OpFAdd %float %float_15 %445
-               OpStore %numSamples %447 None
+        %434 = OpFNegate %v3float %x_362
+        %435 = OpMatrixTimesVector %v3float %x_361 %434
+        %436 = OpCompositeExtract %float %x_366 0
+        %437 = OpCompositeExtract %float %x_366 1
+        %438 = OpCompositeExtract %float %x_366 2
+        %439 = OpCompositeConstruct %v3float %436 %437 %438
+        %440 = OpMatrixTimesVector %v3float %x_365 %439
+        %441 = OpDot %float %435 %440
+        %442 = OpFMul %float %441 %float_n11
+        %444 = OpFAdd %float %float_15 %442
+               OpStore %numSamples %444 None
       %x_374 = OpLoad %float %numSamples None
-        %450 = OpFDiv %float %float_1 %x_374
-               OpStore %stepSize %450 None
+        %447 = OpFDiv %float %float_1 %x_374
+               OpStore %stepSize %447 None
                OpStore %currRayHeight %float_1 None
                OpStore %vCurrOffset %18 None
                OpStore %vLastOffset %18 None
                OpStore %lastSampledHeight %float_1 None
                OpStore %currSampledHeight %float_1 None
                OpStore %i %int_0 None
-               OpBranch %453
-        %453 = OpLabel
-               OpLoopMerge %454 %452 None
                OpBranch %451
         %451 = OpLabel
+               OpLoopMerge %452 %450 None
+               OpBranch %449
+        %449 = OpLabel
       %x_388 = OpLoad %int %i None
-        %456 = OpSLessThan %bool %x_388 %int_15
-               OpSelectionMerge %458 None
-               OpBranchConditional %456 %458 %459
-        %459 = OpLabel
-               OpBranch %454
-        %458 = OpLabel
+        %454 = OpSLessThan %bool %x_388 %int_15
+               OpSelectionMerge %456 None
+               OpBranchConditional %454 %456 %457
+        %457 = OpLabel
+               OpBranch %452
+        %456 = OpLabel
       %x_394 = OpLoad %v2float %v_uv None
       %x_395 = OpLoad %v2float %vCurrOffset None
-        %462 = OpCompositeExtract %float %x_397 3
-               OpStore %currSampledHeight %462 None
+        %460 = OpCompositeExtract %float %x_397 3
+               OpStore %currSampledHeight %460 None
       %x_400 = OpLoad %float %currSampledHeight None
       %x_401 = OpLoad %float %currRayHeight None
-        %465 = OpFOrdGreaterThan %bool %x_400 %x_401
-               OpSelectionMerge %466 None
-               OpBranchConditional %465 %467 %468
-        %467 = OpLabel
+        %463 = OpFOrdGreaterThan %bool %x_400 %x_401
+               OpSelectionMerge %464 None
+               OpBranchConditional %463 %465 %466
+        %465 = OpLabel
       %x_406 = OpLoad %float %currSampledHeight None
       %x_407 = OpLoad %float %currRayHeight None
-        %471 = OpFSub %float %x_406 %x_407
-               OpStore %delta1 %471 None
+        %469 = OpFSub %float %x_406 %x_407
+               OpStore %delta1 %469 None
       %x_410 = OpLoad %float %currRayHeight None
       %x_411 = OpLoad %float %stepSize None
       %x_413 = OpLoad %float %lastSampledHeight None
-        %475 = OpFAdd %float %x_410 %x_411
-        %476 = OpFSub %float %475 %x_413
-               OpStore %delta2 %476 None
+        %473 = OpFAdd %float %x_410 %x_411
+        %474 = OpFSub %float %473 %x_413
+               OpStore %delta2 %474 None
       %x_416 = OpLoad %float %delta1 None
       %x_417 = OpLoad %float %delta1 None
       %x_418 = OpLoad %float %delta2 None
-        %480 = OpFAdd %float %x_417 %x_418
-        %481 = OpFDiv %float %x_416 %480
-               OpStore %ratio %481 None
+        %478 = OpFAdd %float %x_417 %x_418
+        %479 = OpFDiv %float %x_416 %478
+               OpStore %ratio %479 None
       %x_421 = OpLoad %float %ratio None
       %x_422 = OpLoad %v2float %vLastOffset None
       %x_424 = OpLoad %float %ratio None
       %x_426 = OpLoad %v2float %vCurrOffset None
-        %486 = OpVectorTimesScalar %v2float %x_422 %x_421
-        %487 = OpFSub %float %float_1 %x_424
-        %488 = OpVectorTimesScalar %v2float %x_426 %487
-        %489 = OpFAdd %v2float %486 %488
-               OpStore %vCurrOffset %489 None
-               OpBranch %454
-        %468 = OpLabel
+        %484 = OpVectorTimesScalar %v2float %x_422 %x_421
+        %485 = OpFSub %float %float_1 %x_424
+        %486 = OpVectorTimesScalar %v2float %x_426 %485
+        %487 = OpFAdd %v2float %484 %486
+               OpStore %vCurrOffset %487 None
+               OpBranch %452
+        %466 = OpLabel
       %x_431 = OpLoad %float %stepSize None
       %x_432 = OpLoad %float %currRayHeight None
-        %492 = OpFSub %float %x_432 %x_431
-               OpStore %currRayHeight %492 None
+        %490 = OpFSub %float %x_432 %x_431
+               OpStore %currRayHeight %490 None
       %x_434 = OpLoad %v2float %vCurrOffset None
                OpStore %vLastOffset %x_434 None
       %x_435 = OpLoad %float %stepSize None
       %x_436 = OpLoad %v2float %vMaxOffset None
       %x_438 = OpLoad %v2float %vCurrOffset None
-        %497 = OpVectorTimesScalar %v2float %x_436 %x_435
-        %498 = OpFAdd %v2float %x_438 %497
-               OpStore %vCurrOffset %498 None
+        %495 = OpVectorTimesScalar %v2float %x_436 %x_435
+        %496 = OpFAdd %v2float %x_438 %495
+               OpStore %vCurrOffset %496 None
       %x_440 = OpLoad %float %currSampledHeight None
                OpStore %lastSampledHeight %x_440 None
-               OpBranch %466
-        %466 = OpLabel
-               OpBranch %452
-        %452 = OpLabel
+               OpBranch %464
+        %464 = OpLabel
+               OpBranch %450
+        %450 = OpLabel
       %x_441 = OpLoad %int %i None
-        %501 = OpIAdd %int %x_441 %int_1
-               OpStore %i %501 None
-               OpBranch %453
-        %454 = OpLabel
+        %499 = OpIAdd %int %x_441 %int_1
+               OpStore %i %499 None
+               OpBranch %451
+        %452 = OpLabel
       %x_444 = OpLoad %v2float %vCurrOffset None
                OpStore %parallaxOcclusion_0 %x_444 None
       %x_445 = OpLoad %v2float %parallaxOcclusion_0 None
                OpStore %uvOffset %x_445 None
       %x_449 = OpLoad %v2float %v_uv None
       %x_450 = OpLoad %v2float %uvOffset None
-        %506 = OpLoad %11 %TextureSamplerTexture None
-        %507 = OpLoad %14 %TextureSamplerSampler None
-        %508 = OpFAdd %v2float %x_449 %x_450
-        %509 = OpSampledImage %349 %506 %507
-      %x_452 = OpImageSampleImplicitLod %v4float %509 %508 None
-        %511 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_2
-      %x_454 = OpLoad %float %511 None
+        %505 = OpLoad %11 %TextureSamplerTexture None
+        %506 = OpLoad %14 %TextureSamplerSampler None
+        %507 = OpFAdd %v2float %x_449 %x_450
+        %508 = OpSampledImage %346 %505 %506
+      %x_452 = OpImageSampleImplicitLod %v4float %508 %507 None
+        %510 = OpAccessChain %_ptr_Uniform_float %19 %uint_0 %uint_2
+      %x_454 = OpLoad %float %510 None
       %x_457 = OpLoad %mat3v3float %TBN None
                OpStore %param_8 %x_457 None
-        %514 = OpCompositeExtract %float %x_452 0
-        %515 = OpCompositeExtract %float %x_452 1
-        %516 = OpCompositeExtract %float %x_452 2
-        %517 = OpCompositeConstruct %v3float %514 %515 %516
-               OpStore %param_9 %517 None
-        %518 = OpFDiv %float %float_1 %x_454
-               OpStore %param_10 %518 None
+        %513 = OpCompositeExtract %float %x_452 0
+        %514 = OpCompositeExtract %float %x_452 1
+        %515 = OpCompositeExtract %float %x_452 2
+        %516 = OpCompositeConstruct %v3float %513 %514 %515
+               OpStore %param_9 %516 None
+        %517 = OpFDiv %float %float_1 %x_454
+               OpStore %param_10 %517 None
       %x_461 = OpFunctionCall %v3float %perturbNormal_mf33_vf3_f1_ %param_8 %param_9 %param_10
       %x_462 = OpLoad %v4float %output4 None
-        %521 = OpCompositeExtract %float %x_461 0
-        %522 = OpCompositeExtract %float %x_461 1
-        %523 = OpCompositeExtract %float %x_461 2
-        %524 = OpCompositeExtract %float %x_462 3
-        %525 = OpCompositeConstruct %v4float %521 %522 %523 %524
-               OpStore %output4 %525 None
+        %520 = OpCompositeExtract %float %x_461 0
+        %521 = OpCompositeExtract %float %x_461 1
+        %522 = OpCompositeExtract %float %x_461 2
+        %523 = OpCompositeExtract %float %x_462 3
+        %524 = OpCompositeConstruct %v4float %520 %521 %522 %523
+               OpStore %output4 %524 None
       %x_465 = OpLoad %v2float %v_uv None
       %x_466 = OpLoad %v2float %uvOffset None
-        %528 = OpFAdd %v2float %x_465 %x_466
-               OpStore %output6 %528 None
+        %527 = OpFAdd %v2float %x_465 %x_466
+               OpStore %output6 %527 None
       %x_474 = OpLoad %v2float %output6 None
-        %530 = OpLoad %11 %TextureSampler1Texture None
-        %531 = OpLoad %14 %TextureSampler1Sampler None
-        %532 = OpSampledImage %349 %530 %531
-      %x_475 = OpImageSampleImplicitLod %v4float %532 %x_474 None
+        %529 = OpLoad %11 %TextureSampler1Texture None
+        %530 = OpLoad %14 %TextureSampler1Sampler None
+        %531 = OpSampledImage %346 %529 %530
+      %x_475 = OpImageSampleImplicitLod %v4float %531 %x_474 None
                OpStore %tempTextureRead1 %x_475 None
       %x_477 = OpLoad %v4float %tempTextureRead1 None
-        %535 = OpCompositeExtract %float %x_477 0
-        %536 = OpCompositeExtract %float %x_477 1
-        %537 = OpCompositeExtract %float %x_477 2
-        %538 = OpCompositeConstruct %v3float %535 %536 %537
-               OpStore %rgb1 %538 None
-        %539 = OpAccessChain %_ptr_Uniform_v3float %19 %uint_0 %uint_4
-      %x_481 = OpLoad %v3float %539 None
+        %534 = OpCompositeExtract %float %x_477 0
+        %535 = OpCompositeExtract %float %x_477 1
+        %536 = OpCompositeExtract %float %x_477 2
+        %537 = OpCompositeConstruct %v3float %534 %535 %536
+               OpStore %rgb1 %537 None
+        %538 = OpAccessChain %_ptr_Uniform_v3float %19 %uint_0 %uint_4
+      %x_481 = OpLoad %v3float %538 None
       %x_482 = OpLoad %v4float %v_output1 None
-        %542 = OpCompositeExtract %float %x_482 0
-        %543 = OpCompositeExtract %float %x_482 1
-        %544 = OpCompositeExtract %float %x_482 2
-        %545 = OpCompositeConstruct %v3float %542 %543 %544
-        %546 = OpFSub %v3float %x_481 %545
-        %547 = OpExtInst %v3float %85 Normalize %546
-               OpStore %viewDirectionW_1 %547 None
+        %541 = OpCompositeExtract %float %x_482 0
+        %542 = OpCompositeExtract %float %x_482 1
+        %543 = OpCompositeExtract %float %x_482 2
+        %544 = OpCompositeConstruct %v3float %541 %542 %543
+        %545 = OpFSub %v3float %x_481 %544
+        %546 = OpExtInst %v3float %85 Normalize %545
+               OpStore %viewDirectionW_1 %546 None
                OpStore %shadow %float_1 None
       %x_488 = OpLoad %float %u_Float None
-        %549 = OpFMul %float %float_1 %x_488
-               OpStore %glossiness_1 %549 None
+        %548 = OpFMul %float %float_1 %x_488
+               OpStore %glossiness_1 %548 None
                OpStore %diffuseBase %8 None
                OpStore %specularBase %8 None
       %x_494 = OpLoad %v4float %output4 None
-        %551 = OpCompositeExtract %float %x_494 0
-        %552 = OpCompositeExtract %float %x_494 1
-        %553 = OpCompositeExtract %float %x_494 2
-        %554 = OpCompositeConstruct %v3float %551 %552 %553
-               OpStore %normalW %554 None
+        %550 = OpCompositeExtract %float %x_494 0
+        %551 = OpCompositeExtract %float %x_494 1
+        %552 = OpCompositeExtract %float %x_494 2
+        %553 = OpCompositeConstruct %v3float %550 %551 %552
+               OpStore %normalW %553 None
       %x_501 = OpLoad %v3float %viewDirectionW_1 None
                OpStore %param_11 %x_501 None
       %x_503 = OpLoad %v3float %normalW None
                OpStore %param_12 %x_503 None
-        %557 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_0
-      %x_507 = OpLoad %v4float %557 None
+        %556 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_0
+      %x_507 = OpLoad %v4float %556 None
                OpStore %param_13 %x_507 None
-        %560 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_1
-      %x_510 = OpLoad %v4float %560 None
-        %562 = OpCompositeExtract %float %x_510 0
-        %563 = OpCompositeExtract %float %x_510 1
-        %564 = OpCompositeExtract %float %x_510 2
-        %565 = OpCompositeConstruct %v3float %562 %563 %564
-               OpStore %param_14 %565 None
-        %566 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_2
-      %x_514 = OpLoad %v4float %566 None
-        %568 = OpCompositeExtract %float %x_514 0
-        %569 = OpCompositeExtract %float %x_514 1
-        %570 = OpCompositeExtract %float %x_514 2
-        %571 = OpCompositeConstruct %v3float %568 %569 %570
-               OpStore %param_15 %571 None
-        %572 = OpAccessChain %_ptr_Uniform_v3float %37 %uint_0 %uint_3
-      %x_518 = OpLoad %v3float %572 None
+        %559 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_1
+      %x_510 = OpLoad %v4float %559 None
+        %561 = OpCompositeExtract %float %x_510 0
+        %562 = OpCompositeExtract %float %x_510 1
+        %563 = OpCompositeExtract %float %x_510 2
+        %564 = OpCompositeConstruct %v3float %561 %562 %563
+               OpStore %param_14 %564 None
+        %565 = OpAccessChain %_ptr_Uniform_v4float %37 %uint_0 %uint_2
+      %x_514 = OpLoad %v4float %565 None
+        %567 = OpCompositeExtract %float %x_514 0
+        %568 = OpCompositeExtract %float %x_514 1
+        %569 = OpCompositeExtract %float %x_514 2
+        %570 = OpCompositeConstruct %v3float %567 %568 %569
+               OpStore %param_15 %570 None
+        %571 = OpAccessChain %_ptr_Uniform_v3float %37 %uint_0 %uint_3
+      %x_518 = OpLoad %v3float %571 None
                OpStore %param_16 %x_518 None
       %x_520 = OpLoad %float %glossiness_1 None
                OpStore %param_17 %x_520 None
       %x_521 = OpFunctionCall %lightingInfo %computeHemisphericLighting_vf3_vf3_vf4_vf3_vf3_vf3_f1_ %param_11 %param_12 %param_13 %param_14 %param_15 %param_16 %param_17
                OpStore %info %x_521 None
                OpStore %shadow %float_1 None
-        %577 = OpAccessChain %_ptr_Function_v3float %info %uint_0
-      %x_523 = OpLoad %v3float %577 None
+        %576 = OpAccessChain %_ptr_Function_v3float %info %uint_0
+      %x_523 = OpLoad %v3float %576 None
       %x_524 = OpLoad %float %shadow None
       %x_526 = OpLoad %v3float %diffuseBase None
-        %581 = OpVectorTimesScalar %v3float %x_523 %x_524
-        %582 = OpFAdd %v3float %x_526 %581
-               OpStore %diffuseBase %582 None
-        %583 = OpAccessChain %_ptr_Function_v3float %info %uint_1
-      %x_529 = OpLoad %v3float %583 None
+        %580 = OpVectorTimesScalar %v3float %x_523 %x_524
+        %581 = OpFAdd %v3float %x_526 %580
+               OpStore %diffuseBase %581 None
+        %582 = OpAccessChain %_ptr_Function_v3float %info %uint_1
+      %x_529 = OpLoad %v3float %582 None
       %x_530 = OpLoad %float %shadow None
       %x_532 = OpLoad %v3float %specularBase None
-        %587 = OpVectorTimesScalar %v3float %x_529 %x_530
-        %588 = OpFAdd %v3float %x_532 %587
-               OpStore %specularBase %588 None
+        %586 = OpVectorTimesScalar %v3float %x_529 %x_530
+        %587 = OpFAdd %v3float %x_532 %586
+               OpStore %specularBase %587 None
       %x_535 = OpLoad %v3float %diffuseBase None
       %x_536 = OpLoad %v3float %rgb1 None
-        %591 = OpFMul %v3float %x_535 %x_536
-               OpStore %diffuseOutput %591 None
+        %590 = OpFMul %v3float %x_535 %x_536
+               OpStore %diffuseOutput %590 None
       %x_539 = OpLoad %v3float %specularBase None
       %x_540 = OpLoad %v3float %u_Color None
-        %594 = OpFMul %v3float %x_539 %x_540
-               OpStore %specularOutput %594 None
+        %593 = OpFMul %v3float %x_539 %x_540
+               OpStore %specularOutput %593 None
       %x_543 = OpLoad %v3float %diffuseOutput None
       %x_544 = OpLoad %v3float %specularOutput None
-        %597 = OpFAdd %v3float %x_543 %x_544
-               OpStore %output3 %597 None
+        %596 = OpFAdd %v3float %x_543 %x_544
+               OpStore %output3 %596 None
       %x_548 = OpLoad %v3float %output3 None
-        %599 = OpCompositeExtract %float %x_548 0
-        %600 = OpCompositeExtract %float %x_548 1
-        %601 = OpCompositeExtract %float %x_548 2
-        %602 = OpCompositeConstruct %v4float %599 %600 %601 %float_1
-               OpStore %glFragColor %602 None
+        %598 = OpCompositeExtract %float %x_548 0
+        %599 = OpCompositeExtract %float %x_548 1
+        %600 = OpCompositeExtract %float %x_548 2
+        %601 = OpCompositeConstruct %v4float %598 %599 %600 %float_1
+               OpStore %glFragColor %601 None
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %main_out None %610
+ %main_inner = OpFunction %main_out None %609
 %vMainuv_param = OpFunctionParameter %v2float
 %v_output1_param = OpFunctionParameter %v4float
 %gl_FrontFacing_param = OpFunctionParameter %bool
  %v_uv_param = OpFunctionParameter %v2float
 %v_output2_param = OpFunctionParameter %v4float
-        %611 = OpLabel
+        %610 = OpLabel
                OpStore %vMainuv %vMainuv_param None
                OpStore %v_output1 %v_output1_param None
                OpStore %gl_FrontFacing %gl_FrontFacing_param None
                OpStore %v_uv %v_uv_param None
                OpStore %v_output2 %v_output2_param None
-        %612 = OpFunctionCall %void %main_1
-        %613 = OpLoad %v4float %glFragColor None
-        %614 = OpCompositeConstruct %main_out %613
-               OpReturnValue %614
+        %611 = OpFunctionCall %void %main_1
+        %612 = OpLoad %v4float %glFragColor None
+        %613 = OpCompositeConstruct %main_out %612
+               OpReturnValue %613
                OpFunctionEnd
-       %main = OpFunction %void None %286
-        %616 = OpLabel
-        %617 = OpLoad %v2float %main_loc1_Input None
-        %618 = OpLoad %v4float %main_loc0_Input None
-        %619 = OpLoad %bool %main_front_facing_Input None
-        %620 = OpLoad %v2float %main_loc3_Input None
-        %621 = OpLoad %v4float %main_loc2_Input None
-        %622 = OpFunctionCall %main_out %main_inner %617 %618 %619 %620 %621
-        %623 = OpCompositeExtract %v4float %622 0
-               OpStore %main_loc0_Output %623 None
+       %main = OpFunction %void None %282
+        %615 = OpLabel
+        %616 = OpLoad %v2float %main_loc1_Input None
+        %617 = OpLoad %v4float %main_loc0_Input None
+        %618 = OpLoad %bool %main_front_facing_Input None
+        %619 = OpLoad %v2float %main_loc3_Input None
+        %620 = OpLoad %v4float %main_loc2_Input None
+        %621 = OpFunctionCall %main_out %main_inner %616 %617 %618 %619 %620
+        %622 = OpCompositeExtract %v4float %621 0
+               OpStore %main_loc0_Output %622 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/977.spvasm.expected.dxc.hlsl b/test/tint/bug/tint/977.spvasm.expected.dxc.hlsl
index 3115650..c88f59d 100644
--- a/test/tint/bug/tint/977.spvasm.expected.dxc.hlsl
+++ b/test/tint/bug/tint/977.spvasm.expected.dxc.hlsl
@@ -22,6 +22,9 @@
 }
 
 void main_1() {
+  uint tint_symbol_3 = 0u;
+  resultMatrix.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
   int index = 0;
   int a_1 = 0;
   float param = 0.0f;
@@ -32,7 +35,7 @@
   param = -4.0f;
   param_1 = -3.0f;
   float x_68 = binaryOperation_f1_f1_(param, param_1);
-  resultMatrix.Store((4u * uint(x_63)), asuint(x_68));
+  resultMatrix.Store((4u * min(uint(x_63), (tint_symbol_4 - 1u))), asuint(x_68));
   return;
 }
 
diff --git a/test/tint/bug/tint/977.spvasm.expected.fxc.hlsl b/test/tint/bug/tint/977.spvasm.expected.fxc.hlsl
index 3115650..c88f59d 100644
--- a/test/tint/bug/tint/977.spvasm.expected.fxc.hlsl
+++ b/test/tint/bug/tint/977.spvasm.expected.fxc.hlsl
@@ -22,6 +22,9 @@
 }
 
 void main_1() {
+  uint tint_symbol_3 = 0u;
+  resultMatrix.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = ((tint_symbol_3 - 0u) / 4u);
   int index = 0;
   int a_1 = 0;
   float param = 0.0f;
@@ -32,7 +35,7 @@
   param = -4.0f;
   param_1 = -3.0f;
   float x_68 = binaryOperation_f1_f1_(param, param_1);
-  resultMatrix.Store((4u * uint(x_63)), asuint(x_68));
+  resultMatrix.Store((4u * min(uint(x_63), (tint_symbol_4 - 1u))), asuint(x_68));
   return;
 }
 
diff --git a/test/tint/bug/tint/977.spvasm.expected.glsl b/test/tint/bug/tint/977.spvasm.expected.glsl
index 33a6a83..fbec1f7 100644
--- a/test/tint/bug/tint/977.spvasm.expected.glsl
+++ b/test/tint/bug/tint/977.spvasm.expected.glsl
@@ -30,7 +30,9 @@
   param = -4.0f;
   param_1 = -3.0f;
   float x_68 = binaryOperation_f1_f1_(param, param_1);
-  resultMatrix.numbers[x_63] = x_68;
+  uint v = (uint(resultMatrix.numbers.length()) - 1u);
+  uint v_1 = min(uint(x_63), v);
+  resultMatrix.numbers[v_1] = x_68;
 }
 void tint_symbol_1_inner(uvec3 tint_symbol_2) {
   tint_symbol = tint_symbol_2;
diff --git a/test/tint/bug/tint/977.spvasm.expected.ir.dxc.hlsl b/test/tint/bug/tint/977.spvasm.expected.ir.dxc.hlsl
index 815c7e4..e7dc76f 100644
--- a/test/tint/bug/tint/977.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/977.spvasm.expected.ir.dxc.hlsl
@@ -37,7 +37,10 @@
   param = -4.0f;
   param_1 = -3.0f;
   float x_68 = binaryOperation_f1_f1_(param, param_1);
-  resultMatrix.Store((0u + (uint(x_63) * 4u)), asuint(x_68));
+  uint v_1 = 0u;
+  resultMatrix.GetDimensions(v_1);
+  uint v_2 = ((v_1 / 4u) - 1u);
+  resultMatrix.Store((0u + (min(uint(x_63), v_2) * 4u)), asuint(x_68));
 }
 
 void main_inner(uint3 gl_GlobalInvocationID_param) {
diff --git a/test/tint/bug/tint/977.spvasm.expected.ir.fxc.hlsl b/test/tint/bug/tint/977.spvasm.expected.ir.fxc.hlsl
index 815c7e4..e7dc76f 100644
--- a/test/tint/bug/tint/977.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/977.spvasm.expected.ir.fxc.hlsl
@@ -37,7 +37,10 @@
   param = -4.0f;
   param_1 = -3.0f;
   float x_68 = binaryOperation_f1_f1_(param, param_1);
-  resultMatrix.Store((0u + (uint(x_63) * 4u)), asuint(x_68));
+  uint v_1 = 0u;
+  resultMatrix.GetDimensions(v_1);
+  uint v_2 = ((v_1 / 4u) - 1u);
+  resultMatrix.Store((0u + (min(uint(x_63), v_2) * 4u)), asuint(x_68));
 }
 
 void main_inner(uint3 gl_GlobalInvocationID_param) {
diff --git a/test/tint/bug/tint/977.spvasm.expected.ir.msl b/test/tint/bug/tint/977.spvasm.expected.ir.msl
index cf6dd98..d1b7e5e 100644
--- a/test/tint/bug/tint/977.spvasm.expected.ir.msl
+++ b/test/tint/bug/tint/977.spvasm.expected.ir.msl
@@ -37,6 +37,7 @@
   const device FirstMatrix* firstMatrix;
   const device SecondMatrix* secondMatrix;
   const constant Uniforms* x_46;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 float binaryOperation_f1_f1_(thread float* const a, thread float* const b) {
@@ -65,7 +66,8 @@
   param = -4.0f;
   param_1 = -3.0f;
   float const x_68 = binaryOperation_f1_f1_((&param), (&param_1));
-  (*tint_module_vars.resultMatrix).numbers[x_63] = x_68;
+  uint const v = ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u);
+  (*tint_module_vars.resultMatrix).numbers[min(uint(x_63), v)] = x_68;
 }
 
 void tint_symbol_1_inner(uint3 gl_GlobalInvocationID_param, tint_module_vars_struct tint_module_vars) {
@@ -73,8 +75,8 @@
   main_1(tint_module_vars);
 }
 
-kernel void tint_symbol_1(uint3 gl_GlobalInvocationID_param [[thread_position_in_grid]], device ResultMatrix* resultMatrix [[buffer(0)]]) {
+kernel void tint_symbol_1(uint3 gl_GlobalInvocationID_param [[thread_position_in_grid]], device ResultMatrix* resultMatrix [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread uint3 gl_GlobalInvocationID = 0u;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.gl_GlobalInvocationID=(&gl_GlobalInvocationID), .resultMatrix=resultMatrix};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.gl_GlobalInvocationID=(&gl_GlobalInvocationID), .resultMatrix=resultMatrix, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_1_inner(gl_GlobalInvocationID_param, tint_module_vars);
 }
diff --git a/test/tint/bug/tint/977.spvasm.expected.msl b/test/tint/bug/tint/977.spvasm.expected.msl
index c597155..16460dc 100644
--- a/test/tint/bug/tint/977.spvasm.expected.msl
+++ b/test/tint/bug/tint/977.spvasm.expected.msl
@@ -18,6 +18,10 @@
   uint3 gl_GlobalInvocationID;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct ResultMatrix {
   /* 0x0000 */ tint_array<float, 1> numbers;
 };
@@ -51,7 +55,7 @@
   return x_41;
 }
 
-void main_1(thread tint_private_vars_struct* const tint_private_vars, device ResultMatrix* const tint_symbol_2) {
+void main_1(thread tint_private_vars_struct* const tint_private_vars, device ResultMatrix* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
   int index = 0;
   int a_1 = 0;
   float param = 0.0f;
@@ -62,18 +66,18 @@
   param = -4.0f;
   param_1 = -3.0f;
   float const x_68 = binaryOperation_f1_f1_(&(param), &(param_1));
-  (*(tint_symbol_2)).numbers[x_63] = x_68;
+  (*(tint_symbol_2)).numbers[min(uint(x_63), ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] = x_68;
   return;
 }
 
-void tint_symbol_1_inner(uint3 gl_GlobalInvocationID_param, thread tint_private_vars_struct* const tint_private_vars, device ResultMatrix* const tint_symbol_3) {
+void tint_symbol_1_inner(uint3 gl_GlobalInvocationID_param, thread tint_private_vars_struct* const tint_private_vars, device ResultMatrix* const tint_symbol_4, const constant TintArrayLengths* const tint_symbol_5) {
   (*(tint_private_vars)).gl_GlobalInvocationID = gl_GlobalInvocationID_param;
-  main_1(tint_private_vars, tint_symbol_3);
+  main_1(tint_private_vars, tint_symbol_4, tint_symbol_5);
 }
 
-kernel void tint_symbol_1(device ResultMatrix* tint_symbol_4 [[buffer(0)]], uint3 gl_GlobalInvocationID_param [[thread_position_in_grid]]) {
+kernel void tint_symbol_1(device ResultMatrix* tint_symbol_6 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_7 [[buffer(30)]], uint3 gl_GlobalInvocationID_param [[thread_position_in_grid]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_symbol_1_inner(gl_GlobalInvocationID_param, &(tint_private_vars), tint_symbol_4);
+  tint_symbol_1_inner(gl_GlobalInvocationID_param, &(tint_private_vars), tint_symbol_6, tint_symbol_7);
   return;
 }
 
diff --git a/test/tint/bug/tint/977.spvasm.expected.spvasm b/test/tint/bug/tint/977.spvasm.expected.spvasm
index 0ad23b4..500996b 100644
--- a/test/tint/bug/tint/977.spvasm.expected.spvasm
+++ b/test/tint/bug/tint/977.spvasm.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 104
+; Bound: 111
 ; Schema: 0
                OpCapability Shader
          %51 = OpExtInstImport "GLSL.std.450"
@@ -110,8 +110,10 @@
     %int_n10 = OpConstant %int -10
    %float_n4 = OpConstant %float -4
    %float_n3 = OpConstant %float -3
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-         %97 = OpTypeFunction %void %v3uint
+        %104 = OpTypeFunction %void %v3uint
 %binaryOperation_f1_f1_ = OpFunction %float None %28
      %a_root = OpFunctionParameter %_ptr_Function_float
      %b_root = OpFunctionParameter %_ptr_Function_float
@@ -183,20 +185,25 @@
                OpStore %param %float_n4 None
                OpStore %param_1 %float_n3 None
        %x_68 = OpFunctionCall %float %binaryOperation_f1_f1_ %param %param_1
-         %93 = OpAccessChain %_ptr_StorageBuffer_float %resultMatrix %uint_0 %x_63
-               OpStore %93 %x_68 None
+         %93 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %resultMatrix %uint_0
+         %95 = OpArrayLength %uint %resultMatrix 0
+         %96 = OpISub %uint %95 %uint_1
+         %98 = OpBitcast %uint %x_63
+         %99 = OpExtInst %uint %51 UMin %98 %96
+        %100 = OpAccessChain %_ptr_StorageBuffer_float %resultMatrix %uint_0 %99
+               OpStore %100 %x_68 None
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %97
+ %main_inner = OpFunction %void None %104
 %gl_GlobalInvocationID_param = OpFunctionParameter %v3uint
-         %98 = OpLabel
+        %105 = OpLabel
                OpStore %gl_GlobalInvocationID %gl_GlobalInvocationID_param None
-         %99 = OpFunctionCall %void %main_1
+        %106 = OpFunctionCall %void %main_1
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %75
-        %101 = OpLabel
-        %102 = OpLoad %v3uint %main_global_invocation_id_Input None
-        %103 = OpFunctionCall %void %main_inner %102
+        %108 = OpLabel
+        %109 = OpLoad %v3uint %main_global_invocation_id_Input None
+        %110 = OpFunctionCall %void %main_inner %109
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/980.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/980.wgsl.expected.dxc.hlsl
index 0e4a5a5..472e34c 100644
--- a/test/tint/bug/tint/980.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/980.wgsl.expected.dxc.hlsl
@@ -4,7 +4,7 @@
 
 float3 Bad(uint index, float3 rd) {
   float3 normal = (0.0f).xxx;
-  set_vector_element(normal, index, -(float(sign(rd[index]))));
+  set_vector_element(normal, min(index, 2u), -(float(sign(rd[min(index, 2u)]))));
   return normalize(normal);
 }
 
diff --git a/test/tint/bug/tint/980.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/980.wgsl.expected.fxc.hlsl
index 0e4a5a5..472e34c 100644
--- a/test/tint/bug/tint/980.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/980.wgsl.expected.fxc.hlsl
@@ -4,7 +4,7 @@
 
 float3 Bad(uint index, float3 rd) {
   float3 normal = (0.0f).xxx;
-  set_vector_element(normal, index, -(float(sign(rd[index]))));
+  set_vector_element(normal, min(index, 2u), -(float(sign(rd[min(index, 2u)]))));
   return normalize(normal);
 }
 
diff --git a/test/tint/bug/tint/980.wgsl.expected.glsl b/test/tint/bug/tint/980.wgsl.expected.glsl
index 1421c73..ee2545c 100644
--- a/test/tint/bug/tint/980.wgsl.expected.glsl
+++ b/test/tint/bug/tint/980.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 } v_1;
 vec3 Bad(uint index, vec3 rd) {
   vec3 normal = vec3(0.0f);
-  normal[index] = -(sign(rd[index]));
+  normal[min(index, 2u)] = -(sign(rd[min(index, 2u)]));
   return normalize(normal);
 }
 void tint_symbol_inner(uint idx) {
diff --git a/test/tint/bug/tint/980.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/980.wgsl.expected.ir.dxc.hlsl
index a4c4706..7e3aa87 100644
--- a/test/tint/bug/tint/980.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/980.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer io : register(u0);
 float3 Bad(uint index, float3 rd) {
   float3 normal = (0.0f).xxx;
-  normal[index] = -(float(sign(rd[index])));
+  normal[min(index, 2u)] = -(float(sign(rd[min(index, 2u)])));
   return normalize(normal);
 }
 
diff --git a/test/tint/bug/tint/980.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/980.wgsl.expected.ir.fxc.hlsl
index 85f7ef2..b408ab3 100644
--- a/test/tint/bug/tint/980.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/980.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer io : register(u0);
 float3 Bad(uint index, float3 rd) {
   float3 normal = (0.0f).xxx;
-  float v_1 = -(float(sign(rd[index])));
+  float v_1 = -(float(sign(rd[min(index, 2u)])));
   float3 v_2 = normal;
   normal = (((index.xxx == float3(int(0), int(1), int(2)))) ? (v_1.xxx) : (v_2));
   return normalize(normal);
diff --git a/test/tint/bug/tint/980.wgsl.expected.ir.msl b/test/tint/bug/tint/980.wgsl.expected.ir.msl
index be3aac9..b42731a 100644
--- a/test/tint/bug/tint/980.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/980.wgsl.expected.ir.msl
@@ -12,7 +12,7 @@
 
 float3 Bad(uint index, float3 rd) {
   float3 normal = float3(0.0f);
-  normal[index] = -(sign(rd[index]));
+  normal[min(index, 2u)] = -(sign(rd[min(index, 2u)]));
   return normalize(normal);
 }
 
diff --git a/test/tint/bug/tint/980.wgsl.expected.msl b/test/tint/bug/tint/980.wgsl.expected.msl
index 8d0305e..a9ee24b 100644
--- a/test/tint/bug/tint/980.wgsl.expected.msl
+++ b/test/tint/bug/tint/980.wgsl.expected.msl
@@ -8,7 +8,7 @@
 
 float3 Bad(uint index, float3 rd) {
   float3 normal = float3(0.0f);
-  normal[index] = -(sign(rd[index]));
+  normal[min(index, 2u)] = -(sign(rd[min(index, 2u)]));
   return normalize(normal);
 }
 
diff --git a/test/tint/bug/tint/980.wgsl.expected.spvasm b/test/tint/bug/tint/980.wgsl.expected.spvasm
index 9d1240a..4f939f8 100644
--- a/test/tint/bug/tint/980.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/980.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 46
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
-         %20 = OpExtInstImport "GLSL.std.450"
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -41,44 +41,47 @@
          %13 = OpTypeFunction %v3float %uint %v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
          %17 = OpConstantNull %v3float
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void %uint
+         %32 = OpTypeFunction %void %uint
 %_ptr_StorageBuffer_v3float = OpTypePointer StorageBuffer %v3float
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_1 = OpConstant %uint 1
-         %42 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
         %Bad = OpFunction %v3float None %13
       %index = OpFunctionParameter %uint
          %rd = OpFunctionParameter %v3float
          %14 = OpLabel
      %normal = OpVariable %_ptr_Function_v3float Function
                OpStore %normal %17
-         %18 = OpVectorExtractDynamic %float %rd %index
-         %19 = OpExtInst %float %20 FSign %18
-         %21 = OpFNegate %float %19
-         %22 = OpAccessChain %_ptr_Function_float %normal %index
-               OpStore %22 %21 None
-         %24 = OpLoad %v3float %normal None
-         %25 = OpExtInst %v3float %20 Normalize %24
-               OpReturnValue %25
+         %18 = OpExtInst %uint %19 UMin %index %uint_2
+         %21 = OpVectorExtractDynamic %float %rd %18
+         %22 = OpExtInst %float %19 FSign %21
+         %23 = OpFNegate %float %22
+         %24 = OpExtInst %uint %19 UMin %index %uint_2
+         %25 = OpAccessChain %_ptr_Function_float %normal %24
+               OpStore %25 %23 None
+         %27 = OpLoad %v3float %normal None
+         %28 = OpExtInst %v3float %19 Normalize %27
+               OpReturnValue %28
                OpFunctionEnd
- %main_inner = OpFunction %void None %29
+ %main_inner = OpFunction %void None %32
         %idx = OpFunctionParameter %uint
-         %30 = OpLabel
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
-         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_1
-         %37 = OpLoad %uint %34 None
-         %38 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
-         %39 = OpLoad %v3float %38 None
-         %40 = OpFunctionCall %v3float %Bad %37 %39
-               OpStore %31 %40 None
+         %33 = OpLabel
+         %34 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
+         %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %uint_1
+         %40 = OpLoad %uint %37 None
+         %41 = OpAccessChain %_ptr_StorageBuffer_v3float %1 %uint_0 %uint_0
+         %42 = OpLoad %v3float %41 None
+         %43 = OpFunctionCall %v3float %Bad %40 %42
+               OpStore %34 %43 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpLoad %uint %main_local_invocation_index_Input None
-         %45 = OpFunctionCall %void %main_inner %44
+       %main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpLoad %uint %main_local_invocation_index_Input None
+         %48 = OpFunctionCall %void %main_inner %47
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/990.wgsl.expected.ir.msl b/test/tint/bug/tint/990.wgsl.expected.ir.msl
index c72f776..b225169 100644
--- a/test/tint/bug/tint/990.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/990.wgsl.expected.ir.msl
@@ -1,11 +1,15 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     thread int* const p = (&i);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/bug/tint/990.wgsl.expected.msl b/test/tint/bug/tint/990.wgsl.expected.msl
index 1725260..e63c043 100644
--- a/test/tint/bug/tint/990.wgsl.expected.msl
+++ b/test/tint/bug/tint/990.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   for(; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/bug/tint/993.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.dxc.hlsl
index af78cdf..51175e7 100644
--- a/test/tint/bug/tint/993.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.dxc.hlsl
@@ -14,7 +14,7 @@
 
 
 int runTest() {
-  return satomicLoad((4u * (0u + uint(constants[0].x))));
+  return satomicLoad((4u * min((0u + uint(constants[0].x)), 2u)));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/993.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.fxc.hlsl
index af78cdf..51175e7 100644
--- a/test/tint/bug/tint/993.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.fxc.hlsl
@@ -14,7 +14,7 @@
 
 
 int runTest() {
-  return satomicLoad((4u * (0u + uint(constants[0].x))));
+  return satomicLoad((4u * min((0u + uint(constants[0].x)), 2u)));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/bug/tint/993.wgsl.expected.glsl b/test/tint/bug/tint/993.wgsl.expected.glsl
index faadd2b..4da7059 100644
--- a/test/tint/bug/tint/993.wgsl.expected.glsl
+++ b/test/tint/bug/tint/993.wgsl.expected.glsl
@@ -26,7 +26,7 @@
   TestData inner;
 } v_2;
 int runTest() {
-  uint v_3 = (0u + uint(v.inner.zero));
+  uint v_3 = min((0u + uint(v.inner.zero)), 2u);
   return atomicOr(v_2.inner.data[v_3], 0);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
index f5cf4d4..c49140f 100644
--- a/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer s : register(u0);
 int runTest() {
   int v = int(0);
-  s.InterlockedOr(int((0u + ((0u + uint(constants[0u].x)) * 4u))), int(0), v);
+  s.InterlockedOr(int((0u + (min((0u + uint(constants[0u].x)), 2u) * 4u))), int(0), v);
   return v;
 }
 
diff --git a/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
index f5cf4d4..c49140f 100644
--- a/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/993.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 RWByteAddressBuffer s : register(u0);
 int runTest() {
   int v = int(0);
-  s.InterlockedOr(int((0u + ((0u + uint(constants[0u].x)) * 4u))), int(0), v);
+  s.InterlockedOr(int((0u + (min((0u + uint(constants[0u].x)), 2u) * 4u))), int(0), v);
   return v;
 }
 
diff --git a/test/tint/bug/tint/993.wgsl.expected.ir.msl b/test/tint/bug/tint/993.wgsl.expected.ir.msl
index 5a17088..d1c8f81 100644
--- a/test/tint/bug/tint/993.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/993.wgsl.expected.ir.msl
@@ -32,7 +32,7 @@
 };
 
 int runTest(tint_module_vars_struct tint_module_vars) {
-  return atomic_load_explicit((&(*tint_module_vars.s).data[(0u + uint((*tint_module_vars.constants).zero))]), memory_order_relaxed);
+  return atomic_load_explicit((&(*tint_module_vars.s).data[min((0u + uint((*tint_module_vars.constants).zero)), 2u)]), memory_order_relaxed);
 }
 
 kernel void tint_symbol(const constant Constants* constants [[buffer(0)]], device Result* result [[buffer(1)]], device TestData* s [[buffer(2)]]) {
diff --git a/test/tint/bug/tint/993.wgsl.expected.msl b/test/tint/bug/tint/993.wgsl.expected.msl
index b23a6ea..fdaf57a 100644
--- a/test/tint/bug/tint/993.wgsl.expected.msl
+++ b/test/tint/bug/tint/993.wgsl.expected.msl
@@ -27,7 +27,7 @@
 };
 
 int runTest(device TestData* const tint_symbol_2, const constant Constants* const tint_symbol_3) {
-  return atomic_load_explicit(&((*(tint_symbol_2)).data[(0u + uint((*(tint_symbol_3)).zero))]), memory_order_relaxed);
+  return atomic_load_explicit(&((*(tint_symbol_2)).data[min((0u + uint((*(tint_symbol_3)).zero)), 2u)]), memory_order_relaxed);
 }
 
 kernel void tint_symbol(device TestData* tint_symbol_4 [[buffer(2)]], const constant Constants* tint_symbol_5 [[buffer(0)]], device Result* tint_symbol_6 [[buffer(1)]]) {
diff --git a/test/tint/bug/tint/993.wgsl.expected.spvasm b/test/tint/bug/tint/993.wgsl.expected.spvasm
index 8b7b8b9..4085d42 100644
--- a/test/tint/bug/tint/993.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/993.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -59,25 +60,27 @@
          %18 = OpTypeFunction %int
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
     %runTest = OpFunction %int None %18
          %19 = OpLabel
          %20 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %23 = OpLoad %uint %20 None
          %24 = OpIAdd %uint %uint_0 %23
-         %25 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %24
-         %27 = OpAtomicLoad %int %25 %uint_1 %uint_0
-               OpReturnValue %27
+         %25 = OpExtInst %uint %26 UMin %24 %uint_2
+         %28 = OpAccessChain %_ptr_StorageBuffer_int %10 %uint_0 %uint_0 %25
+         %30 = OpAtomicLoad %int %28 %uint_1 %uint_0
+               OpReturnValue %30
                OpFunctionEnd
-       %main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpAccessChain %_ptr_StorageBuffer_uint %6 %uint_0 %uint_0
-         %35 = OpFunctionCall %int %runTest
-         %36 = OpBitcast %uint %35
-               OpStore %33 %36 None
+       %main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpAccessChain %_ptr_StorageBuffer_uint %6 %uint_0 %uint_0
+         %38 = OpFunctionCall %int %runTest
+         %39 = OpBitcast %uint %38
+               OpStore %36 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/bug/tint/998.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/998.wgsl.expected.dxc.hlsl
index a197d25..e2c6cf6 100644
--- a/test/tint/bug/tint/998.wgsl.expected.dxc.hlsl
+++ b/test/tint/bug/tint/998.wgsl.expected.dxc.hlsl
@@ -14,7 +14,7 @@
 void main() {
   {
     uint tint_symbol_1[3] = s.data;
-    tint_symbol_1[constants[0].x] = 0u;
+    tint_symbol_1[min(constants[0].x, 2u)] = 0u;
     s.data = tint_symbol_1;
   }
   return;
diff --git a/test/tint/bug/tint/998.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/998.wgsl.expected.fxc.hlsl
index a197d25..e2c6cf6 100644
--- a/test/tint/bug/tint/998.wgsl.expected.fxc.hlsl
+++ b/test/tint/bug/tint/998.wgsl.expected.fxc.hlsl
@@ -14,7 +14,7 @@
 void main() {
   {
     uint tint_symbol_1[3] = s.data;
-    tint_symbol_1[constants[0].x] = 0u;
+    tint_symbol_1[min(constants[0].x, 2u)] = 0u;
     s.data = tint_symbol_1;
   }
   return;
diff --git a/test/tint/bug/tint/998.wgsl.expected.glsl b/test/tint/bug/tint/998.wgsl.expected.glsl
index dcbde09..f7f0bcd 100644
--- a/test/tint/bug/tint/998.wgsl.expected.glsl
+++ b/test/tint/bug/tint/998.wgsl.expected.glsl
@@ -16,6 +16,6 @@
 S s = S(uint[3](0u, 0u, 0u));
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint v_1 = v.inner.zero;
+  uint v_1 = min(v.inner.zero, 2u);
   s.data[v_1] = 0u;
 }
diff --git a/test/tint/bug/tint/998.wgsl.expected.ir.dxc.hlsl b/test/tint/bug/tint/998.wgsl.expected.ir.dxc.hlsl
index ea68142..9d987ac 100644
--- a/test/tint/bug/tint/998.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/bug/tint/998.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 static S s = (S)0;
 [numthreads(1, 1, 1)]
 void main() {
-  uint v = constants[0u].x;
+  uint v = min(constants[0u].x, 2u);
   s.data[v] = 0u;
 }
 
diff --git a/test/tint/bug/tint/998.wgsl.expected.ir.fxc.hlsl b/test/tint/bug/tint/998.wgsl.expected.ir.fxc.hlsl
index 5866bb0..bf155f8 100644
--- a/test/tint/bug/tint/998.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/bug/tint/998.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 void main() {
   uint v = constants[0u].x;
   uint tint_array_copy[3] = s.data;
-  tint_array_copy[v] = 0u;
+  tint_array_copy[min(v, 2u)] = 0u;
   uint v_1[3] = tint_array_copy;
   s.data = v_1;
 }
diff --git a/test/tint/bug/tint/998.wgsl.expected.ir.msl b/test/tint/bug/tint/998.wgsl.expected.ir.msl
index d8a150d..8d376b0 100644
--- a/test/tint/bug/tint/998.wgsl.expected.ir.msl
+++ b/test/tint/bug/tint/998.wgsl.expected.ir.msl
@@ -34,5 +34,5 @@
 kernel void tint_symbol(const constant Constants* constants [[buffer(0)]]) {
   thread S s = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.constants=constants, .s=(&s)};
-  (*tint_module_vars.s).data[(*tint_module_vars.constants).zero] = 0u;
+  (*tint_module_vars.s).data[min((*tint_module_vars.constants).zero, 2u)] = 0u;
 }
diff --git a/test/tint/bug/tint/998.wgsl.expected.msl b/test/tint/bug/tint/998.wgsl.expected.msl
index 89d43d5..5009ded 100644
--- a/test/tint/bug/tint/998.wgsl.expected.msl
+++ b/test/tint/bug/tint/998.wgsl.expected.msl
@@ -32,7 +32,7 @@
 
 kernel void tint_symbol(const constant Constants* tint_symbol_1 [[buffer(0)]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  tint_private_vars.s.data[(*(tint_symbol_1)).zero] = 0u;
+  tint_private_vars.s.data[min((*(tint_symbol_1)).zero, 2u)] = 0u;
   return;
 }
 
diff --git a/test/tint/bug/tint/998.wgsl.expected.spvasm b/test/tint/bug/tint/998.wgsl.expected.spvasm
index 1e1eb43..dd1aae7 100644
--- a/test/tint/bug/tint/998.wgsl.expected.spvasm
+++ b/test/tint/bug/tint/998.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -52,12 +53,14 @@
          %18 = OpTypeFunction %void
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_uint = OpTypePointer Private %uint
        %main = OpFunction %void None %18
          %19 = OpLabel
          %20 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %23 = OpLoad %uint %20 None
-         %24 = OpAccessChain %_ptr_Private_uint %s %uint_0 %23
-               OpStore %24 %uint_0 None
+         %24 = OpExtInst %uint %25 UMin %23 %uint_2
+         %27 = OpAccessChain %_ptr_Private_uint %s %uint_0 %24
+               OpStore %27 %uint_0 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl
index 8052da9..1a6f1d8 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.dxc.hlsl
@@ -34,7 +34,7 @@
     uint x_33 = idx;
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl
index 8052da9..1a6f1d8 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.fxc.hlsl
@@ -34,7 +34,7 @@
     uint x_33 = idx;
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl
index 612522e..75f9991 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.glsl
@@ -21,8 +21,8 @@
       uint x_35 = idx;
       uint v = tint_div_u32(x_31, 2u);
       uint v_1 = tint_mod_u32(x_33, 2u);
-      uint v_2 = tint_mod_u32(x_35, 1u);
-      atomicExchange(wg[v][v_1][v_2], 0u);
+      uint v_2 = min(tint_mod_u32(x_35, 1u), 0u);
+      atomicExchange(wg[min(v, 2u)][min(v_1, 1u)][v_2], 0u);
       {
         idx = (idx + 1u);
       }
@@ -30,7 +30,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[2][1][0], 1u);
+  atomicExchange(wg[2u][1u][0u], 1u);
 }
 void compute_main_1() {
   uint x_57 = local_invocation_index_1;
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.dxc.hlsl
index cba56b2..9691040 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.dxc.hlsl
@@ -27,9 +27,9 @@
       uint x_35 = idx;
       uint v_1 = tint_div_u32(x_31, 2u);
       uint v_2 = tint_mod_u32(x_33, 2u);
-      uint v_3 = tint_mod_u32(x_35, 1u);
+      uint v_3 = min(tint_mod_u32(x_35, 1u), 0u);
       uint v_4 = 0u;
-      InterlockedExchange(wg[v_1][v_2][v_3], 0u, v_4);
+      InterlockedExchange(wg[min(v_1, 2u)][min(v_2, 1u)][v_3], 0u, v_4);
       {
         idx = (idx + 1u);
       }
@@ -38,7 +38,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_5 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_5);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_5);
 }
 
 void compute_main_1() {
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.fxc.hlsl
index cba56b2..9691040 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.ir.fxc.hlsl
@@ -27,9 +27,9 @@
       uint x_35 = idx;
       uint v_1 = tint_div_u32(x_31, 2u);
       uint v_2 = tint_mod_u32(x_33, 2u);
-      uint v_3 = tint_mod_u32(x_35, 1u);
+      uint v_3 = min(tint_mod_u32(x_35, 1u), 0u);
       uint v_4 = 0u;
-      InterlockedExchange(wg[v_1][v_2][v_3], 0u, v_4);
+      InterlockedExchange(wg[min(v_1, 2u)][min(v_2, 1u)][v_3], 0u, v_4);
       {
         idx = (idx + 1u);
       }
@@ -38,7 +38,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_5 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_5);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_5);
 }
 
 void compute_main_1() {
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 aea0d8d..f5103c1 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
@@ -18,6 +18,9 @@
   threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
 };
@@ -35,6 +38,7 @@
   idx = local_invocation_index_2;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (!((idx < 6u))) {
         break;
       }
@@ -43,7 +47,7 @@
       uint const x_35 = idx;
       uint const v = tint_div_u32(x_31, 2u);
       uint const v_1 = tint_mod_u32(x_33, 2u);
-      atomic_store_explicit((&(*tint_module_vars.wg)[v][v_1][tint_mod_u32(x_35, 1u)]), 0u, memory_order_relaxed);
+      atomic_store_explicit((&(*tint_module_vars.wg)[min(v, 2u)][min(v_1, 1u)][min(tint_mod_u32(x_35, 1u), 0u)]), 0u, memory_order_relaxed);
       {
         idx = (idx + 1u);
       }
@@ -51,7 +55,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2u][1u][0u]), 1u, memory_order_relaxed);
 }
 
 void compute_main_1(tint_module_vars_struct tint_module_vars) {
@@ -64,6 +68,7 @@
     uint v_2 = 0u;
     v_2 = local_invocation_index_1_param;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 6u)) {
         break;
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
index b73f460..7b64813 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint local_invocation_index_1;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
   for(uint idx_1 = local_idx; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx_1 / 2u);
     uint const i_1 = (idx_1 % 2u);
     uint const i_2 = (idx_1 % 1u);
@@ -40,13 +44,14 @@
   uint idx = 0u;
   idx = local_invocation_index_2;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (!((idx < 6u))) {
       break;
     }
     uint const x_31 = idx;
     uint const x_33 = idx;
     uint const x_35 = idx;
-    atomic_store_explicit(&((*(tint_symbol_1))[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)]), 0u, memory_order_relaxed);
+    atomic_store_explicit(&((*(tint_symbol_1))[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)]), 0u, memory_order_relaxed);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm
index 50b8f43..c2a94e8 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.spvasm.expected.spvasm
@@ -4,6 +4,7 @@
 ; Bound: 98
 ; Schema: 0
                OpCapability Shader
+         %43 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %compute_main "compute_main" %compute_main_local_invocation_index_Input
                OpExecutionMode %compute_main LocalSize 1 1 1
@@ -53,10 +54,6 @@
        %bool = OpTypeBool
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
          %56 = OpTypeFunction %void
          %81 = OpTypeFunction %uint %uint %uint
 %compute_main_inner = OpFunction %void None %18
@@ -84,18 +81,21 @@
          %37 = OpFunctionCall %uint %tint_div_u32 %x_31 %uint_2
          %39 = OpFunctionCall %uint %tint_mod_u32 %x_33 %uint_2
          %41 = OpFunctionCall %uint %tint_mod_u32 %x_35 %uint_1
-         %42 = OpAccessChain %_ptr_Workgroup_uint %wg %37 %39 %41
-               OpAtomicStore %42 %uint_2 %uint_0 %uint_0
+         %42 = OpExtInst %uint %43 UMin %37 %uint_2
+         %44 = OpExtInst %uint %43 UMin %39 %uint_1
+         %45 = OpExtInst %uint %43 UMin %41 %uint_0
+         %46 = OpAccessChain %_ptr_Workgroup_uint %wg %42 %44 %45
+               OpAtomicStore %46 %uint_2 %uint_0 %uint_0
                OpBranch %24
          %24 = OpLabel
-         %45 = OpLoad %uint %idx None
-         %46 = OpIAdd %uint %45 %uint_1
-               OpStore %idx %46 None
+         %49 = OpLoad %uint %idx None
+         %50 = OpIAdd %uint %49 %uint_1
+               OpStore %idx %50 None
                OpBranch %25
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %49 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %int_0
-               OpAtomicStore %49 %uint_2 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2 %uint_1 %uint_0
+               OpAtomicStore %53 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
 %compute_main_1 = OpFunction %void None %56
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl
index 29be9bc..21b4cd5 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.glsl
@@ -18,7 +18,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[2][1][0], 1u);
+  atomicExchange(wg[2u][1u][0u], 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.dxc.hlsl
index 0489c10..a8d1191 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_3);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.fxc.hlsl
index 0489c10..a8d1191 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.ir.fxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_3);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
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 325a251..f1273b1 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
@@ -17,6 +17,9 @@
   threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
 };
@@ -26,6 +29,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 6u)) {
         break;
@@ -38,7 +42,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2u][1u][0u]), 1u, memory_order_relaxed);
 }
 
 kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl
index 4b15cfe..cdc5187 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 6u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx / 2u);
     uint const i_1 = (idx % 2u);
     uint const i_2 = (idx % 1u);
diff --git a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm
index 744f406..3cdfd0d 100644
--- a/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/aliased_arrays.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 48
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -34,11 +34,7 @@
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
      %uint_0 = OpConstant %uint 0
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
-         %44 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -66,13 +62,13 @@
                OpBranch %20
          %21 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %37 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %int_0
+         %37 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2 %uint_1 %uint_0
                OpAtomicStore %37 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %47 = OpFunctionCall %void %compute_main_inner %46
+%compute_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %43 = OpFunctionCall %void %compute_main_inner %42
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.dxc.hlsl
index 8ebaba5..5ca1452 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.dxc.hlsl
@@ -22,7 +22,7 @@
     }
     uint x_26 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[x_26], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(x_26, 3u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.fxc.hlsl
index 8ebaba5..5ca1452 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.fxc.hlsl
@@ -22,7 +22,7 @@
     }
     uint x_26 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[x_26], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(x_26, 3u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.glsl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.glsl
index 2569ee4..463a9c6 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.glsl
@@ -11,7 +11,7 @@
         break;
       }
       uint x_26 = idx;
-      atomicExchange(wg[x_26], 0u);
+      atomicExchange(wg[min(x_26, 3u)], 0u);
       {
         idx = (idx + 1u);
       }
@@ -19,7 +19,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[1], 1u);
+  atomicExchange(wg[1u], 1u);
 }
 void compute_main_1() {
   uint x_47 = local_invocation_index_1;
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.dxc.hlsl
index e0da11b..8677f59 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.dxc.hlsl
@@ -15,7 +15,7 @@
       }
       uint x_26 = idx;
       uint v = 0u;
-      InterlockedExchange(wg[x_26], 0u, v);
+      InterlockedExchange(wg[min(x_26, 3u)], 0u, v);
       {
         idx = (idx + 1u);
       }
@@ -24,7 +24,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg[int(1)], 1u, v_1);
+  InterlockedExchange(wg[1u], 1u, v_1);
 }
 
 void compute_main_1() {
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.fxc.hlsl
index e0da11b..8677f59 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.fxc.hlsl
@@ -15,7 +15,7 @@
       }
       uint x_26 = idx;
       uint v = 0u;
-      InterlockedExchange(wg[x_26], 0u, v);
+      InterlockedExchange(wg[min(x_26, 3u)], 0u, v);
       {
         idx = (idx + 1u);
       }
@@ -24,7 +24,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg[int(1)], 1u, v_1);
+  InterlockedExchange(wg[1u], 1u, v_1);
 }
 
 void compute_main_1() {
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 d66b4cd..7466113 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<atomic_uint, 4>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<atomic_uint, 4> tint_symbol;
 };
@@ -27,11 +30,12 @@
   idx = local_invocation_index_2;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (!((idx < 4u))) {
         break;
       }
       uint const x_26 = idx;
-      atomic_store_explicit((&(*tint_module_vars.wg)[x_26]), 0u, memory_order_relaxed);
+      atomic_store_explicit((&(*tint_module_vars.wg)[min(x_26, 3u)]), 0u, memory_order_relaxed);
       {
         idx = (idx + 1u);
       }
@@ -39,7 +43,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[1]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[1u]), 1u, memory_order_relaxed);
 }
 
 void compute_main_1(tint_module_vars_struct tint_module_vars) {
@@ -52,6 +56,7 @@
     uint v = 0u;
     v = local_invocation_index_1_param;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
index 1e3bac7..1494ffe 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint local_invocation_index_1;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<atomic_uint, 4>* const tint_symbol) {
   for(uint idx_1 = local_idx; (idx_1 < 4u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx_1;
     atomic_store_explicit(&((*(tint_symbol))[i]), 0u, memory_order_relaxed);
   }
@@ -30,11 +34,12 @@
   uint idx = 0u;
   idx = local_invocation_index_2;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (!((idx < 4u))) {
       break;
     }
     uint const x_26 = idx;
-    atomic_store_explicit(&((*(tint_symbol_1))[x_26]), 0u, memory_order_relaxed);
+    atomic_store_explicit(&((*(tint_symbol_1))[min(x_26, 3u)]), 0u, memory_order_relaxed);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/array.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/array/array.spvasm.expected.spvasm
index 022f17e..ec2dc67 100644
--- a/test/tint/builtins/atomicStore/array/array.spvasm.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/array.spvasm.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %compute_main "compute_main" %compute_main_local_invocation_index_Input
                OpExecutionMode %compute_main LocalSize 1 1 1
@@ -36,13 +37,12 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_0 = OpConstant %uint 0
        %bool = OpTypeBool
+     %uint_3 = OpConstant %uint 3
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
      %uint_2 = OpConstant %uint 2
      %uint_1 = OpConstant %uint 1
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %44 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %14
 %local_invocation_index_2 = OpFunctionParameter %uint
          %15 = OpLabel
@@ -63,58 +63,59 @@
                OpBranch %22
          %27 = OpLabel
        %x_26 = OpLoad %uint %idx None
-         %30 = OpAccessChain %_ptr_Workgroup_uint %wg %x_26
-               OpAtomicStore %30 %uint_2 %uint_0 %uint_0
+         %30 = OpExtInst %uint %31 UMin %x_26 %uint_3
+         %33 = OpAccessChain %_ptr_Workgroup_uint %wg %30
+               OpAtomicStore %33 %uint_2 %uint_0 %uint_0
                OpBranch %20
          %20 = OpLabel
-         %34 = OpLoad %uint %idx None
-         %35 = OpIAdd %uint %34 %uint_1
-               OpStore %idx %35 None
+         %37 = OpLoad %uint %idx None
+         %38 = OpIAdd %uint %37 %uint_1
+               OpStore %idx %38 None
                OpBranch %21
          %22 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %39 = OpAccessChain %_ptr_Workgroup_uint %wg %int_1
-               OpAtomicStore %39 %uint_2 %uint_0 %uint_1
+         %42 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
+               OpAtomicStore %42 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main_1 = OpFunction %void None %44
-         %45 = OpLabel
+%compute_main_1 = OpFunction %void None %45
+         %46 = OpLabel
        %x_47 = OpLoad %uint %local_invocation_index_1 None
-         %47 = OpFunctionCall %void %compute_main_inner %x_47
+         %48 = OpFunctionCall %void %compute_main_inner %x_47
                OpReturn
                OpFunctionEnd
 %compute_main_inner_0 = OpFunction %void None %14
 %local_invocation_index_1_param = OpFunctionParameter %uint
-         %50 = OpLabel
-               OpBranch %51
          %51 = OpLabel
-               OpBranch %54
-         %54 = OpLabel
-         %56 = OpPhi %uint %local_invocation_index_1_param %51 %57 %53
-               OpLoopMerge %55 %53 None
                OpBranch %52
          %52 = OpLabel
-         %58 = OpUGreaterThanEqual %bool %56 %uint_4
-               OpSelectionMerge %59 None
-               OpBranchConditional %58 %60 %59
-         %60 = OpLabel
                OpBranch %55
-         %59 = OpLabel
-         %61 = OpAccessChain %_ptr_Workgroup_uint %wg %56
-               OpAtomicStore %61 %uint_2 %uint_0 %uint_0
+         %55 = OpLabel
+         %57 = OpPhi %uint %local_invocation_index_1_param %52 %58 %54
+               OpLoopMerge %56 %54 None
                OpBranch %53
          %53 = OpLabel
-         %57 = OpIAdd %uint %56 %uint_1
+         %59 = OpUGreaterThanEqual %bool %57 %uint_4
+               OpSelectionMerge %60 None
+               OpBranchConditional %59 %61 %60
+         %61 = OpLabel
+               OpBranch %56
+         %60 = OpLabel
+         %62 = OpAccessChain %_ptr_Workgroup_uint %wg %57
+               OpAtomicStore %62 %uint_2 %uint_0 %uint_0
                OpBranch %54
-         %55 = OpLabel
+         %54 = OpLabel
+         %58 = OpIAdd %uint %57 %uint_1
+               OpBranch %55
+         %56 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
                OpStore %local_invocation_index_1 %local_invocation_index_1_param None
-         %64 = OpFunctionCall %void %compute_main_1
+         %65 = OpFunctionCall %void %compute_main_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %66 = OpLabel
-         %67 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %68 = OpFunctionCall %void %compute_main_inner_0 %67
+%compute_main = OpFunction %void None %45
+         %67 = OpLabel
+         %68 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %69 = OpFunctionCall %void %compute_main_inner_0 %68
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl
index 0b2b938..5a60b91 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.glsl
@@ -18,7 +18,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[1], 1u);
+  atomicExchange(wg[1u], 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.dxc.hlsl
index 4413c75..4631109 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(1)], 1u, v_3);
+  InterlockedExchange(wg[1u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.fxc.hlsl
index 4413c75..4631109 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.fxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(1)], 1u, v_3);
+  InterlockedExchange(wg[1u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
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 04f2299..b35d5d0 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<atomic_uint, 4>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<atomic_uint, 4> tint_symbol;
 };
@@ -26,6 +29,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -38,7 +42,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[1]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[1u]), 1u, memory_order_relaxed);
 }
 
 kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl
index b705e55..61cb568 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<atomic_uint, 4>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     atomic_store_explicit(&((*(tint_symbol))[i]), 0u, memory_order_relaxed);
   }
diff --git a/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm
index 20b912e..1feba90 100644
--- a/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -29,9 +29,7 @@
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %37 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %11
 %tint_local_index = OpFunctionParameter %uint
          %12 = OpLabel
@@ -57,13 +55,13 @@
                OpBranch %16
          %17 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpAccessChain %_ptr_Workgroup_uint %wg %int_1
+         %32 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_1
                OpAtomicStore %32 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %40 = OpFunctionCall %void %compute_main_inner %39
+%compute_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %38 = OpFunctionCall %void %compute_main_inner %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl
index 8052da9..1a6f1d8 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.dxc.hlsl
@@ -34,7 +34,7 @@
     uint x_33 = idx;
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl
index 8052da9..1a6f1d8 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.fxc.hlsl
@@ -34,7 +34,7 @@
     uint x_33 = idx;
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)], 0u, atomic_result_1);
+    InterlockedExchange(wg[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl
index 612522e..75f9991 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.glsl
@@ -21,8 +21,8 @@
       uint x_35 = idx;
       uint v = tint_div_u32(x_31, 2u);
       uint v_1 = tint_mod_u32(x_33, 2u);
-      uint v_2 = tint_mod_u32(x_35, 1u);
-      atomicExchange(wg[v][v_1][v_2], 0u);
+      uint v_2 = min(tint_mod_u32(x_35, 1u), 0u);
+      atomicExchange(wg[min(v, 2u)][min(v_1, 1u)][v_2], 0u);
       {
         idx = (idx + 1u);
       }
@@ -30,7 +30,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[2][1][0], 1u);
+  atomicExchange(wg[2u][1u][0u], 1u);
 }
 void compute_main_1() {
   uint x_57 = local_invocation_index_1;
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.dxc.hlsl
index cba56b2..9691040 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.dxc.hlsl
@@ -27,9 +27,9 @@
       uint x_35 = idx;
       uint v_1 = tint_div_u32(x_31, 2u);
       uint v_2 = tint_mod_u32(x_33, 2u);
-      uint v_3 = tint_mod_u32(x_35, 1u);
+      uint v_3 = min(tint_mod_u32(x_35, 1u), 0u);
       uint v_4 = 0u;
-      InterlockedExchange(wg[v_1][v_2][v_3], 0u, v_4);
+      InterlockedExchange(wg[min(v_1, 2u)][min(v_2, 1u)][v_3], 0u, v_4);
       {
         idx = (idx + 1u);
       }
@@ -38,7 +38,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_5 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_5);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_5);
 }
 
 void compute_main_1() {
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.fxc.hlsl
index cba56b2..9691040 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.fxc.hlsl
@@ -27,9 +27,9 @@
       uint x_35 = idx;
       uint v_1 = tint_div_u32(x_31, 2u);
       uint v_2 = tint_mod_u32(x_33, 2u);
-      uint v_3 = tint_mod_u32(x_35, 1u);
+      uint v_3 = min(tint_mod_u32(x_35, 1u), 0u);
       uint v_4 = 0u;
-      InterlockedExchange(wg[v_1][v_2][v_3], 0u, v_4);
+      InterlockedExchange(wg[min(v_1, 2u)][min(v_2, 1u)][v_3], 0u, v_4);
       {
         idx = (idx + 1u);
       }
@@ -38,7 +38,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_5 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_5);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_5);
 }
 
 void compute_main_1() {
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 aea0d8d..f5103c1 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.ir.msl
@@ -18,6 +18,9 @@
   threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
 };
@@ -35,6 +38,7 @@
   idx = local_invocation_index_2;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (!((idx < 6u))) {
         break;
       }
@@ -43,7 +47,7 @@
       uint const x_35 = idx;
       uint const v = tint_div_u32(x_31, 2u);
       uint const v_1 = tint_mod_u32(x_33, 2u);
-      atomic_store_explicit((&(*tint_module_vars.wg)[v][v_1][tint_mod_u32(x_35, 1u)]), 0u, memory_order_relaxed);
+      atomic_store_explicit((&(*tint_module_vars.wg)[min(v, 2u)][min(v_1, 1u)][min(tint_mod_u32(x_35, 1u), 0u)]), 0u, memory_order_relaxed);
       {
         idx = (idx + 1u);
       }
@@ -51,7 +55,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2u][1u][0u]), 1u, memory_order_relaxed);
 }
 
 void compute_main_1(tint_module_vars_struct tint_module_vars) {
@@ -64,6 +68,7 @@
     uint v_2 = 0u;
     v_2 = local_invocation_index_1_param;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_3 = v_2;
       if ((v_3 >= 6u)) {
         break;
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
index b73f460..7b64813 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint local_invocation_index_1;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
   for(uint idx_1 = local_idx; (idx_1 < 6u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx_1 / 2u);
     uint const i_1 = (idx_1 % 2u);
     uint const i_2 = (idx_1 % 1u);
@@ -40,13 +44,14 @@
   uint idx = 0u;
   idx = local_invocation_index_2;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (!((idx < 6u))) {
       break;
     }
     uint const x_31 = idx;
     uint const x_33 = idx;
     uint const x_35 = idx;
-    atomic_store_explicit(&((*(tint_symbol_1))[tint_div(x_31, 2u)][tint_mod(x_33, 2u)][tint_mod(x_35, 1u)]), 0u, memory_order_relaxed);
+    atomic_store_explicit(&((*(tint_symbol_1))[min(tint_div(x_31, 2u), 2u)][min(tint_mod(x_33, 2u), 1u)][min(tint_mod(x_35, 1u), 0u)]), 0u, memory_order_relaxed);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm
index 50b8f43..c2a94e8 100644
--- a/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/arrays.spvasm.expected.spvasm
@@ -4,6 +4,7 @@
 ; Bound: 98
 ; Schema: 0
                OpCapability Shader
+         %43 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %compute_main "compute_main" %compute_main_local_invocation_index_Input
                OpExecutionMode %compute_main LocalSize 1 1 1
@@ -53,10 +54,6 @@
        %bool = OpTypeBool
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
          %56 = OpTypeFunction %void
          %81 = OpTypeFunction %uint %uint %uint
 %compute_main_inner = OpFunction %void None %18
@@ -84,18 +81,21 @@
          %37 = OpFunctionCall %uint %tint_div_u32 %x_31 %uint_2
          %39 = OpFunctionCall %uint %tint_mod_u32 %x_33 %uint_2
          %41 = OpFunctionCall %uint %tint_mod_u32 %x_35 %uint_1
-         %42 = OpAccessChain %_ptr_Workgroup_uint %wg %37 %39 %41
-               OpAtomicStore %42 %uint_2 %uint_0 %uint_0
+         %42 = OpExtInst %uint %43 UMin %37 %uint_2
+         %44 = OpExtInst %uint %43 UMin %39 %uint_1
+         %45 = OpExtInst %uint %43 UMin %41 %uint_0
+         %46 = OpAccessChain %_ptr_Workgroup_uint %wg %42 %44 %45
+               OpAtomicStore %46 %uint_2 %uint_0 %uint_0
                OpBranch %24
          %24 = OpLabel
-         %45 = OpLoad %uint %idx None
-         %46 = OpIAdd %uint %45 %uint_1
-               OpStore %idx %46 None
+         %49 = OpLoad %uint %idx None
+         %50 = OpIAdd %uint %49 %uint_1
+               OpStore %idx %50 None
                OpBranch %25
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %49 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %int_0
-               OpAtomicStore %49 %uint_2 %uint_0 %uint_1
+         %53 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2 %uint_1 %uint_0
+               OpAtomicStore %53 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
 %compute_main_1 = OpFunction %void None %56
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl
index 29be9bc..21b4cd5 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.glsl
@@ -18,7 +18,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[2][1][0], 1u);
+  atomicExchange(wg[2u][1u][0u], 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.dxc.hlsl
index 0489c10..a8d1191 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_3);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.fxc.hlsl
index 0489c10..a8d1191 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.fxc.hlsl
@@ -23,7 +23,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(2)][int(1)][int(0)], 1u, v_3);
+  InterlockedExchange(wg[2u][1u][0u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
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 325a251..f1273b1 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3> tint_symbol;
 };
@@ -26,6 +29,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 6u)) {
         break;
@@ -38,7 +42,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[2][1][0]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[2u][1u][0u]), 1u, memory_order_relaxed);
 }
 
 kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl
index 4b15cfe..cdc5187 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<tint_array<atomic_uint, 1>, 2>, 3>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 6u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx / 2u);
     uint const i_1 = (idx % 2u);
     uint const i_2 = (idx % 1u);
diff --git a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm
index 744f406..3cdfd0d 100644
--- a/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm
+++ b/test/tint/builtins/atomicStore/array/arrays.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 48
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -34,11 +34,7 @@
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
      %uint_0 = OpConstant %uint 0
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
-      %int_0 = OpConstant %int 0
-         %44 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %15
 %tint_local_index = OpFunctionParameter %uint
          %16 = OpLabel
@@ -66,13 +62,13 @@
                OpBranch %20
          %21 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %37 = OpAccessChain %_ptr_Workgroup_uint %wg %int_2 %int_1 %int_0
+         %37 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2 %uint_1 %uint_0
                OpAtomicStore %37 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %47 = OpFunctionCall %void %compute_main_inner %46
+%compute_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %43 = OpFunctionCall %void %compute_main_inner %42
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.dxc.hlsl
index c88c8c6..986e32e 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.dxc.hlsl
@@ -29,10 +29,10 @@
       break;
     }
     uint x_28 = idx;
-    wg[x_28].x = 0;
+    wg[min(x_28, 9u)].x = 0;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[x_28].a, 0u, atomic_result_1);
-    wg[x_28].y = 0u;
+    InterlockedExchange(wg[min(x_28, 9u)].a, 0u, atomic_result_1);
+    wg[min(x_28, 9u)].y = 0u;
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.fxc.hlsl
index c88c8c6..986e32e 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.fxc.hlsl
@@ -29,10 +29,10 @@
       break;
     }
     uint x_28 = idx;
-    wg[x_28].x = 0;
+    wg[min(x_28, 9u)].x = 0;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg[x_28].a, 0u, atomic_result_1);
-    wg[x_28].y = 0u;
+    InterlockedExchange(wg[min(x_28, 9u)].a, 0u, atomic_result_1);
+    wg[min(x_28, 9u)].y = 0u;
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.glsl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.glsl
index 7e232fc..7ca77c5 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.glsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.glsl
@@ -18,9 +18,9 @@
         break;
       }
       uint x_28 = idx;
-      wg[x_28].x = 0;
-      atomicExchange(wg[x_28].a, 0u);
-      wg[x_28].y = 0u;
+      wg[min(x_28, 9u)].x = 0;
+      atomicExchange(wg[min(x_28, 9u)].a, 0u);
+      wg[min(x_28, 9u)].y = 0u;
       {
         idx = (idx + 1u);
       }
@@ -28,7 +28,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[4].a, 1u);
+  atomicExchange(wg[4u].a, 1u);
 }
 void compute_main_1() {
   uint x_53 = local_invocation_index_1;
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.dxc.hlsl
index b6b31b4..6bd54f9 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.dxc.hlsl
@@ -20,10 +20,10 @@
         break;
       }
       uint x_28 = idx;
-      wg[x_28].x = int(0);
+      wg[min(x_28, 9u)].x = int(0);
       uint v = 0u;
-      InterlockedExchange(wg[x_28].a, 0u, v);
-      wg[x_28].y = 0u;
+      InterlockedExchange(wg[min(x_28, 9u)].a, 0u, v);
+      wg[min(x_28, 9u)].y = 0u;
       {
         idx = (idx + 1u);
       }
@@ -32,7 +32,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg[int(4)].a, 1u, v_1);
+  InterlockedExchange(wg[4u].a, 1u, v_1);
 }
 
 void compute_main_1() {
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.fxc.hlsl
index b6b31b4..6bd54f9 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.ir.fxc.hlsl
@@ -20,10 +20,10 @@
         break;
       }
       uint x_28 = idx;
-      wg[x_28].x = int(0);
+      wg[min(x_28, 9u)].x = int(0);
       uint v = 0u;
-      InterlockedExchange(wg[x_28].a, 0u, v);
-      wg[x_28].y = 0u;
+      InterlockedExchange(wg[min(x_28, 9u)].a, 0u, v);
+      wg[min(x_28, 9u)].y = 0u;
       {
         idx = (idx + 1u);
       }
@@ -32,7 +32,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg[int(4)].a, 1u, v_1);
+  InterlockedExchange(wg[4u].a, 1u, v_1);
 }
 
 void compute_main_1() {
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 ee08efb..4d00e1a 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
@@ -24,6 +24,9 @@
   threadgroup tint_array<S_atomic, 10>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S_atomic, 10> tint_symbol;
 };
@@ -33,13 +36,14 @@
   idx = local_invocation_index_2;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       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;
+      (*tint_module_vars.wg)[min(x_28, 9u)].x = 0;
+      atomic_store_explicit((&(*tint_module_vars.wg)[min(x_28, 9u)].a), 0u, memory_order_relaxed);
+      (*tint_module_vars.wg)[min(x_28, 9u)].y = 0u;
       {
         idx = (idx + 1u);
       }
@@ -47,7 +51,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[4].a), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[4u].a), 1u, memory_order_relaxed);
 }
 
 void compute_main_1(tint_module_vars_struct tint_module_vars) {
@@ -60,6 +64,7 @@
     uint v = 0u;
     v = local_invocation_index_1_param;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_1 = v;
       if ((v_1 >= 10u)) {
         break;
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
index 7942a90..e6bdb66 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint local_invocation_index_1;
 };
@@ -26,6 +29,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S_atomic, 10>* const tint_symbol) {
   for(uint idx_1 = local_idx; (idx_1 < 10u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx_1;
     (*(tint_symbol))[i].x = 0;
     atomic_store_explicit(&((*(tint_symbol))[i].a), 0u, memory_order_relaxed);
@@ -44,13 +48,14 @@
   uint idx = 0u;
   idx = local_invocation_index_2;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (!((idx < 10u))) {
       break;
     }
     uint const x_28 = idx;
-    (*(tint_symbol_1))[x_28].x = 0;
-    atomic_store_explicit(&((*(tint_symbol_1))[x_28].a), 0u, memory_order_relaxed);
-    (*(tint_symbol_1))[x_28].y = 0u;
+    (*(tint_symbol_1))[min(x_28, 9u)].x = 0;
+    atomic_store_explicit(&((*(tint_symbol_1))[min(x_28, 9u)].a), 0u, memory_order_relaxed);
+    (*(tint_symbol_1))[min(x_28, 9u)].y = 0u;
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.spvasm
index f96a08f..e2b1db1 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.spvasm
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.spvasm.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 77
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %compute_main "compute_main" %compute_main_local_invocation_index_Input
                OpExecutionMode %compute_main LocalSize 1 1 1
@@ -45,6 +46,7 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_0 = OpConstant %uint 0
        %bool = OpTypeBool
+     %uint_9 = OpConstant %uint 9
 %_ptr_Workgroup_int = OpTypePointer Workgroup %int
       %int_0 = OpConstant %int 0
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
@@ -52,8 +54,8 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
    %uint_264 = OpConstant %uint 264
-      %int_4 = OpConstant %int 4
-         %50 = OpTypeFunction %void
+     %uint_4 = OpConstant %uint 4
+         %55 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %16
 %local_invocation_index_2 = OpFunctionParameter %uint
          %17 = OpLabel
@@ -74,66 +76,69 @@
                OpBranch %24
          %29 = OpLabel
        %x_28 = OpLoad %uint %idx None
-         %32 = OpAccessChain %_ptr_Workgroup_int %wg %x_28 %uint_0
-               OpStore %32 %int_0 None
-         %35 = OpAccessChain %_ptr_Workgroup_uint %wg %x_28 %uint_1
-               OpAtomicStore %35 %uint_2 %uint_0 %uint_0
-         %40 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %x_28 %uint_2
-               OpStore %40 %uint_0 None
+         %32 = OpExtInst %uint %33 UMin %x_28 %uint_9
+         %35 = OpAccessChain %_ptr_Workgroup_int %wg %32 %uint_0
+               OpStore %35 %int_0 None
+         %38 = OpExtInst %uint %33 UMin %x_28 %uint_9
+         %39 = OpAccessChain %_ptr_Workgroup_uint %wg %38 %uint_1
+               OpAtomicStore %39 %uint_2 %uint_0 %uint_0
+         %44 = OpExtInst %uint %33 UMin %x_28 %uint_9
+         %45 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %44 %uint_2
+               OpStore %45 %uint_0 None
                OpBranch %22
          %22 = OpLabel
-         %42 = OpLoad %uint %idx None
-         %43 = OpIAdd %uint %42 %uint_1
-               OpStore %idx %43 None
+         %47 = OpLoad %uint %idx None
+         %48 = OpIAdd %uint %47 %uint_1
+               OpStore %idx %48 None
                OpBranch %23
          %24 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %46 = OpAccessChain %_ptr_Workgroup_uint %wg %int_4 %uint_1
-               OpAtomicStore %46 %uint_2 %uint_0 %uint_1
+         %51 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_4 %uint_1
+               OpAtomicStore %51 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main_1 = OpFunction %void None %50
-         %51 = OpLabel
+%compute_main_1 = OpFunction %void None %55
+         %56 = OpLabel
        %x_53 = OpLoad %uint %local_invocation_index_1 None
-         %53 = OpFunctionCall %void %compute_main_inner %x_53
+         %58 = OpFunctionCall %void %compute_main_inner %x_53
                OpReturn
                OpFunctionEnd
 %compute_main_inner_0 = OpFunction %void None %16
 %local_invocation_index_1_param = OpFunctionParameter %uint
-         %56 = OpLabel
-               OpBranch %57
-         %57 = OpLabel
-               OpBranch %60
-         %60 = OpLabel
-         %62 = OpPhi %uint %local_invocation_index_1_param %57 %63 %59
-               OpLoopMerge %61 %59 None
-               OpBranch %58
-         %58 = OpLabel
-         %64 = OpUGreaterThanEqual %bool %62 %uint_10
-               OpSelectionMerge %65 None
-               OpBranchConditional %64 %66 %65
-         %66 = OpLabel
-               OpBranch %61
-         %65 = OpLabel
-         %67 = OpAccessChain %_ptr_Workgroup_int %wg %62 %uint_0
-               OpStore %67 %int_0 None
-         %68 = OpAccessChain %_ptr_Workgroup_uint %wg %62 %uint_1
-               OpAtomicStore %68 %uint_2 %uint_0 %uint_0
-         %70 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %62 %uint_2
-               OpStore %70 %uint_0 None
-               OpBranch %59
-         %59 = OpLabel
-         %63 = OpIAdd %uint %62 %uint_1
-               OpBranch %60
          %61 = OpLabel
+               OpBranch %62
+         %62 = OpLabel
+               OpBranch %65
+         %65 = OpLabel
+         %67 = OpPhi %uint %local_invocation_index_1_param %62 %68 %64
+               OpLoopMerge %66 %64 None
+               OpBranch %63
+         %63 = OpLabel
+         %69 = OpUGreaterThanEqual %bool %67 %uint_10
+               OpSelectionMerge %70 None
+               OpBranchConditional %69 %71 %70
+         %71 = OpLabel
+               OpBranch %66
+         %70 = OpLabel
+         %72 = OpAccessChain %_ptr_Workgroup_int %wg %67 %uint_0
+               OpStore %72 %int_0 None
+         %73 = OpAccessChain %_ptr_Workgroup_uint %wg %67 %uint_1
+               OpAtomicStore %73 %uint_2 %uint_0 %uint_0
+         %75 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %67 %uint_2
+               OpStore %75 %uint_0 None
+               OpBranch %64
+         %64 = OpLabel
+         %68 = OpIAdd %uint %67 %uint_1
+               OpBranch %65
+         %66 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
                OpStore %local_invocation_index_1 %local_invocation_index_1_param None
-         %72 = OpFunctionCall %void %compute_main_1
+         %77 = OpFunctionCall %void %compute_main_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %50
-         %74 = OpLabel
-         %75 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %76 = OpFunctionCall %void %compute_main_inner_0 %75
+%compute_main = OpFunction %void None %55
+         %79 = OpLabel
+         %80 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %81 = OpFunctionCall %void %compute_main_inner_0 %80
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl
index 7979a57..412ca89 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.glsl
@@ -27,7 +27,7 @@
     }
   }
   barrier();
-  atomicExchange(wg[4].a, 1u);
+  atomicExchange(wg[4u].a, 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.dxc.hlsl
index b851f8d..390a4b0 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(4)].a, 1u, v_3);
+  InterlockedExchange(wg[4u].a, 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.fxc.hlsl
index b851f8d..390a4b0 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.ir.fxc.hlsl
@@ -31,7 +31,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg[int(4)].a, 1u, v_3);
+  InterlockedExchange(wg[4u].a, 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
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 a4f77ac..a20354c 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
@@ -23,6 +23,9 @@
   threadgroup tint_array<S, 10>* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   tint_array<S, 10> tint_symbol;
 };
@@ -32,6 +35,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 10u)) {
         break;
@@ -46,7 +50,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg)[4].a), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg)[4u].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)]]) {
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl
index a4a3bb9..4dfe73a 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   int x;
   atomic_uint a;
@@ -22,6 +25,7 @@
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<S, 10>* const tint_symbol) {
   for(uint idx = local_idx; (idx < 10u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol))[i].x = 0;
     atomic_store_explicit(&((*(tint_symbol))[i].a), 0u, memory_order_relaxed);
diff --git a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm
index db937a5..d2d42b0 100644
--- a/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm
+++ b/test/tint/builtins/atomicStore/struct/array_of_struct.wgsl.expected.spvasm
@@ -41,7 +41,7 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
    %uint_264 = OpConstant %uint 264
-      %int_4 = OpConstant %int 4
+     %uint_4 = OpConstant %uint 4
          %43 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %13
 %tint_local_index = OpFunctionParameter %uint
@@ -72,7 +72,7 @@
                OpBranch %18
          %19 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %39 = OpAccessChain %_ptr_Workgroup_uint %wg %int_4 %uint_1
+         %39 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_4 %uint_1
                OpAtomicStore %39 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.dxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.dxc.hlsl
index ec5fa72..82af5f6 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.dxc.hlsl
@@ -34,7 +34,7 @@
     }
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg.a[x_35], 0u, atomic_result_1);
+    InterlockedExchange(wg.a[min(x_35, 9u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.fxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.fxc.hlsl
index ec5fa72..82af5f6 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.fxc.hlsl
@@ -34,7 +34,7 @@
     }
     uint x_35 = idx;
     uint atomic_result_1 = 0u;
-    InterlockedExchange(wg.a[x_35], 0u, atomic_result_1);
+    InterlockedExchange(wg.a[min(x_35, 9u)], 0u, atomic_result_1);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.glsl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.glsl
index 8cf4790..7d6f072 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.glsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.glsl
@@ -20,7 +20,7 @@
         break;
       }
       uint x_35 = idx;
-      atomicExchange(wg.a[x_35], 0u);
+      atomicExchange(wg.a[min(x_35, 9u)], 0u);
       {
         idx = (idx + 1u);
       }
@@ -28,7 +28,7 @@
     }
   }
   barrier();
-  atomicExchange(wg.a[4], 1u);
+  atomicExchange(wg.a[4u], 1u);
 }
 void compute_main_1() {
   uint x_53 = local_invocation_index_1;
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.dxc.hlsl
index b667593..35b24ab 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
       }
       uint x_35 = idx;
       uint v = 0u;
-      InterlockedExchange(wg.a[x_35], 0u, v);
+      InterlockedExchange(wg.a[min(x_35, 9u)], 0u, v);
       {
         idx = (idx + 1u);
       }
@@ -32,7 +32,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg.a[int(4)], 1u, v_1);
+  InterlockedExchange(wg.a[4u], 1u, v_1);
 }
 
 void compute_main_1() {
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.fxc.hlsl
index b667593..35b24ab 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.ir.fxc.hlsl
@@ -23,7 +23,7 @@
       }
       uint x_35 = idx;
       uint v = 0u;
-      InterlockedExchange(wg.a[x_35], 0u, v);
+      InterlockedExchange(wg.a[min(x_35, 9u)], 0u, v);
       {
         idx = (idx + 1u);
       }
@@ -32,7 +32,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_1 = 0u;
-  InterlockedExchange(wg.a[int(4)], 1u, v_1);
+  InterlockedExchange(wg.a[4u], 1u, v_1);
 }
 
 void compute_main_1() {
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 d2cd0a2..14b0564 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
@@ -24,6 +24,9 @@
   threadgroup S_atomic* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   S_atomic tint_symbol;
 };
@@ -35,11 +38,12 @@
   idx = local_invocation_index_2;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (!((idx < 10u))) {
         break;
       }
       uint const x_35 = idx;
-      atomic_store_explicit((&(*tint_module_vars.wg).a[x_35]), 0u, memory_order_relaxed);
+      atomic_store_explicit((&(*tint_module_vars.wg).a[min(x_35, 9u)]), 0u, memory_order_relaxed);
       {
         idx = (idx + 1u);
       }
@@ -47,7 +51,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg).a[4]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg).a[4u]), 1u, memory_order_relaxed);
 }
 
 void compute_main_1(tint_module_vars_struct tint_module_vars) {
@@ -64,6 +68,7 @@
     uint v = 0u;
     v = local_invocation_index_1_param;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1)
       uint const v_1 = v;
       if ((v_1 >= 10u)) {
         break;
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
index 3c9a457..e2727fc 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint local_invocation_index_1;
 };
@@ -30,6 +33,7 @@
     (*(tint_symbol)).y = 0u;
   }
   for(uint idx_1 = local_idx; (idx_1 < 10u); idx_1 = (idx_1 + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx_1;
     atomic_store_explicit(&((*(tint_symbol)).a[i]), 0u, memory_order_relaxed);
   }
@@ -48,11 +52,12 @@
   (*(tint_symbol_1)).y = 0u;
   idx = local_invocation_index_2;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false_1);
     if (!((idx < 10u))) {
       break;
     }
     uint const x_35 = idx;
-    atomic_store_explicit(&((*(tint_symbol_1)).a[x_35]), 0u, memory_order_relaxed);
+    atomic_store_explicit(&((*(tint_symbol_1)).a[min(x_35, 9u)]), 0u, memory_order_relaxed);
     {
       idx = (idx + 1u);
     }
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.spvasm b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.spvasm
index dcda55c..3ec2b71 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.spvasm
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.spvasm.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 80
+; Bound: 83
 ; Schema: 0
                OpCapability Shader
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %compute_main "compute_main" %compute_main_local_invocation_index_Input
                OpExecutionMode %compute_main LocalSize 1 1 1
@@ -49,11 +50,12 @@
 %_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
      %uint_2 = OpConstant %uint 2
        %bool = OpTypeBool
+     %uint_9 = OpConstant %uint 9
 %_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
      %uint_1 = OpConstant %uint 1
    %uint_264 = OpConstant %uint 264
-      %int_4 = OpConstant %int 4
-         %50 = OpTypeFunction %void
+     %uint_4 = OpConstant %uint 4
+         %53 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %16
 %local_invocation_index_2 = OpFunctionParameter %uint
          %17 = OpLabel
@@ -78,68 +80,69 @@
                OpBranch %30
          %35 = OpLabel
        %x_35 = OpLoad %uint %idx None
-         %38 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %x_35
-               OpAtomicStore %38 %uint_2 %uint_0 %uint_0
+         %38 = OpExtInst %uint %39 UMin %x_35 %uint_9
+         %41 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %38
+               OpAtomicStore %41 %uint_2 %uint_0 %uint_0
                OpBranch %28
          %28 = OpLabel
-         %42 = OpLoad %uint %idx None
-         %43 = OpIAdd %uint %42 %uint_1
-               OpStore %idx %43 None
+         %45 = OpLoad %uint %idx None
+         %46 = OpIAdd %uint %45 %uint_1
+               OpStore %idx %46 None
                OpBranch %29
          %30 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %46 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %int_4
-               OpAtomicStore %46 %uint_2 %uint_0 %uint_1
+         %49 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %uint_4
+               OpAtomicStore %49 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
-%compute_main_1 = OpFunction %void None %50
-         %51 = OpLabel
+%compute_main_1 = OpFunction %void None %53
+         %54 = OpLabel
        %x_53 = OpLoad %uint %local_invocation_index_1 None
-         %53 = OpFunctionCall %void %compute_main_inner %x_53
+         %56 = OpFunctionCall %void %compute_main_inner %x_53
                OpReturn
                OpFunctionEnd
 %compute_main_inner_0 = OpFunction %void None %16
 %local_invocation_index_1_param = OpFunctionParameter %uint
-         %56 = OpLabel
-         %57 = OpULessThan %bool %local_invocation_index_1_param %uint_1
-               OpSelectionMerge %58 None
-               OpBranchConditional %57 %59 %58
          %59 = OpLabel
-         %60 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
-               OpStore %60 %int_0 None
-         %61 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2
-               OpStore %61 %uint_0 None
-               OpBranch %58
-         %58 = OpLabel
-               OpBranch %62
+         %60 = OpULessThan %bool %local_invocation_index_1_param %uint_1
+               OpSelectionMerge %61 None
+               OpBranchConditional %60 %62 %61
          %62 = OpLabel
+         %63 = OpAccessChain %_ptr_Workgroup_int %wg %uint_0
+               OpStore %63 %int_0 None
+         %64 = OpAccessChain %_ptr_Workgroup_uint %wg %uint_2
+               OpStore %64 %uint_0 None
+               OpBranch %61
+         %61 = OpLabel
                OpBranch %65
          %65 = OpLabel
-         %67 = OpPhi %uint %local_invocation_index_1_param %62 %68 %64
-               OpLoopMerge %66 %64 None
-               OpBranch %63
-         %63 = OpLabel
-         %69 = OpUGreaterThanEqual %bool %67 %uint_10
-               OpSelectionMerge %70 None
-               OpBranchConditional %69 %71 %70
-         %71 = OpLabel
+               OpBranch %68
+         %68 = OpLabel
+         %70 = OpPhi %uint %local_invocation_index_1_param %65 %71 %67
+               OpLoopMerge %69 %67 None
                OpBranch %66
-         %70 = OpLabel
-         %72 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %67
-               OpAtomicStore %72 %uint_2 %uint_0 %uint_0
-               OpBranch %64
-         %64 = OpLabel
-         %68 = OpIAdd %uint %67 %uint_1
-               OpBranch %65
          %66 = OpLabel
+         %72 = OpUGreaterThanEqual %bool %70 %uint_10
+               OpSelectionMerge %73 None
+               OpBranchConditional %72 %74 %73
+         %74 = OpLabel
+               OpBranch %69
+         %73 = OpLabel
+         %75 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %70
+               OpAtomicStore %75 %uint_2 %uint_0 %uint_0
+               OpBranch %67
+         %67 = OpLabel
+         %71 = OpIAdd %uint %70 %uint_1
+               OpBranch %68
+         %69 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
                OpStore %local_invocation_index_1 %local_invocation_index_1_param None
-         %75 = OpFunctionCall %void %compute_main_1
+         %78 = OpFunctionCall %void %compute_main_1
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %50
-         %77 = OpLabel
-         %78 = OpLoad %uint %compute_main_local_invocation_index_Input None
-         %79 = OpFunctionCall %void %compute_main_inner_0 %78
+%compute_main = OpFunction %void None %53
+         %80 = OpLabel
+         %81 = OpLoad %uint %compute_main_local_invocation_index_Input None
+         %82 = OpFunctionCall %void %compute_main_inner_0 %81
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl
index fb8969af..2ce0d4d 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.glsl
@@ -29,7 +29,7 @@
     }
   }
   barrier();
-  atomicExchange(wg.a[4], 1u);
+  atomicExchange(wg.a[4u], 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.dxc.hlsl
index 8d27cdd..1ef058b 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.dxc.hlsl
@@ -33,7 +33,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg.a[int(4)], 1u, v_3);
+  InterlockedExchange(wg.a[4u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.fxc.hlsl
index 8d27cdd..1ef058b 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.ir.fxc.hlsl
@@ -33,7 +33,7 @@
   }
   GroupMemoryBarrierWithGroupSync();
   uint v_3 = 0u;
-  InterlockedExchange(wg.a[int(4)], 1u, v_3);
+  InterlockedExchange(wg.a[4u], 1u, v_3);
 }
 
 [numthreads(1, 1, 1)]
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 d1a6149..b9386d8 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
@@ -23,6 +23,9 @@
   threadgroup S* wg;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   S tint_symbol;
 };
@@ -36,6 +39,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 10u)) {
         break;
@@ -48,7 +52,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  atomic_store_explicit((&(*tint_module_vars.wg).a[4]), 1u, memory_order_relaxed);
+  atomic_store_explicit((&(*tint_module_vars.wg).a[4u]), 1u, memory_order_relaxed);
 }
 
 kernel void compute_main(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_1* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl
index aa522b6..f11766f 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   int x;
   tint_array<atomic_uint, 10> a;
@@ -26,6 +29,7 @@
     (*(tint_symbol)).y = 0u;
   }
   for(uint idx = local_idx; (idx < 10u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     atomic_store_explicit(&((*(tint_symbol)).a[i]), 0u, memory_order_relaxed);
   }
diff --git a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm
index 9784f1a..93a5b1a 100644
--- a/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm
+++ b/test/tint/builtins/atomicStore/struct/struct_of_array.wgsl.expected.spvasm
@@ -41,7 +41,7 @@
      %uint_2 = OpConstant %uint 2
 %_ptr_Workgroup_uint_0 = OpTypePointer Workgroup %uint
    %uint_264 = OpConstant %uint 264
-      %int_4 = OpConstant %int 4
+     %uint_4 = OpConstant %uint 4
          %46 = OpTypeFunction %void
 %compute_main_inner = OpFunction %void None %13
 %tint_local_index = OpFunctionParameter %uint
@@ -78,7 +78,7 @@
                OpBranch %30
          %31 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %42 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %int_4
+         %42 = OpAccessChain %_ptr_Workgroup_uint_0 %wg %uint_1 %uint_4
                OpAtomicStore %42 %uint_2 %uint_0 %uint_1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.glsl
index c1026c2..fc69339 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_022903() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_022903() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_022903() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
index 0128584..7434fff 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 uint textureDimensions_022903() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_022903();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
index 0128584..7434fff 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 uint textureDimensions_022903() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_022903();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.msl
index 19cd6aa..34f0089 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_022903(tint_module_vars_struct tint_module_vars) {
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.msl
index ec5c0a8..bda8308 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_022903(texture1d<int, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.spvasm
index bb970c8..b459002 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/022903.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +62,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_022903 = OpFunction %uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %20 = OpLoad %7 %arg_0 None
-         %21 = OpImageQuerySizeLod %uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %uint %textureDimensions_022903
-         %31 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %uint %textureDimensions_022903
+         %35 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %uint %textureDimensions_022903
-         %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %uint %textureDimensions_022903
+         %41 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %49 = OpFunctionCall %uint %textureDimensions_022903
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %53 = OpFunctionCall %uint %textureDimensions_022903
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.glsl
index 355d6e8..5994c5b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_0890c6() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_0890c6() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_0890c6() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
index 199b9d99..4727f4a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 uint3 textureDimensions_0890c6() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0890c6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
index 199b9d99..4727f4a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 uint3 textureDimensions_0890c6() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0890c6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.msl
index 006c320..bab5684 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_0890c6(tint_module_vars_struct tint_module_vars) {
-  uint3 res = uint3(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u), tint_module_vars.arg_0.get_depth(1u));
+  uint3 res = uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.msl
index b390965..20a7994 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_0890c6(texture3d<float, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u), tint_symbol_1.get_depth(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.spvasm
index 697d153..b10994c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/0890c6.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_0890c6 = OpFunction %v3uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v3uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v3uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v3uint %textureDimensions_0890c6
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v3uint %textureDimensions_0890c6
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v3uint %textureDimensions_0890c6
-         %37 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v3uint %textureDimensions_0890c6
+         %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %49 = OpFunctionCall %v3uint %textureDimensions_0890c6
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %53 = OpFunctionCall %v3uint %textureDimensions_0890c6
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v3uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v3uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.glsl
index 00ba2c3..a4f0df2 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_0ff9a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_0ff9a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_0ff9a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
index a5052bd..308010c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray arg_0 : register(t0, space1);
 uint2 textureDimensions_0ff9a4() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0ff9a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
index a5052bd..308010c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray arg_0 : register(t0, space1);
 uint2 textureDimensions_0ff9a4() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0ff9a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.msl
index 9736f99..1e7a085 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_0ff9a4(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.msl
index c1b2162..92a011e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_0ff9a4(depthcube_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.spvasm
index 8f5bf1d..8337710 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/0ff9a4.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +59,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_0ff9a4 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.glsl
index aca0640..b0ec764 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_13f8db() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_13f8db() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_13f8db() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
index 9226b85..faad4f3 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_13f8db() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_13f8db();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
index 9226b85..faad4f3 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_13f8db() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_13f8db();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.msl
index 7e62ddc..1d1c57e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_13f8db(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.msl
index 608c5df..2dd2512 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_13f8db(texture2d<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.spvasm
index da78c4b..43c1838 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/13f8db.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_13f8db = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_13f8db
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_13f8db
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_13f8db
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_13f8db
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_13f8db
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_13f8db
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.glsl
index 1d8f967..cba1cb7 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_15b577() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_15b577() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_15b577() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
index c145502..95c0596 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_15b577() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_15b577();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
index c145502..95c0596 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_15b577() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_15b577();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.msl
index 9dd8ad6..62e2db0 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_15b577(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.msl
index 86fd9a3..92c9e9f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_15b577(texture2d<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.spvasm
index 558e295..1e58710 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/15b577.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_15b577 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_15b577
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_15b577
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_15b577
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_15b577
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_15b577
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.glsl
index 33fa3d9..620c07b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_1bc428() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_1bc428() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_1bc428() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
index ba57c98..eb3721c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 uint3 textureDimensions_1bc428() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bc428();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
index ba57c98..eb3721c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 uint3 textureDimensions_1bc428() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bc428();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.msl
index d7778b0..7ee2d24 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_1bc428(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.msl
index e39058c..09f2899 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_1bc428(texture3d<float, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1), tint_symbol_1.get_depth(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.spvasm
index eab7370..11bf642 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bc428.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v3uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_1bc428 = OpFunction %v3uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v3uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v3uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v3uint %textureDimensions_1bc428
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v3uint %textureDimensions_1bc428
          %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %51 = OpFunctionCall %v3uint %textureDimensions_1bc428
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v3uint %textureDimensions_1bc428
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v3uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %56 = OpFunctionCall %v3uint %textureDimensions_1bc428
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v3uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.glsl
index f7db778..1a2cd3a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_1bd78c() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_1bd78c() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_1bd78c() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
index a449940..905f81f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_1bd78c() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bd78c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
index a449940..905f81f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_1bd78c() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bd78c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.msl
index 3583e9f..712f2fb 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_1bd78c(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.msl
index 91f7aef..2de2218 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_1bd78c(texture2d<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.spvasm
index b0e2491..3e2e595 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/1bd78c.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_1bd78c = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_1bd78c
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_1bd78c
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_1bd78c
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_1bd78c
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_1bd78c
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.glsl
index c944c1b..814c941 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_22b5b6() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_22b5b6() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_22b5b6() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
index bfea15d..ef9e1c8 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_22b5b6() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_22b5b6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
index bfea15d..ef9e1c8 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_22b5b6() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_22b5b6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.msl
index 63da12a..13c2f0f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_22b5b6(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.msl
index 44f5994..09b98fd 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_22b5b6(texturecube_array<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.spvasm
index cdab723..85be1d5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/22b5b6.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +59,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_22b5b6 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_22b5b6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_22b5b6
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_22b5b6
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_22b5b6
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_22b5b6
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.glsl
index e95f5e5..7a21570 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_2e443d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_2e443d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_2e443d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
index 6856397..a150322 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_2e443d() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2e443d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
index 6856397..a150322 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_2e443d() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2e443d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.msl
index a8d1a02..d657fb5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_2e443d(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.msl
index bf667fb..7eec598 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_2e443d(texture2d<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.spvasm
index d957d18..380c0d6 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/2e443d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,61 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_2e443d = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v2uint %21 %int_1
-               OpStore %res %22
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v2uint %21 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_2e443d
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_2e443d
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_2e443d
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_2e443d
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_2e443d
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.glsl
index 437aba3..f542a50 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_2fd2a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_2fd2a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_2fd2a4() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
index 8674b7e..8851b4a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_2fd2a4() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2fd2a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
index 8674b7e..8851b4a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_2fd2a4() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2fd2a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.msl
index 98facd3..44d69d3 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_2fd2a4(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.msl
index a7a299f..e654944 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_2fd2a4(texture2d_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.spvasm
index 7a9b1b7..3dc666d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/2fd2a4.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +58,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_2fd2a4 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.glsl
index bef8b9d..6bad5c5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_346fee() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_346fee() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_346fee() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
index 74a21d1..7c05e42 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_346fee() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_346fee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
index 74a21d1..7c05e42 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_346fee() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_346fee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.msl
index 22f82e2..0058003 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_346fee(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.msl
index f25a45c..0d80bf11 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_346fee(texturecube_array<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.spvasm
index 61afd6a..bdb18e4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/346fee.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_346fee = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_346fee
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_346fee
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_346fee
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_346fee
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_346fee
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_346fee
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.glsl
index 84ea26f..e609c9e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_382b16() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_382b16() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_382b16() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
index 65596ec..3eeef8c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_382b16() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_382b16();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
index 65596ec..3eeef8c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_382b16() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_382b16();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.msl
index 7e6f60d..399c150 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_382b16(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.msl
index 29859a2..1e04493 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_382b16(texturecube<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.spvasm
index f714f68..71a2677 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/382b16.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_382b16 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_382b16
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_382b16
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_382b16
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_382b16
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_382b16
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_382b16
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.glsl
index 77f1cc3..644c4e4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3963d0() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3963d0() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3963d0() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
index 9d54dac..291ce88 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3963d0() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3963d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
index 9d54dac..291ce88 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3963d0() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3963d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.msl
index aec4dad..a604b09 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_3963d0(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.msl
index 080da89..a61f514 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_3963d0(texturecube_array<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.spvasm
index 8a13194..503e129 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/3963d0.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,62 +60,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3963d0 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %uint_1
-         %25 = OpVectorShuffle %v2uint %22 %22 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v3uint %21 %25
+         %29 = OpVectorShuffle %v2uint %27 %27 0 1
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_3963d0
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_3963d0
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_3963d0
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_3963d0
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_3963d0
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_3963d0
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.glsl
index cc41b32..b0fe2747 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3c66f0() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3c66f0() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3c66f0() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
index dc4ad8d..3d26d0f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3c66f0() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3c66f0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
index dc4ad8d..3d26d0f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3c66f0() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3c66f0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.msl
index b8a070d..fab563b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_3c66f0(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.msl
index f24e298..873648e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_3c66f0(texturecube_array<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.spvasm
index 1ca6825..7338480 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/3c66f0.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +60,67 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3c66f0 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %int_1
-         %25 = OpVectorShuffle %v2uint %22 %22 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v3uint %21 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_3c66f0
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_3c66f0
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_3c66f0
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_3c66f0
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_3c66f0
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.glsl
index 93ecb02..f941533 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_3fc3dc() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_3fc3dc() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3fc3dc() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
index 24ed7da..2d6e309 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3fc3dc() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3fc3dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
index 24ed7da..2d6e309 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_3fc3dc() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3fc3dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.msl
index d46e5c3..3f2b9e5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_3fc3dc(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.msl
index 9d8b457..8fc8ea4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_3fc3dc(texture2d_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.spvasm
index b60fff8..ac98595 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/3fc3dc.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3fc3dc = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.glsl
index 2786922..08b4fd9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_49a067() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_49a067() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_49a067() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
index fd18b02..abf8c7a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_49a067() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_49a067();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
index fd18b02..abf8c7a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_49a067() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_49a067();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.msl
index d9682ea..ffa9c55 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_49a067(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.msl
index c827c71..22b872b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_49a067(texturecube<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.spvasm
index 86657d0..686863f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/49a067.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_49a067 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_49a067
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_49a067
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_49a067
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_49a067
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_49a067
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.glsl
index 2ee8106..d911982 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_528c0e() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_528c0e() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_528c0e() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
index 65f4a27..208f60a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_528c0e() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_528c0e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
index 65f4a27..208f60a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_528c0e() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_528c0e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.msl
index 2ea4f48..4b4a3e6 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_528c0e(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.msl
index 84ca9a2..a4224b9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_528c0e(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.spvasm
index 92bb597..8a56e1f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/528c0e.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_528c0e = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_528c0e
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_528c0e
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_528c0e
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_528c0e
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_528c0e
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_528c0e
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.glsl
index 50dff91..6ab4e0d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_64dc74() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_64dc74() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_64dc74() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
index ab82001b..a73d999 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_64dc74() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_64dc74();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
index ab82001b..a73d999 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_64dc74() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_64dc74();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.msl
index 3b74fe0..f0c8a65 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_64dc74(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.msl
index 15f0a9b..2e7cf0d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_64dc74(texturecube<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.spvasm
index 3b610d2..64836f6 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/64dc74.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +62,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_64dc74 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v2uint %21 %uint_1
-               OpStore %res %22
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v2uint %21 %25
+               OpStore %res %27
+         %30 = OpLoad %v2uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_64dc74
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v2uint %textureDimensions_64dc74
+         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v2uint %textureDimensions_64dc74
-         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v2uint %textureDimensions_64dc74
+         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %50 = OpFunctionCall %v2uint %textureDimensions_64dc74
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %54 = OpFunctionCall %v2uint %textureDimensions_64dc74
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v2uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v2uint %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.glsl
index ebc0c23..b08b281 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_6e6c7a() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_6e6c7a() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_6e6c7a() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
index 223aaba..aeafe45 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint3 textureDimensions_6e6c7a() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6e6c7a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
index 223aaba..aeafe45 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint3 textureDimensions_6e6c7a() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6e6c7a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.msl
index cab68f6..10aa606 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_6e6c7a(tint_module_vars_struct tint_module_vars) {
-  uint3 res = uint3(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u), tint_module_vars.arg_0.get_depth(1u));
+  uint3 res = uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.msl
index 530e38d..8eb0cf7 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_6e6c7a(texture3d<uint, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u), tint_symbol_1.get_depth(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.spvasm
index a292ce8..8578cb7 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/6e6c7a.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_6e6c7a = OpFunction %v3uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v3uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v3uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-         %31 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-         %37 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+         %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %49 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %53 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v3uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v3uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.glsl
index 7075a20..5409c97 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_6f1b5d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_6f1b5d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_6f1b5d() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
index 7c44ceb..2d0b8d5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D arg_0 : register(t0, space1);
 uint2 textureDimensions_6f1b5d() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6f1b5d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
index 7c44ceb..2d0b8d5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D arg_0 : register(t0, space1);
 uint2 textureDimensions_6f1b5d() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6f1b5d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.msl
index d68a1d8..1da1c8f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_6f1b5d(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.msl
index 874b520..ec64a84 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_6f1b5d(depth2d<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.spvasm
index 7023a85..511b9dc 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/6f1b5d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_6f1b5d = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.glsl
index 73180a8..555f7b3 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_756031() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_756031() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_756031() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
index 17c4be2..c068dfa 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 uint3 textureDimensions_756031() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_756031();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
index 17c4be2..c068dfa 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 uint3 textureDimensions_756031() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_756031();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.msl
index 34ceb4a..5d12793 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_756031(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.msl
index bba58b3..3ece6a6 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_756031(texture3d<int, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1), tint_symbol_1.get_depth(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.spvasm
index 53e17e4..7460205 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/756031.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,61 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v3uint
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_756031 = OpFunction %v3uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %int_1
-               OpStore %res %22
-         %26 = OpLoad %v3uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v3uint %21 %27
+               OpStore %res %29
+         %32 = OpLoad %v3uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v3uint %textureDimensions_756031
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v3uint %textureDimensions_756031
          %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %51 = OpFunctionCall %v3uint %textureDimensions_756031
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v3uint %textureDimensions_756031
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v3uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %56 = OpFunctionCall %v3uint %textureDimensions_756031
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v3uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.glsl
index d503847..65323bb5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_79d168() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_79d168() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_79d168() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
index f3144f4..c802dcf 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube arg_0 : register(t0, space1);
 uint2 textureDimensions_79d168() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_79d168();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
index f3144f4..c802dcf 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube arg_0 : register(t0, space1);
 uint2 textureDimensions_79d168() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_79d168();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.msl
index 247e563..b9c94f4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_79d168(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.msl
index 4a80235..816033a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_79d168(depthcube<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.spvasm
index e23dfda..1aa8eda 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/79d168.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_79d168 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_79d168
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_79d168
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_79d168
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_79d168
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_79d168
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.glsl
index a957543..05ab004 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_920006() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_920006() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_920006() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
index 857b2d7..251ebd4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint textureDimensions_920006() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_920006();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
index 857b2d7..251ebd4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint textureDimensions_920006() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_920006();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.msl
index c2e47fb..39a0e77 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_920006(tint_module_vars_struct tint_module_vars) {
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.msl
index acea533..370dbec 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_920006(texture1d<uint, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.spvasm
index 559a348..a1f45ae 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/920006.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %17 = OpTypeFunction %uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %40 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_920006 = OpFunction %uint None %17
          %18 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %19 = OpLoad %7 %arg_0 None
-         %20 = OpImageQuerySizeLod %uint %19 %int_1
-               OpStore %res %20
-         %25 = OpLoad %uint %res None
-               OpReturnValue %25
+         %20 = OpImageQueryLevels %uint %19
+         %21 = OpISub %uint %20 %uint_1
+         %23 = OpBitcast %uint %int_1
+         %26 = OpExtInst %uint %27 UMin %23 %21
+         %28 = OpImageQuerySizeLod %uint %19 %26
+               OpStore %res %28
+         %31 = OpLoad %uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %uint %textureDimensions_920006
-         %31 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %34
          %35 = OpLabel
          %36 = OpFunctionCall %uint %textureDimensions_920006
          %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
+%compute_main = OpFunction %void None %34
          %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %50 = OpFunctionCall %uint %textureDimensions_920006
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %42 = OpFunctionCall %uint %textureDimensions_920006
+         %43 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %43 %42 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %55 = OpFunctionCall %uint %textureDimensions_920006
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.glsl
index 81fff5b..e653a31 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_991ea9() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_991ea9() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_991ea9() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
index 1aec6dd..9a12f5d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D arg_0 : register(t0, space1);
 uint2 textureDimensions_991ea9() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_991ea9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
index 1aec6dd..9a12f5d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D arg_0 : register(t0, space1);
 uint2 textureDimensions_991ea9() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_991ea9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.msl
index 30f28ef..cb2e20b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_991ea9(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.msl
index f343828..55fbd09 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_991ea9(depth2d<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.spvasm
index 8b7287e..1fa6a40 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/991ea9.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_991ea9 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_991ea9
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_991ea9
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_991ea9
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_991ea9
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_991ea9
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_991ea9
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.glsl
index aa2de70..4589d5d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9baf27() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9baf27() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9baf27() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
index 396a553..461fad0 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9baf27() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9baf27();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
index 396a553..461fad0 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9baf27() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9baf27();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.msl
index f73f006..2c2399b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_9baf27(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.msl
index 3962478..7fb4b81 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_9baf27(texturecube<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.spvasm
index e6c36b9d..2d97e81 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/9baf27.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9baf27 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_9baf27
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_9baf27
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_9baf27
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_9baf27
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_9baf27
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_9baf27
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.glsl
index 1d84481..01653b9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_9c7a00() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_9c7a00() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_9c7a00() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
index f81a88e..bc287b7 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint textureDimensions_9c7a00() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9c7a00();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
index f81a88e..bc287b7 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint textureDimensions_9c7a00() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9c7a00();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.msl
index 02dfe42..748637d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_9c7a00(tint_module_vars_struct tint_module_vars) {
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.msl
index 88ee06b..deffed8 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_9c7a00(texture1d<uint, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.spvasm
index c986230..f6d48da 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/9c7a00.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %39 = OpTypeFunction %VertexOutput
+         %43 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
+         %47 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %46 = OpConstantNull %v4float
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9c7a00 = OpFunction %uint None %17
          %18 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %19 = OpLoad %7 %arg_0 None
-         %20 = OpImageQuerySizeLod %uint %19 %uint_1
-               OpStore %res %20
-         %24 = OpLoad %uint %res None
-               OpReturnValue %24
+         %20 = OpImageQueryLevels %uint %19
+         %21 = OpISub %uint %20 %uint_1
+         %23 = OpExtInst %uint %24 UMin %uint_1 %21
+         %25 = OpImageQuerySizeLod %uint %19 %23
+               OpStore %res %25
+         %28 = OpLoad %uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %uint %textureDimensions_9c7a00
-         %30 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %uint %textureDimensions_9c7a00
+         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %uint %textureDimensions_9c7a00
-         %36 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %uint %textureDimensions_9c7a00
+         %40 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
-         %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %46 None
-         %47 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %48 = OpFunctionCall %uint %textureDimensions_9c7a00
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %43
+         %44 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %47
+         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %48 %50 None
+         %51 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %52 = OpFunctionCall %uint %textureDimensions_9c7a00
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %27
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %uint %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %31
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %uint %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.glsl
index 2ed74dc..daaa142 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9cd4ca() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9cd4ca() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9cd4ca() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
index e503cfa..617232e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9cd4ca() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9cd4ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
index e503cfa..617232e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9cd4ca() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9cd4ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.msl
index 2d1361a..92439db 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_9cd4ca(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.msl
index 52967fd..20cecc9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_9cd4ca(texturecube<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.spvasm
index 9ada05a..ab25605 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/9cd4ca.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9cd4ca = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.glsl
index 6963bec..821fbe4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_9e0794() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_9e0794() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9e0794() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
index 183994c..67a1729 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9e0794() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9e0794();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
index 183994c..67a1729 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_9e0794() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9e0794();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.msl
index 842f12b..a2368d6 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_9e0794(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.msl
index 6cc1fb7..c943ca2 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_9e0794(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.spvasm
index 3b71b7c..ab489d5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/9e0794.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +58,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9e0794 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_9e0794
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_9e0794
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_9e0794
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_9e0794
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_9e0794
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.glsl
index 6d33b20..d2c8c33 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_a2ba5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_a2ba5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_a2ba5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
index e2b5927..52ab31c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_a2ba5e() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a2ba5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
index e2b5927..52ab31c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_a2ba5e() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a2ba5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.msl
index 54aa348..b5555b9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_a2ba5e(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.msl
index a5389a2..4ab3a02 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_a2ba5e(texturecube<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.spvasm
index c221cad..7a17daa 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/a2ba5e.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,61 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_a2ba5e = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v2uint %21 %int_1
-               OpStore %res %22
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v2uint %21 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
          %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.glsl
index 2bb3d73..1b93bb9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_a48049() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_a48049() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_a48049() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
index 01544a6..83f8dab 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_a48049() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a48049();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
index 01544a6..83f8dab 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_a48049() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a48049();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.msl
index e5f7306..aedcf07 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_a48049(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.msl
index 96ac89b..81ff1b4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_a48049(texture2d<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.spvasm
index c008d5c..6b61daf 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/a48049.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +62,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_a48049 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v2uint %21 %uint_1
-               OpStore %res %22
-         %26 = OpLoad %v2uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v2uint %21 %25
+               OpStore %res %27
+         %30 = OpLoad %v2uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v2uint %textureDimensions_a48049
-         %32 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v2uint %textureDimensions_a48049
+         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v2uint %textureDimensions_a48049
-         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v2uint %textureDimensions_a48049
+         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %50 = OpFunctionCall %v2uint %textureDimensions_a48049
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %54 = OpFunctionCall %v2uint %textureDimensions_a48049
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v2uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v2uint %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.glsl
index bad2bd2..f6d097d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_aac604() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_aac604() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_aac604() {
-  uint res = uvec2(textureSize(arg_0, int(1u))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
index 3f942cb9..46ab06a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 uint textureDimensions_aac604() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_aac604();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
index 3f942cb9..46ab06a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 uint textureDimensions_aac604() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_aac604();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.msl
index 5ff783d..ae27ff5 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_aac604(tint_module_vars_struct tint_module_vars) {
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.msl
index 7420de5..c115e03 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_aac604(texture1d<float, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.spvasm
index f071a8b..ff3d40d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/aac604.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %39 = OpTypeFunction %VertexOutput
+         %43 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
+         %47 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %46 = OpConstantNull %v4float
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_aac604 = OpFunction %uint None %17
          %18 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %19 = OpLoad %7 %arg_0 None
-         %20 = OpImageQuerySizeLod %uint %19 %uint_1
-               OpStore %res %20
-         %24 = OpLoad %uint %res None
-               OpReturnValue %24
+         %20 = OpImageQueryLevels %uint %19
+         %21 = OpISub %uint %20 %uint_1
+         %23 = OpExtInst %uint %24 UMin %uint_1 %21
+         %25 = OpImageQuerySizeLod %uint %19 %23
+               OpStore %res %25
+         %28 = OpLoad %uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %uint %textureDimensions_aac604
-         %30 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %uint %textureDimensions_aac604
+         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %uint %textureDimensions_aac604
-         %36 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %uint %textureDimensions_aac604
+         %40 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
-         %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %46 None
-         %47 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %48 = OpFunctionCall %uint %textureDimensions_aac604
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %43
+         %44 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %47
+         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %48 %50 None
+         %51 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %52 = OpFunctionCall %uint %textureDimensions_aac604
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %27
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %uint %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %31
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %uint %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.glsl
index cbbee8c..c860d92 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_b3ab5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_b3ab5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_b3ab5e() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
index 9e85ffa..f29e57a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_b3ab5e() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b3ab5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
index 9e85ffa..f29e57a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_b3ab5e() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b3ab5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.msl
index 6f1a7b05..d00d103 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_b3ab5e(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.msl
index 56f53f1..8189c78 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_b3ab5e(texturecube_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.spvasm
index 7cc9a7d..bae2764 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/b3ab5e.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +59,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_b3ab5e = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.glsl
index 60bbfed..b9a0c4c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_b46d97() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_b46d97() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_b46d97() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
index 0f922fb4..be8459d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 uint textureDimensions_b46d97() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b46d97();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
index 0f922fb4..be8459d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 uint textureDimensions_b46d97() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b46d97();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.msl
index 2e246b1..1ec95ed 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_b46d97(tint_module_vars_struct tint_module_vars) {
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.msl
index f4c5cbe..a3bd016 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_b46d97(texture1d<int, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.spvasm
index 27df59f..f893c81 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/b46d97.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,61 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %uint
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %40 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_b46d97 = OpFunction %uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %20 = OpLoad %7 %arg_0 None
-         %21 = OpImageQuerySizeLod %uint %20 %int_1
-               OpStore %res %21
-         %25 = OpLoad %uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %26 = OpExtInst %uint %27 UMin %24 %22
+         %28 = OpImageQuerySizeLod %uint %20 %26
+               OpStore %res %28
+         %31 = OpLoad %uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %uint %textureDimensions_b46d97
-         %31 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %34
          %35 = OpLabel
          %36 = OpFunctionCall %uint %textureDimensions_b46d97
          %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
+%compute_main = OpFunction %void None %34
          %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %50 = OpFunctionCall %uint %textureDimensions_b46d97
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %42 = OpFunctionCall %uint %textureDimensions_b46d97
+         %43 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %43 %42 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %55 = OpFunctionCall %uint %textureDimensions_b46d97
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.glsl
index 4b06161..9530c27 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_bd94c8() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_bd94c8() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_bd94c8() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
index 8d24349..c36dfa1 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray arg_0 : register(t0, space1);
 uint2 textureDimensions_bd94c8() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_bd94c8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
index 8d24349..c36dfa1 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray arg_0 : register(t0, space1);
 uint2 textureDimensions_bd94c8() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_bd94c8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.msl
index 3780279..938be15 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_bd94c8(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.msl
index 632b4d0..df4b8b8 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_bd94c8(depthcube_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.spvasm
index ab58c85..4d4a077 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/bd94c8.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_bd94c8 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.glsl
index f5480b2..393f47a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_c871f3() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_c871f3() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_c871f3() {
-  uvec3 res = uvec3(textureSize(arg_0, int(1u)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
index 94d7e80..8850c88 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 uint3 textureDimensions_c871f3() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_c871f3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
index 94d7e80..8850c88 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 uint3 textureDimensions_c871f3() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_c871f3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.msl
index 7dbd925..bfe5014 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_c871f3(tint_module_vars_struct tint_module_vars) {
-  uint3 res = uint3(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u), tint_module_vars.arg_0.get_depth(1u));
+  uint3 res = uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.msl
index 4afe292..4b1c406 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_c871f3(texture3d<int, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u), tint_symbol_1.get_depth(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.spvasm
index 2a1696f..f7abbc4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/c871f3.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +62,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_c871f3 = OpFunction %v3uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %uint_1
-               OpStore %res %22
-         %26 = OpLoad %v3uint %res None
-               OpReturnValue %26
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v3uint %21 %25
+               OpStore %res %27
+         %30 = OpLoad %v3uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v3uint %textureDimensions_c871f3
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v3uint %textureDimensions_c871f3
+         %36 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v3uint %textureDimensions_c871f3
-         %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v3uint %textureDimensions_c871f3
+         %42 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %50 = OpFunctionCall %v3uint %textureDimensions_c871f3
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %54 = OpFunctionCall %v3uint %textureDimensions_c871f3
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v3uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v3uint %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.glsl
index 0c10440..d5e8d2c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_cf2b50() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_cf2b50() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_cf2b50() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
index 00262cf..f392682 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_cf2b50() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_cf2b50();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
index 00262cf..f392682 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCubeArray<float4> arg_0 : register(t0, space1);
 uint2 textureDimensions_cf2b50() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_cf2b50();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.msl
index 1c31af1..c883f73 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_cf2b50(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.msl
index 0d79c38..ccfd3b0 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_cf2b50(texturecube_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.spvasm
index 6880428..e71a8a4 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/cf2b50.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_cf2b50 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.glsl
index b6f4023..9295ebc 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_d3accd() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_d3accd() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_d3accd() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
index a7df088..079d079 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube arg_0 : register(t0, space1);
 uint2 textureDimensions_d3accd() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_d3accd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
index a7df088..079d079 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 TextureCube arg_0 : register(t0, space1);
 uint2 textureDimensions_d3accd() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_d3accd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.msl
index 7155c8a..59fd8fe 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_d3accd(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.msl
index 5a84a89..8456892 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_d3accd(depthcube<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.spvasm
index 5ed36aa..87ce49f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/d3accd.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_d3accd = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_d3accd
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_d3accd
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_d3accd
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_d3accd
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_d3accd
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_d3accd
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.glsl
index f92ebd5..80e381a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_dfdc32() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_dfdc32() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_dfdc32() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
index 436cf2f..6a0177c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray arg_0 : register(t0, space1);
 uint2 textureDimensions_dfdc32() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_dfdc32();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
index 436cf2f..6a0177c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray arg_0 : register(t0, space1);
 uint2 textureDimensions_dfdc32() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_dfdc32();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.msl
index efc7df4..9ceda8d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_dfdc32(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.msl
index d1e6af1..f1f2918 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_dfdc32(depth2d_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.spvasm
index e6c0b40..9efad0d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/dfdc32.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +58,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_dfdc32 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-         %25 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_dfdc32
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_dfdc32
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_dfdc32
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_dfdc32
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_dfdc32
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.glsl
index 98027f6..392fd0c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_e18a8b() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_e18a8b() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_e18a8b() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
index 3cdad2a..5479a95 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_e18a8b() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e18a8b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
index 3cdad2a..5479a95 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint2 textureDimensions_e18a8b() {
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e18a8b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.msl
index 8ccb6b5..e798724 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_e18a8b(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.msl
index cd2e510..7e93cac 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_e18a8b(texture2d<uint, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.spvasm
index 6cf8bd6..b1e1bae 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/e18a8b.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e18a8b = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v2uint %20 %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v2uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+               OpStore %res %26
+         %29 = OpLoad %v2uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-         %31 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %49 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %53 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v2uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v2uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.glsl
index e147a84..f9bc55a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_e4e310() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_e4e310() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_e4e310() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
index 0ca789e..f67cfb9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_e4e310() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e4e310();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
index 0ca789e..f67cfb9 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_e4e310() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e4e310();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.msl
index 513e365..a7c627d 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_e4e310(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.msl
index cfb4a96..fbd1e77 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_e4e310(texture2d_array<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.spvasm
index 69155bb..eaf465c 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/e4e310.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +59,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e4e310 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %uint_1
-         %25 = OpVectorShuffle %v2uint %22 %22 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v3uint %21 %25
+         %29 = OpVectorShuffle %v2uint %27 %27 0 1
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_e4e310
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_e4e310
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_e4e310
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_e4e310
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_e4e310
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_e4e310
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.glsl
index 4543bf3..e93f80a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_e5a203() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_e5a203() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_e5a203() {
-  uvec3 res = uvec3(textureSize(arg_0, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
index a7f0ff1..7a08fff 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint3 textureDimensions_e5a203() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e5a203();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
index a7f0ff1..7a08fff 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint3 textureDimensions_e5a203() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e5a203();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.msl
index 8de23b4..e53bced 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint3 textureDimensions_e5a203(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.msl
index 3fbf237..a356c97 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint3 textureDimensions_e5a203(texture3d<uint, access::sample> tint_symbol_1) {
-  uint3 res = uint3(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1), tint_symbol_1.get_depth(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.spvasm
index 302304b..eeff0ee 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/e5a203.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v3uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e5a203 = OpFunction %v3uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v3uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %int_1
-               OpStore %res %21
-         %26 = OpLoad %v3uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+               OpStore %res %29
+         %32 = OpLoad %v3uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v3uint %textureDimensions_e5a203
-         %32 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v3uint %textureDimensions_e5a203
          %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %51 = OpFunctionCall %v3uint %textureDimensions_e5a203
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v3uint %textureDimensions_e5a203
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v3uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %56 = OpFunctionCall %v3uint %textureDimensions_e5a203
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v3uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.glsl
index ad94bd3..6f6ac6e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.glsl
@@ -2,13 +2,22 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_eafe19() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -16,13 +25,22 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_eafe19() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +50,23 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_eafe19() {
-  uvec2 res = uvec2(textureSize(arg_0, int(1u)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(1u, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +76,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
index e81c5d8..19a9b66 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray arg_0 : register(t0, space1);
 uint2 textureDimensions_eafe19() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_eafe19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
index e81c5d8..19a9b66 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray arg_0 : register(t0, space1);
 uint2 textureDimensions_eafe19() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(1u), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_eafe19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.msl
index 1e733f6..51ec8cf 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_eafe19(tint_module_vars_struct tint_module_vars) {
-  uint2 res = uint2(tint_module_vars.arg_0.get_width(1u), tint_module_vars.arg_0.get_height(1u));
+  uint2 res = uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.msl
index bc4a913..5b2dd9f 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_eafe19(depth2d_array<float, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1u), tint_symbol_1.get_height(1u));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.spvasm
index 4b02f63..a64633b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/eafe19.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,65 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_eafe19 = OpFunction %v2uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageQuerySizeLod %v3uint %20 %uint_1
-         %24 = OpVectorShuffle %v2uint %21 %21 0 1
-               OpStore %res %24
-         %27 = OpLoad %v2uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpVectorShuffle %v2uint %26 %26 0 1
+               OpStore %res %28
+         %31 = OpLoad %v2uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v2uint %textureDimensions_eafe19
-         %33 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v2uint %textureDimensions_eafe19
+         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v2uint %textureDimensions_eafe19
-         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v2uint %textureDimensions_eafe19
+         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %51 = OpFunctionCall %v2uint %textureDimensions_eafe19
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %55 = OpFunctionCall %v2uint %textureDimensions_eafe19
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v2uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v2uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.glsl
index 993ffd0..ce82105 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_f17acd() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_f17acd() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_f17acd() {
-  uint res = uvec2(textureSize(arg_0, 1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
index f98e093..76f82a1 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 uint textureDimensions_f17acd() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_f17acd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
index f98e093..76f82a1 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 uint textureDimensions_f17acd() {
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_f17acd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.msl
index 64a9eca..34adb8e 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.ir.msl
@@ -17,6 +17,7 @@
 };
 
 uint textureDimensions_f17acd(tint_module_vars_struct tint_module_vars) {
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.msl
index 9b2d166..242c82a 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.msl
@@ -2,6 +2,7 @@
 
 using namespace metal;
 uint textureDimensions_f17acd(texture1d<float, access::sample> tint_symbol_1) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.spvasm
index e35b2a2..8be1e69 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/f17acd.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %17 = OpTypeFunction %uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %40 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_f17acd = OpFunction %uint None %17
          %18 = OpLabel
         %res = OpVariable %_ptr_Function_uint Function
          %19 = OpLoad %7 %arg_0 None
-         %20 = OpImageQuerySizeLod %uint %19 %int_1
-               OpStore %res %20
-         %25 = OpLoad %uint %res None
-               OpReturnValue %25
+         %20 = OpImageQueryLevels %uint %19
+         %21 = OpISub %uint %20 %uint_1
+         %23 = OpBitcast %uint %int_1
+         %26 = OpExtInst %uint %27 UMin %23 %21
+         %28 = OpImageQuerySizeLod %uint %19 %26
+               OpStore %res %28
+         %31 = OpLoad %uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %uint %textureDimensions_f17acd
-         %31 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %34
          %35 = OpLabel
          %36 = OpFunctionCall %uint %textureDimensions_f17acd
          %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
+%compute_main = OpFunction %void None %34
          %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %50 = OpFunctionCall %uint %textureDimensions_f17acd
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %42 = OpFunctionCall %uint %textureDimensions_f17acd
+         %43 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %43 %42 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %55 = OpFunctionCall %uint %textureDimensions_f17acd
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.glsl
index 277ee9d..2181c12 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.glsl
@@ -2,13 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_fdf6e9() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 void main() {
@@ -16,13 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_fdf6e9() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -32,15 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_fdf6e9() {
-  uvec2 res = uvec2(textureSize(arg_0, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
index 97f15e0..8889b57 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_fdf6e9() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_fdf6e9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
index 97f15e0..8889b57 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
@@ -13,8 +13,10 @@
 Texture2DArray<int4> arg_0 : register(t0, space1);
 uint2 textureDimensions_fdf6e9() {
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -31,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_fdf6e9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.msl
index eb90256..6baefe2 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint2 textureDimensions_fdf6e9(tint_module_vars_struct tint_module_vars) {
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.msl
index 6a16bb4..ca23d0b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint2 textureDimensions_fdf6e9(texture2d_array<int, access::sample> tint_symbol_1) {
-  uint2 res = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.spvasm
index cba5926..e858e7b 100644
--- a/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureDimensions/fdf6e9.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +59,67 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %19 = OpTypeFunction %v2uint
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_fdf6e9 = OpFunction %v2uint None %19
          %20 = OpLabel
         %res = OpVariable %_ptr_Function_v2uint Function
          %21 = OpLoad %8 %arg_0 None
-         %22 = OpImageQuerySizeLod %v3uint %21 %int_1
-         %25 = OpVectorShuffle %v2uint %22 %22 0 1
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %22 = OpImageQueryLevels %uint %21
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v3uint %21 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
          %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
index a30ebcd..8e0a655 100644
--- a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_012e11() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
index a30ebcd..8e0a655 100644
--- a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_012e11() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.msl
index d5764b9..31ad12e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_012e11(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.msl
index 006026b..fef5c13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_012e11(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.spvasm
index cd869dc..f163178 100644
--- a/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/012e11.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_012e11 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_012e11
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_012e11
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_012e11
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_012e11
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.glsl
index 587561e..7b9b9a7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_019da0() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_019da0() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_019da0() {
-  ivec3 v = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_2 = (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u));
+  ivec3 v_3 = ivec3(min(uvec3(ivec3(1)), v_2));
+  vec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
index 2381322..1e79edd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_019da0() {
-  int3 v = int3((int(1)).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_019da0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
index 2381322..1e79edd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_019da0() {
-  int3 v = int3((int(1)).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_019da0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.msl
index dbfdbad..048a346 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_019da0(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1u);
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.msl
index 6b3bc22..d6df079 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_019da0(texture3d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.spvasm
index 4847577..f713a1c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/019da0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %27 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_019da0 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v3uint %17 %22
+         %26 = OpISub %v3uint %24 %27
+         %28 = OpBitcast %v3uint %29
+         %33 = OpExtInst %v3uint %23 UMin %28 %26
+         %34 = OpImageFetch %v4float %17 %33 Lod %22
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_019da0
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_019da0
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_019da0
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_019da0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_019da0
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %30
+%vertex_main_inner = OpFunction %VertexOutput None %52
          %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_019da0
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.glsl
index d030309..efa15c6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_01cd01() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_01cd01() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
index 8b05b80..f7b3711 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_01cd01() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
index 8b05b80..f7b3711 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_01cd01() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.msl
index 8da10e0..6f8d999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_01cd01(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.msl
index a0959f8..e582798 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_01cd01(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.spvasm
index 1a04689..28e33f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/01cd01.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_01cd01 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4int %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4int %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_01cd01
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_01cd01
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_01cd01
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_01cd01
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.glsl
index ff05f1e..1c6bb99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_026217() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_026217() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_026217() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
index 9a049b7..8158b9b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_026217() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_026217();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
index 9a049b7..8158b9b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_026217() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_026217();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.msl
index ac984fb..1f05906 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_026217(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.msl
index bbfe7b2..8ff4a3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_026217(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.spvasm
index edc8dd7..f0bffe1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/026217.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,65 +59,77 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_026217 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageFetch %v4uint %20 %22 Lod %int_1
-               OpStore %res %26
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQueryLevels %uint %20
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_1
+         %34 = OpExtInst %uint %28 UMin %31 %30
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpExtInst %v2uint %28 UMin %39 %38
+         %41 = OpCompositeConstruct %v3uint %40 %27
+         %42 = OpImageFetch %v4uint %20 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4uint %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_026217
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_026217
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_026217
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_026217
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_026217
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
index df9d2ee..4ab5344 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02c48d() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
index df9d2ee..4ab5344 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02c48d() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.msl
index 6ccbec3..a90152f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_02c48d(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.msl
index a07b0ce..383db084 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_02c48d(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.spvasm
index 4b57365..935b41e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/02c48d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_02c48d = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpExtInst %v3uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_02c48d
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_02c48d
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_02c48d
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_02c48d
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.glsl
index 7cc6798..f86513e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_02ef1f() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_02ef1f() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
index 517dd03..d8d1c35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02ef1f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
index 517dd03..d8d1c35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02ef1f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.msl
index 85e46d6..b1724bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_02ef1f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.msl
index a9ad952..192a48b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_02ef1f(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.spvasm
index c5cc2d1..52d05c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/02ef1f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_02ef1f = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpBitcast %v2uint %19
+         %23 = OpExtInst %v2uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_02ef1f
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_02ef1f
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_02ef1f
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_02ef1f
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
index 21433a6..0e341ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_03e03e() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
index 21433a6..0e341ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_03e03e() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.msl
index 0082d5a..9472d71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_03e03e(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.msl
index e6779c4..54c1730 100644
--- a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_03e03e(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(int3(1)));
+  int4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.spvasm
index 3fe11f2..b6be163 100644
--- a/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/03e03e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_03e03e = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %23 = OpExtInst %v3uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_03e03e
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_03e03e
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_03e03e
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_03e03e
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.glsl
index b598576..fa01813 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_045ec9() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_045ec9() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_045ec9() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
index 7a2b298..9bb12e1d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_045ec9() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_045ec9();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
index 7a2b298..9bb12e1d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_045ec9() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_045ec9();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.msl
index 9d08b73..2ce0db4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_045ec9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.msl
index b02488f..e237675 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_045ec9(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.spvasm
index 34be54d..e8fbf66 100644
--- a/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/045ec9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_045ec9 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpExtInst %v3uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_045ec9
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_045ec9
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_045ec9
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_045ec9
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_045ec9
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_045ec9
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.glsl
index 960262c..6f9e027 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_04b911() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_04b911() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_04b911() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
index f91a5f4..cc8bed3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_04b911() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  float res = arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_04b911();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
index f91a5f4..cc8bed3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_04b911() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  float res = arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_04b911();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.msl
index 8b40e3d..1f8ad08 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_04b911(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.msl
index 0b3f07f..c0e63ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_04b911(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.spvasm
index 7327c8a..ceb6545 100644
--- a/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/04b911.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,68 +56,79 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %46 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_04b911 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %uint_1
-         %28 = OpCompositeExtract %float %27 0
-               OpStore %res %28
-         %31 = OpLoad %float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpExtInst %v2uint %29 UMin %37 %36
+         %39 = OpCompositeConstruct %v3uint %38 %28
+         %40 = OpImageFetch %v4float %17 %39 Lod %32
+         %41 = OpCompositeExtract %float %40 0
+               OpStore %res %41
+         %44 = OpLoad %float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %float %textureLoad_04b911
-         %37 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %float %textureLoad_04b911
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %float %textureLoad_04b911
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %47
+         %53 = OpLabel
+         %54 = OpFunctionCall %float %textureLoad_04b911
+         %55 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %55 = OpFunctionCall %float %textureLoad_04b911
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %67 = OpFunctionCall %float %textureLoad_04b911
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %float %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %47
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %float %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.glsl
index c34ab21..c5c105b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_050c33() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_050c33() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_050c33() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
index 86f7f4d..64793c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_050c33() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_050c33();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
index 86f7f4d..64793c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_050c33() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_050c33();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.msl
index 72381c3..661af3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_050c33(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.msl
index 63d1053..ed1531a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_050c33(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.spvasm
index 1834253..578f2cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/050c33.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +60,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_050c33 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_050c33
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_050c33
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_050c33
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_050c33
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_050c33
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_050c33
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
index c874277..49a72b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_054350() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
index c874277..49a72b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_054350() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.msl
index 0d7a776..8741dd8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_054350(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.msl
index 0629540..5a2c442 100644
--- a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_054350(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1u));
+  uint4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.spvasm
index e7c91ba..3a84e44 100644
--- a/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/054350.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,29 +39,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_054350 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %uint_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4uint %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpExtInst %uint %17 UMin %uint_1 %14
+         %18 = OpImageRead %v4uint %12 %16 None
+               OpStore %res %18
+         %21 = OpLoad %v4uint %res None
+               OpReturnValue %21
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4uint %textureLoad_054350
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %23 %22 None
+%fragment_main = OpFunction %void None %24
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4uint %textureLoad_054350
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %27 %26 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %20
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_054350
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%compute_main = OpFunction %void None %24
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4uint %textureLoad_054350
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.glsl
index f467279..eab5e64 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_0674b1() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_0674b1() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_0674b1() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
index d14719c..c47e3b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_0674b1() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0674b1();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
index d14719c..c47e3b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_0674b1() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0674b1();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.msl
index 9202b65..1b3b64e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_0674b1(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.msl
index 0f008cf..c672752 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_0674b1(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.spvasm
index 9135b2e..aee7ddc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/0674b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_0674b1 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_0674b1
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_0674b1
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_0674b1
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_0674b1
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_0674b1
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_0674b1
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.glsl
index 4f88571..2ae3b90 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_06ac37() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_06ac37() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_06ac37() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
index 6b134e7..204a60d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_06ac37() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_06ac37();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
index 6b134e7..204a60d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_06ac37() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_06ac37();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.msl
index c4e814c..5782513 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_06ac37(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.msl
index 741a746..c5b388e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_06ac37(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.spvasm
index 10847e6..51bdd9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/06ac37.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_06ac37 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_06ac37
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_06ac37
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_06ac37
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_06ac37
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_06ac37
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_06ac37
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.glsl
index 3973cc3..5423eac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_072e26() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_072e26() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_072e26() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
index ac743a9..833df87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_072e26() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_072e26();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
index ac743a9..833df87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_072e26() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_072e26();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.msl
index d5cd0d9..a112dcf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_072e26(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.msl
index 46365eb..e26f999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_072e26(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.spvasm
index 06fe8d1..313b6eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/072e26.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_072e26 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_072e26
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_072e26
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_072e26
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_072e26
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_072e26
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_072e26
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.glsl
index 8ad700f..0e392bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_078bc4() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_078bc4() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_078bc4() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
index f37a266..09020ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_078bc4() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_078bc4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
index f37a266..09020ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_078bc4() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_078bc4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.msl
index e409a60..84e0361 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_078bc4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.msl
index 636e3ec..845ce13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_078bc4(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.spvasm
index 9df5f29..77aca96 100644
--- a/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/078bc4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_078bc4 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_078bc4
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_078bc4
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_078bc4
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_078bc4
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_078bc4
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_078bc4
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
index af59a5b..1919fea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_0b515a() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
index af59a5b..1919fea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_0b515a() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.msl
index cdb212e..fd79a37 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_0b515a(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.msl
index fce88c2..ad7be59 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_0b515a(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.spvasm
index b53dc7d..6361c7e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/0b515a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_0b515a = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4int %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4int %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_0b515a
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_0b515a
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_0b515a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_0b515a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.glsl
index 4fc992b..7b328c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_0cb698() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_0cb698() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_0cb698() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_1))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
index c133003..18f50f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_0cb698() {
-  int v = int(1u);
-  int4 res = int4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0cb698();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
index c133003..18f50f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_0cb698() {
-  int v = int(1u);
-  int4 res = int4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0cb698();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.msl
index 936f183..3e3f6d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_0cb698(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.msl
index 07cdcd1..887382f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_0cb698(texture1d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.spvasm
index 3e1f4c4..881c931 100644
--- a/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/0cb698.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +63,63 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_0cb698 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %uint_1 Lod %uint_1
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %uint %20 %25
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageFetch %v4int %20 %29 Lod %25
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_0cb698
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_0cb698
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_0cb698
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_0cb698
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_0cb698
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_0cb698
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.glsl
index 3118bea..b3f8242 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_10db82() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_10db82() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_10db82() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
index 34da83a..6008048 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_10db82() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_10db82();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
index 34da83a..6008048 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_10db82() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_10db82();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.msl
index 36b9f8c..9d64f12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_10db82(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.msl
index 440fb73..8c594ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_10db82(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.spvasm
index e901c64..9a80204 100644
--- a/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/10db82.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_10db82 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_10db82
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_10db82
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_10db82
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_10db82
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_10db82
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_10db82
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.glsl
index e5531b3..1fd40e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_126466() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_126466() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
index 13c0e5f..ce15e68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_126466() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
index 13c0e5f..ce15e68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_126466() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.msl
index 9521487..7cf6bc0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_126466(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.msl
index 02d6e8c..53751f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_126466(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.spvasm
index b11469c..6c54d1e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/126466.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,36 +36,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_126466 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_126466
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_126466
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_126466
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_126466
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.glsl
index 2c35a46..c2ca3ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_127e12() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_127e12() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_127e12() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
index 4a8731e..18717f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_127e12() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_127e12();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
index 4a8731e..18717f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_127e12() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_127e12();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.msl
index 29e502b..36d08ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_127e12(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.msl
index c7c2fb9..82cd635 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_127e12(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.spvasm
index 851320b..5ceef9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/127e12.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_127e12 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageRead %v4uint %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4uint %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_127e12
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_127e12
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_127e12
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_127e12
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_127e12
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.glsl
index 87b3a94..a02547f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_1373dc() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_1373dc() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1373dc() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
index db0eb14..2da7f89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1373dc() {
-  int v = int(1u);
-  float4 res = float4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1373dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
index db0eb14..2da7f89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1373dc() {
-  int v = int(1u);
-  float4 res = float4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1373dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.msl
index 250648f..7f288b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_1373dc(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.msl
index 5a089a6..75d273e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_1373dc(texture1d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.spvasm
index 9faa2ea..bfbe7ac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1373dc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,56 +62,63 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1373dc = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %uint_1 Lod %int_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %uint %17 %25
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageFetch %v4float %17 %29 Lod %25
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_1373dc
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_1373dc
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_1373dc
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_1373dc
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_1373dc
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_1373dc
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.glsl
index 94e4a39..4992b34 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_13d539() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_13d539() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_13d539() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
index 2cd12c4..fde75b9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_13d539() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13d539();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
index 2cd12c4..fde75b9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_13d539() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13d539();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.msl
index 8c7a8e0..c1d4d7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_13d539(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.msl
index 49651ce..8c8961a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_13d539(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.spvasm
index 04dafdd..60f50ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/13d539.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_13d539 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4int %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_13d539
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_13d539
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_13d539
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_13d539
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_13d539
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_13d539
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.glsl
index 02ca5da..4957a70 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_13e90c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_13e90c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_13e90c() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
index c9de707..43c0c68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_13e90c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13e90c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
index c9de707..43c0c68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_13e90c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13e90c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.msl
index 0f57240..1fd4fc8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_13e90c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.msl
index 13eccb4..397d61e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_13e90c(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.spvasm
index 30beabd..3125188 100644
--- a/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/13e90c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_13e90c = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_13e90c
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_13e90c
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_13e90c
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_13e90c
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_13e90c
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_13e90c
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.glsl
index 2ac3b96..e29c1d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_143d84() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_143d84() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_143d84() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
index 390f8b6..6e28018 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_143d84() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_143d84();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
index 390f8b6..6e28018 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_143d84() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_143d84();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.msl
index 9de124a..97b1e42 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_143d84(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.msl
index a54eb76..9372895 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_143d84(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.spvasm
index 018cb6a..ebc8754 100644
--- a/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/143d84.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,67 +57,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_143d84 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_143d84
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_143d84
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_143d84
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_143d84
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_143d84
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_143d84
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.glsl
index 21dc481..d7fabab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_1471b8() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_1471b8() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_1471b8() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
index 9a07027..ba650a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_1471b8() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1471b8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
index 9a07027..ba650a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_1471b8() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1471b8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.msl
index 05cd4a0..f930465 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_1471b8(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.msl
index 1c57db0..472d86f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1471b8(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.spvasm
index 1549125..2c1bb9e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1471b8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1471b8 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4int %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_1471b8
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_1471b8
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_1471b8
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_1471b8
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_1471b8
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_1471b8
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
index 23a82e1..38e50bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_14cc4c() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
index 23a82e1..38e50bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_14cc4c() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.msl
index de724c7..4aa986c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_14cc4c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.msl
index 35ffa7c..d922a7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_14cc4c(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.spvasm
index 497a26c..89d8483 100644
--- a/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/14cc4c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_14cc4c = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_14cc4c
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_14cc4c
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_14cc4c
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_14cc4c
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.glsl
index c6ae649..0352f43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1561a7() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1561a7() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1561a7() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
index a725eb8..ddf1b35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1561a7() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1561a7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
index a725eb8..ddf1b35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1561a7() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1561a7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.msl
index 2ee4e71..8548b0a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_1561a7(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.msl
index 80c6b0a..93a1cd6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1561a7(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.spvasm
index 13ac4ef..d8a8629 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1561a7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1561a7 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %int_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageRead %v4uint %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_1561a7
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4uint %textureLoad_1561a7
          %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_1561a7
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4uint %textureLoad_1561a7
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_1561a7
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.glsl
index 2a3616a..400576c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_15e675() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_15e675() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_15e675() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
index 15c5104..0d035e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_15e675() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_15e675();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
index 15c5104..0d035e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_15e675() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_15e675();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.msl
index d642fb3..5d423b5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_15e675(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.msl
index 93ad418..75ecb82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_15e675(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.spvasm
index cb8ebd7..2b378d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/15e675.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,75 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_15e675 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4uint %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_15e675
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_15e675
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_15e675
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_15e675
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_15e675
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_15e675
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.glsl
index 9b57421..ae90178 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_1619bf() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_1619bf() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
index 6a38654..ce98264 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1619bf() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
index 6a38654..ce98264 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1619bf() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.msl
index d21305e..49c28f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_1619bf(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.msl
index 8361b8f..dbb5f45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1619bf(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.spvasm
index 4c1c056..e624f5e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1619bf.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,46 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_1619bf = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %14
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4int %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_1619bf
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_1619bf
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_1619bf
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_1619bf
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.glsl
index d0ea019..85780c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_168dc8() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_168dc8() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_168dc8() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
index 7432584..32aab27 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_168dc8() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_168dc8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
index 7432584..32aab27 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_168dc8() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_168dc8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.msl
index 8276bd0..823ec36 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_168dc8(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v, v_1);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.msl
index 5927865..f5db185 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_168dc8(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.spvasm
index b2426e9..58752b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/168dc8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_168dc8 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageFetch %v4int %20 %25 Lod %int_1
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %28 %26
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %20 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpExtInst %v2uint %31 UMin %40 %39
+         %42 = OpCompositeConstruct %v3uint %41 %30
+         %43 = OpImageFetch %v4int %20 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4int %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_168dc8
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4int %textureLoad_168dc8
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_168dc8
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %49
+         %55 = OpLabel
          %56 = OpFunctionCall %v4int %textureLoad_168dc8
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_168dc8
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
index e24fb8a..32c0603 100644
--- a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_170593() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
index e24fb8a..32c0603 100644
--- a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_170593() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.msl
index 9705c49..dfbc96f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_170593(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.msl
index 4c326e0..82d0534 100644
--- a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_170593(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.spvasm
index 608560d..ccd64a9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/170593.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_170593 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpBitcast %v2uint %19
+         %23 = OpExtInst %v2uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_170593
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_170593
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_170593
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_170593
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
index 4e94659..3e3b040 100644
--- a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_17095b() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
index 4e94659..3e3b040 100644
--- a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_17095b() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.msl
index 8cc46ba..47d2f5e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_17095b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.msl
index 4f154c2..ede176d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_17095b(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1u));
+  uint4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.spvasm
index 8a0fc66..6b026bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/17095b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,29 +39,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_17095b = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %uint_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4uint %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpExtInst %uint %17 UMin %uint_1 %14
+         %18 = OpImageRead %v4uint %12 %16 None
+               OpStore %res %18
+         %21 = OpLoad %v4uint %res None
+               OpReturnValue %21
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4uint %textureLoad_17095b
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %23 %22 None
+%fragment_main = OpFunction %void None %24
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4uint %textureLoad_17095b
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %27 %26 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %20
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_17095b
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%compute_main = OpFunction %void None %24
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4uint %textureLoad_17095b
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.glsl
index c85c3eb..9edbc61 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_18ac11() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_18ac11() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_18ac11() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
index 55b4dd1..48d881d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_18ac11() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_18ac11();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
index 55b4dd1..48d881d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_18ac11() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_18ac11();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.msl
index 73dca8f..9ee625c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_18ac11(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.msl
index 836c82f..60df6b9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_18ac11(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.spvasm
index 00efd4d..5f798f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/18ac11.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,57 +65,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_18ac11 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %uint_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageRead %v4int %20 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4int %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_18ac11
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_18ac11
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_18ac11
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_18ac11
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_18ac11
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %54 = OpFunctionCall %v4int %textureLoad_18ac11
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4int %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.glsl
index 08cc4e8..ddbf076 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_19cf87() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_19cf87() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_19cf87() {
-  ivec2 v = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v, int(1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
index 1f0d01c..16e0307 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_19cf87() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(int3(v, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float res = arg_0.Load(int3(v_4, int(v_1))).x;
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19cf87();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
index 1f0d01c..16e0307 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_19cf87() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(int3(v, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float res = arg_0.Load(int3(v_4, int(v_1))).x;
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19cf87();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.msl
index d1b4016..eea0a36 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float textureLoad_19cf87(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.msl
index 51cf861..567d0e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_19cf87(depth2d<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.spvasm
index 558cec9..f6b2d2d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/19cf87.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,76 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %42 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_19cf87 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-         %23 = OpCompositeExtract %float %18 0
-               OpStore %res %23
-         %26 = OpLoad %float %res None
-               OpReturnValue %26
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v2uint %17 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %34 = OpExtInst %v2uint %26 UMin %31 %29
+         %35 = OpImageFetch %v4float %17 %34 Lod %25
+         %36 = OpCompositeExtract %float %35 0
+               OpStore %res %36
+         %39 = OpLoad %float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %float %textureLoad_19cf87
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %37 = OpLabel
-         %38 = OpFunctionCall %float %textureLoad_19cf87
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %39 %38 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%fragment_main = OpFunction %void None %42
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_19cf87
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+         %44 = OpFunctionCall %float %textureLoad_19cf87
+         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %float %textureLoad_19cf87
+         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %51 %50 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %54
          %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %63 = OpFunctionCall %float %textureLoad_19cf87
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %float %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.glsl
index 97766a5..504c03d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_19d6be() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_19d6be() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
index b0299c3..968f315 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_19d6be() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
index b0299c3..968f315 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_19d6be() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.msl
index c8b1837..575ae4a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_19d6be(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.msl
index 98b17a2..c06fcd3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_19d6be(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.spvasm
index 549dbfa..58cf379 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/19d6be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_19d6be = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpExtInst %v3uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_19d6be
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_19d6be
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_19d6be
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_19d6be
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.glsl
index 791c2fc..15aeb47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_19e5ca() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_19e5ca() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_19e5ca() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
index af83c9d..d54d25e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_19e5ca() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19e5ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
index af83c9d..d54d25e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_19e5ca() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19e5ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.msl
index 87bb060..e1cd67b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_19e5ca(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.msl
index c314532..d2641e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_19e5ca(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.spvasm
index 23cb6ce..3c3f74d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/19e5ca.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,67 +57,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_19e5ca = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_19e5ca
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_19e5ca
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_19e5ca
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_19e5ca
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_19e5ca
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_19e5ca
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.glsl
index 77cb816..abbfceb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_1a062f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_1a062f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1a062f() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
index ed8abaf..e035c69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1a062f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a062f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
index ed8abaf..e035c69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1a062f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a062f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.msl
index f43c904..f4c0305 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_1a062f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.msl
index 4248286..4953def 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_1a062f(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.spvasm
index 1a62df1..4315159 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1a062f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1a062f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_1a062f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_1a062f
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_1a062f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_1a062f
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_1a062f
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_1a062f
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.glsl
index 065e4bb..541b164 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1a8452() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1a8452() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1a8452() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
index 7af6919..e9e6a6c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1a8452() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a8452();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
index 7af6919..e9e6a6c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1a8452() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a8452();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.msl
index b284faf..321462e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_1a8452(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.msl
index f2b27af..3341c9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1a8452(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.spvasm
index ede44c6..9b43276 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1a8452.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1a8452 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %int_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageRead %v4uint %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_1a8452
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4uint %textureLoad_1a8452
          %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_1a8452
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4uint %textureLoad_1a8452
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_1a8452
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.glsl
index c889318..0d3d992 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_1aa950() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_1aa950() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_1aa950() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
index af64b60..18f6fbb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_1aa950() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1aa950();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
index af64b60..18f6fbb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_1aa950() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1aa950();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.msl
index 1f4f9f5..d5fa4e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_1aa950(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.msl
index 54eaae8..0951203 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1aa950(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.spvasm
index 9d59d69..81c14ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1aa950.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,76 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1aa950 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %38 = OpExtInst %v2uint %28 UMin %34 %32
+         %39 = OpCompositeConstruct %v3uint %38 %27
+         %40 = OpImageRead %v4int %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_1aa950
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_1aa950
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_1aa950
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_1aa950
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_1aa950
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_1aa950
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.glsl
index f3e0f5f..f7d57df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_1b051f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_1b051f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1b051f() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
index 550596a..52e7065 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1b051f() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b051f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
index 550596a..52e7065 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1b051f() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b051f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.msl
index 94f9a0b..63a92f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_1b051f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.msl
index 1cd2848..c387cdf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b051f(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.spvasm
index e56aa41..bc1b608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1b051f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,67 +58,80 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %38 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1b051f = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageFetch %v4uint %20 %25 Lod %uint_1
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQueryLevels %uint %20
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpExtInst %uint %28 UMin %uint_1 %30
+         %32 = OpImageQuerySizeLod %v3uint %20 %31
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %38
+         %42 = OpExtInst %v2uint %28 UMin %37 %35
+         %43 = OpCompositeConstruct %v3uint %42 %27
+         %44 = OpImageFetch %v4uint %20 %43 Lod %31
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_1b051f
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_1b051f
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_1b051f
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %50
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4uint %textureLoad_1b051f
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_1b051f
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %70 = OpFunctionCall %v4uint %textureLoad_1b051f
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4uint %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.glsl
index 6527d34..f9bb8e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_1b4332() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_1b4332() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
index 250cb2b..10bb2a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_1b4332() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
index 250cb2b..10bb2a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_1b4332() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.msl
index 8d5abcb..7bbc0df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_1b4332(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.msl
index 03ba2cd..0d88129 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b4332(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(int3(1)));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.spvasm
index 69d4656..bd478a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1b4332.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_1b4332 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpBitcast %v3uint %19
+         %23 = OpExtInst %v3uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_1b4332
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_1b4332
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_1b4332
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_1b4332
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.glsl
index e88be88..768dd31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_1b8588() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_1b8588() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1b8588() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
index 23d2cc3..70bb92c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1b8588() {
-  int v = int(int(1));
-  uint4 res = uint4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b8588();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
index 23d2cc3..70bb92c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1b8588() {
-  int v = int(int(1));
-  uint4 res = uint4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b8588();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.msl
index cdff360..ebd5758 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_1b8588(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.msl
index 058e9e0..38f1baf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b8588(texture1d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.spvasm
index aeea7e6..b9f21b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1b8588.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1b8588 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %int_1 Lod %int_1
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %uint %20 %27
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %28 UMin %31 %30
+         %33 = OpImageFetch %v4uint %20 %32 Lod %27
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_1b8588
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_1b8588
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_1b8588
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_1b8588
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_1b8588
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_1b8588
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
index 24d6f90..17497ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1bc5ab() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
index 24d6f90..17497ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1bc5ab() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.msl
index 3427574..6fd7312 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_1bc5ab(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.msl
index a98a997..20e424c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_1bc5ab(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.spvasm
index 259062b..5428c89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1bc5ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1bc5ab = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_1bc5ab
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_1bc5ab
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_1bc5ab
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_1bc5ab
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.glsl
index 74f0f52..dd95220 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.glsl
@@ -105,7 +105,8 @@
   return tint_ExternalTextureParams(tint_input.numPlanes, tint_input.doYuvToRgbConversionOnly, tint_input.yuvToRgbConversionMatrix, tint_input.gammaDecodeParams, tint_input.gammaEncodeParams, v_15, v_16, mat3x2(tint_input.loadTransform_col0, tint_input.loadTransform_col1, tint_input.loadTransform_col2), tint_input.samplePlane0RectMin, tint_input.samplePlane0RectMax, tint_input.samplePlane1RectMin, tint_input.samplePlane1RectMax, tint_input.apparentSize, tint_input.plane1CoordFactor);
 }
 vec4 textureLoad_1bfdfb() {
-  vec4 res = tint_TextureLoadExternal(tint_convert_tint_ExternalTextureParams(v_2.inner), uvec2(1u));
+  tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(1u), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 void main() {
@@ -216,7 +217,8 @@
   return tint_ExternalTextureParams(tint_input.numPlanes, tint_input.doYuvToRgbConversionOnly, tint_input.yuvToRgbConversionMatrix, tint_input.gammaDecodeParams, tint_input.gammaEncodeParams, v_15, v_16, mat3x2(tint_input.loadTransform_col0, tint_input.loadTransform_col1, tint_input.loadTransform_col2), tint_input.samplePlane0RectMin, tint_input.samplePlane0RectMax, tint_input.samplePlane1RectMin, tint_input.samplePlane1RectMax, tint_input.apparentSize, tint_input.plane1CoordFactor);
 }
 vec4 textureLoad_1bfdfb() {
-  vec4 res = tint_TextureLoadExternal(tint_convert_tint_ExternalTextureParams(v_2.inner), uvec2(1u));
+  tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(1u), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -330,7 +332,8 @@
   return tint_ExternalTextureParams(tint_input.numPlanes, tint_input.doYuvToRgbConversionOnly, tint_input.yuvToRgbConversionMatrix, tint_input.gammaDecodeParams, tint_input.gammaEncodeParams, v_14, v_15, mat3x2(tint_input.loadTransform_col0, tint_input.loadTransform_col1, tint_input.loadTransform_col2), tint_input.samplePlane0RectMin, tint_input.samplePlane0RectMax, tint_input.samplePlane1RectMin, tint_input.samplePlane1RectMax, tint_input.apparentSize, tint_input.plane1CoordFactor);
 }
 vec4 textureLoad_1bfdfb() {
-  vec4 res = tint_TextureLoadExternal(tint_convert_tint_ExternalTextureParams(v_1.inner), uvec2(1u));
+  tint_ExternalTextureParams v_16 = tint_convert_tint_ExternalTextureParams(v_1.inner);
+  vec4 res = tint_TextureLoadExternal(v_16, min(uvec2(1u), ((v_16.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -340,10 +343,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_16 = vertex_main_inner();
-  gl_Position = v_16.pos;
+  VertexOutput v_17 = vertex_main_inner();
+  gl_Position = v_17.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_16.prevent_dce;
+  vertex_main_loc0_Output = v_17.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
index c67ac10..4c6e752 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
@@ -60,78 +60,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_1bfdfb() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, (1u).xx);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, (1u).xx);
   return res;
 }
 
@@ -148,13 +161,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1bfdfb();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
index c67ac10..4c6e752 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
@@ -60,78 +60,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_1bfdfb() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, (1u).xx);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, (1u).xx);
   return res;
 }
 
@@ -148,13 +161,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1bfdfb();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.msl
index e83af94..f6bac6c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.ir.msl
@@ -124,7 +124,8 @@
 }
 
 float4 textureLoad_1bfdfb(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, tint_load_struct_packed_vec3(tint_module_vars.arg_0_params), uint2(1u));
+  tint_ExternalTextureParams const v_19 = tint_load_struct_packed_vec3(tint_module_vars.arg_0_params);
+  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, min(uint2(1u), ((v_19.apparentSize + uint2(1u)) - uint2(1u))));
   return res;
 }
 
@@ -147,9 +148,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0_plane0 [[texture(0)]], texture2d<float, access::sample> arg_0_plane1 [[texture(1)]], const constant tint_ExternalTextureParams_packed_vec3* arg_0_params [[buffer(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0_plane0=arg_0_plane0, .arg_0_plane1=arg_0_plane1, .arg_0_params=arg_0_params};
-  VertexOutput const v_19 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_20 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_19.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_19.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_20.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_20.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.msl
index 43e5287..656cadd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.msl
@@ -119,7 +119,7 @@
 }
 
 float4 textureLoad_1bfdfb(texture2d<float, access::sample> tint_symbol_1, texture2d<float, access::sample> tint_symbol_2, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_3) {
-  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, uint2(1u), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
+  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, min(uint2(1u), (((*(tint_symbol_3)).apparentSize + uint2(1u)) - uint2(1u))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.spvasm
index fa5fae4..5365c6f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1bfdfb.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 181
+; Bound: 185
 ; Schema: 0
                OpCapability Shader
-         %81 = OpExtInstImport "GLSL.std.450"
+         %45 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -191,19 +191,19 @@
          %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %48 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %59 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %63 = OpConstantNull %VertexOutput
-         %65 = OpConstantNull %v4float
-         %73 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
+         %68 = OpConstantNull %VertexOutput
+         %70 = OpConstantNull %v4float
+         %78 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
        %bool = OpTypeBool
-        %122 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+        %126 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %155 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %159 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
 %textureLoad_1bfdfb = OpFunction %v4float None %26
          %27 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
@@ -212,159 +212,163 @@
          %30 = OpAccessChain %_ptr_Uniform_tint_ExternalTextureParams_std140 %10 %uint_0
          %33 = OpLoad %tint_ExternalTextureParams_std140 %30 None
          %34 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %33
-         %39 = OpFunctionCall %v4float %tint_TextureLoadExternal %28 %29 %34 %41
-               OpStore %res %39
-         %45 = OpLoad %v4float %res None
-               OpReturnValue %45
+         %39 = OpCompositeExtract %v2uint %34 12
+         %40 = OpIAdd %v2uint %39 %41
+         %43 = OpISub %v2uint %40 %41
+         %44 = OpExtInst %v2uint %45 UMin %41 %43
+         %46 = OpFunctionCall %v4float %tint_TextureLoadExternal %28 %29 %34 %44
+               OpStore %res %46
+         %50 = OpLoad %v4float %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %48
-         %49 = OpLabel
-         %50 = OpFunctionCall %v4float %textureLoad_1bfdfb
-         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %51 %50 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %48
+%fragment_main = OpFunction %void None %53
          %54 = OpLabel
          %55 = OpFunctionCall %v4float %textureLoad_1bfdfb
          %56 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %59
-         %60 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %63
-         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %64 %65 None
-         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %67 = OpFunctionCall %v4float %textureLoad_1bfdfb
-               OpStore %66 %67 None
-         %68 = OpLoad %VertexOutput %out None
-               OpReturnValue %68
+%compute_main = OpFunction %void None %53
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4float %textureLoad_1bfdfb
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
+               OpReturn
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %73
+%vertex_main_inner = OpFunction %VertexOutput None %64
+         %65 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %70 None
+         %71 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %72 = OpFunctionCall %v4float %textureLoad_1bfdfb
+               OpStore %71 %72 None
+         %73 = OpLoad %VertexOutput %out None
+               OpReturnValue %73
+               OpFunctionEnd
+%tint_TextureLoadExternal = OpFunction %v4float None %78
     %plane_0 = OpFunctionParameter %8
     %plane_1 = OpFunctionParameter %8
      %params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2uint
-         %74 = OpLabel
-         %75 = OpCompositeExtract %uint %params 1
-         %76 = OpCompositeExtract %mat3v4float %params 2
-         %77 = OpCompositeExtract %mat3v2float %params 7
-         %78 = OpCompositeExtract %v2uint %params 12
-         %79 = OpCompositeExtract %v2float %params 13
-         %80 = OpExtInst %v2uint %81 UMin %coords %78
-         %82 = OpConvertUToF %v2float %80
-         %83 = OpCompositeConstruct %v3float %82 %float_1
-         %85 = OpMatrixTimesVector %v2float %77 %83
-         %86 = OpExtInst %v2float %81 RoundEven %85
-         %87 = OpConvertFToU %v2uint %86
-         %88 = OpCompositeExtract %uint %params 0
-         %89 = OpIEqual %bool %88 %uint_1
-               OpSelectionMerge %91 None
-               OpBranchConditional %89 %92 %93
-         %92 = OpLabel
-         %94 = OpImageFetch %v4float %plane_0 %87 Lod %uint_0
-         %95 = OpVectorShuffle %v3float %94 %94 0 1 2
-         %96 = OpCompositeExtract %float %94 3
-               OpBranch %91
-         %93 = OpLabel
-         %97 = OpImageFetch %v4float %plane_0 %87 Lod %uint_0
-         %98 = OpCompositeExtract %float %97 0
-         %99 = OpFMul %v2float %86 %79
-        %100 = OpConvertFToU %v2uint %99
-        %101 = OpImageFetch %v4float %plane_1 %100 Lod %uint_0
-        %102 = OpVectorShuffle %v2float %101 %101 0 1
-        %103 = OpCompositeConstruct %v4float %98 %102 %float_1
-        %104 = OpVectorTimesMatrix %v3float %103 %76
-               OpBranch %91
-         %91 = OpLabel
-        %105 = OpPhi %v3float %95 %92 %104 %93
-        %106 = OpPhi %float %96 %92 %float_1 %93
-        %107 = OpIEqual %bool %75 %uint_0
-               OpSelectionMerge %108 None
-               OpBranchConditional %107 %109 %110
-        %109 = OpLabel
-        %111 = OpCompositeExtract %tint_GammaTransferParams %params 3
-        %112 = OpCompositeExtract %tint_GammaTransferParams %params 4
-        %113 = OpCompositeExtract %mat3v3float %params 5
-        %114 = OpFunctionCall %v3float %tint_GammaCorrection %105 %111
-        %116 = OpMatrixTimesVector %v3float %113 %114
-        %117 = OpFunctionCall %v3float %tint_GammaCorrection %116 %112
-               OpBranch %108
-        %110 = OpLabel
-               OpBranch %108
-        %108 = OpLabel
-        %118 = OpPhi %v3float %117 %109 %105 %110
-        %119 = OpCompositeConstruct %v4float %118 %106
-               OpReturnValue %119
+         %79 = OpLabel
+         %80 = OpCompositeExtract %uint %params 1
+         %81 = OpCompositeExtract %mat3v4float %params 2
+         %82 = OpCompositeExtract %mat3v2float %params 7
+         %83 = OpCompositeExtract %v2uint %params 12
+         %84 = OpCompositeExtract %v2float %params 13
+         %85 = OpExtInst %v2uint %45 UMin %coords %83
+         %86 = OpConvertUToF %v2float %85
+         %87 = OpCompositeConstruct %v3float %86 %float_1
+         %89 = OpMatrixTimesVector %v2float %82 %87
+         %90 = OpExtInst %v2float %45 RoundEven %89
+         %91 = OpConvertFToU %v2uint %90
+         %92 = OpCompositeExtract %uint %params 0
+         %93 = OpIEqual %bool %92 %uint_1
+               OpSelectionMerge %95 None
+               OpBranchConditional %93 %96 %97
+         %96 = OpLabel
+         %98 = OpImageFetch %v4float %plane_0 %91 Lod %uint_0
+         %99 = OpVectorShuffle %v3float %98 %98 0 1 2
+        %100 = OpCompositeExtract %float %98 3
+               OpBranch %95
+         %97 = OpLabel
+        %101 = OpImageFetch %v4float %plane_0 %91 Lod %uint_0
+        %102 = OpCompositeExtract %float %101 0
+        %103 = OpFMul %v2float %90 %84
+        %104 = OpConvertFToU %v2uint %103
+        %105 = OpImageFetch %v4float %plane_1 %104 Lod %uint_0
+        %106 = OpVectorShuffle %v2float %105 %105 0 1
+        %107 = OpCompositeConstruct %v4float %102 %106 %float_1
+        %108 = OpVectorTimesMatrix %v3float %107 %81
+               OpBranch %95
+         %95 = OpLabel
+        %109 = OpPhi %v3float %99 %96 %108 %97
+        %110 = OpPhi %float %100 %96 %float_1 %97
+        %111 = OpIEqual %bool %80 %uint_0
+               OpSelectionMerge %112 None
+               OpBranchConditional %111 %113 %114
+        %113 = OpLabel
+        %115 = OpCompositeExtract %tint_GammaTransferParams %params 3
+        %116 = OpCompositeExtract %tint_GammaTransferParams %params 4
+        %117 = OpCompositeExtract %mat3v3float %params 5
+        %118 = OpFunctionCall %v3float %tint_GammaCorrection %109 %115
+        %120 = OpMatrixTimesVector %v3float %117 %118
+        %121 = OpFunctionCall %v3float %tint_GammaCorrection %120 %116
+               OpBranch %112
+        %114 = OpLabel
+               OpBranch %112
+        %112 = OpLabel
+        %122 = OpPhi %v3float %121 %113 %109 %114
+        %123 = OpCompositeConstruct %v4float %122 %110
+               OpReturnValue %123
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %122
+%tint_GammaCorrection = OpFunction %v3float None %126
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-        %123 = OpLabel
-        %124 = OpCompositeExtract %float %params_0 0
-        %125 = OpCompositeExtract %float %params_0 1
-        %126 = OpCompositeExtract %float %params_0 2
-        %127 = OpCompositeExtract %float %params_0 3
-        %128 = OpCompositeExtract %float %params_0 4
-        %129 = OpCompositeExtract %float %params_0 5
-        %130 = OpCompositeExtract %float %params_0 6
-        %131 = OpCompositeConstruct %v3float %124 %124 %124
-        %132 = OpCompositeConstruct %v3float %128 %128 %128
-        %133 = OpExtInst %v3float %81 FAbs %v
-        %134 = OpExtInst %v3float %81 FSign %v
-        %135 = OpFOrdLessThan %v3bool %133 %132
-        %137 = OpVectorTimesScalar %v3float %133 %127
-        %138 = OpCompositeConstruct %v3float %130 %130 %130
-        %139 = OpFAdd %v3float %137 %138
-        %140 = OpFMul %v3float %134 %139
-        %141 = OpVectorTimesScalar %v3float %133 %125
-        %142 = OpCompositeConstruct %v3float %126 %126 %126
+        %127 = OpLabel
+        %128 = OpCompositeExtract %float %params_0 0
+        %129 = OpCompositeExtract %float %params_0 1
+        %130 = OpCompositeExtract %float %params_0 2
+        %131 = OpCompositeExtract %float %params_0 3
+        %132 = OpCompositeExtract %float %params_0 4
+        %133 = OpCompositeExtract %float %params_0 5
+        %134 = OpCompositeExtract %float %params_0 6
+        %135 = OpCompositeConstruct %v3float %128 %128 %128
+        %136 = OpCompositeConstruct %v3float %132 %132 %132
+        %137 = OpExtInst %v3float %45 FAbs %v
+        %138 = OpExtInst %v3float %45 FSign %v
+        %139 = OpFOrdLessThan %v3bool %137 %136
+        %141 = OpVectorTimesScalar %v3float %137 %131
+        %142 = OpCompositeConstruct %v3float %134 %134 %134
         %143 = OpFAdd %v3float %141 %142
-        %144 = OpExtInst %v3float %81 Pow %143 %131
-        %145 = OpCompositeConstruct %v3float %129 %129 %129
-        %146 = OpFAdd %v3float %144 %145
-        %147 = OpFMul %v3float %134 %146
-        %148 = OpSelect %v3float %135 %140 %147
-               OpReturnValue %148
+        %144 = OpFMul %v3float %138 %143
+        %145 = OpVectorTimesScalar %v3float %137 %129
+        %146 = OpCompositeConstruct %v3float %130 %130 %130
+        %147 = OpFAdd %v3float %145 %146
+        %148 = OpExtInst %v3float %45 Pow %147 %135
+        %149 = OpCompositeConstruct %v3float %133 %133 %133
+        %150 = OpFAdd %v3float %148 %149
+        %151 = OpFMul %v3float %138 %150
+        %152 = OpSelect %v3float %139 %144 %151
+               OpReturnValue %152
                OpFunctionEnd
-%vertex_main = OpFunction %void None %48
-        %150 = OpLabel
-        %151 = OpFunctionCall %VertexOutput %vertex_main_inner
-        %152 = OpCompositeExtract %v4float %151 0
-               OpStore %vertex_main_position_Output %152 None
-        %153 = OpCompositeExtract %v4float %151 1
-               OpStore %vertex_main_loc0_Output %153 None
+%vertex_main = OpFunction %void None %53
+        %154 = OpLabel
+        %155 = OpFunctionCall %VertexOutput %vertex_main_inner
+        %156 = OpCompositeExtract %v4float %155 0
+               OpStore %vertex_main_position_Output %156 None
+        %157 = OpCompositeExtract %v4float %155 1
+               OpStore %vertex_main_loc0_Output %157 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %155
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %159
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %156 = OpLabel
-        %157 = OpCompositeExtract %uint %tint_input 0
-        %158 = OpCompositeExtract %uint %tint_input 1
-        %159 = OpCompositeExtract %mat3v4float %tint_input 2
-        %160 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %161 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %162 = OpCompositeExtract %v3float %tint_input 5
-        %163 = OpCompositeExtract %v3float %tint_input 6
-        %164 = OpCompositeExtract %v3float %tint_input 7
-        %165 = OpCompositeConstruct %mat3v3float %162 %163 %164
-        %166 = OpCompositeExtract %v2float %tint_input 8
-        %167 = OpCompositeExtract %v2float %tint_input 9
-        %168 = OpCompositeExtract %v2float %tint_input 10
-        %169 = OpCompositeConstruct %mat3v2float %166 %167 %168
-        %170 = OpCompositeExtract %v2float %tint_input 11
-        %171 = OpCompositeExtract %v2float %tint_input 12
-        %172 = OpCompositeExtract %v2float %tint_input 13
+        %160 = OpLabel
+        %161 = OpCompositeExtract %uint %tint_input 0
+        %162 = OpCompositeExtract %uint %tint_input 1
+        %163 = OpCompositeExtract %mat3v4float %tint_input 2
+        %164 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %165 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %166 = OpCompositeExtract %v3float %tint_input 5
+        %167 = OpCompositeExtract %v3float %tint_input 6
+        %168 = OpCompositeExtract %v3float %tint_input 7
+        %169 = OpCompositeConstruct %mat3v3float %166 %167 %168
+        %170 = OpCompositeExtract %v2float %tint_input 8
+        %171 = OpCompositeExtract %v2float %tint_input 9
+        %172 = OpCompositeExtract %v2float %tint_input 10
         %173 = OpCompositeConstruct %mat3v2float %170 %171 %172
-        %174 = OpCompositeExtract %v2float %tint_input 14
-        %175 = OpCompositeExtract %v2float %tint_input 15
-        %176 = OpCompositeExtract %v2float %tint_input 16
-        %177 = OpCompositeExtract %v2float %tint_input 17
-        %178 = OpCompositeExtract %v2uint %tint_input 18
-        %179 = OpCompositeExtract %v2float %tint_input 19
-        %180 = OpCompositeConstruct %tint_ExternalTextureParams %157 %158 %159 %160 %161 %165 %169 %173 %174 %175 %176 %177 %178 %179
-               OpReturnValue %180
+        %174 = OpCompositeExtract %v2float %tint_input 11
+        %175 = OpCompositeExtract %v2float %tint_input 12
+        %176 = OpCompositeExtract %v2float %tint_input 13
+        %177 = OpCompositeConstruct %mat3v2float %174 %175 %176
+        %178 = OpCompositeExtract %v2float %tint_input 14
+        %179 = OpCompositeExtract %v2float %tint_input 15
+        %180 = OpCompositeExtract %v2float %tint_input 16
+        %181 = OpCompositeExtract %v2float %tint_input 17
+        %182 = OpCompositeExtract %v2uint %tint_input 18
+        %183 = OpCompositeExtract %v2float %tint_input 19
+        %184 = OpCompositeConstruct %tint_ExternalTextureParams %161 %162 %163 %164 %165 %169 %173 %177 %178 %179 %180 %181 %182 %183
+               OpReturnValue %184
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.glsl
index f47989f..0a498f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_1c562a() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_1c562a() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1c562a() {
-  ivec3 v = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_2 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
index 8e9600d..edd9bea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1c562a() {
-  int3 v = int3((1u).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1c562a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
index 8e9600d..edd9bea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1c562a() {
-  int3 v = int3((1u).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1c562a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.msl
index 6241217..46a93d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_1c562a(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.msl
index 6e1ddff..1775949 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_1c562a(texture3d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.spvasm
index cbd5ecb..b90244f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1c562a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+     %v3uint = OpTypeVector %uint 3
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1c562a = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %uint_1
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpISub %v3uint %26 %29
+         %30 = OpExtInst %v3uint %25 UMin %29 %28
+         %31 = OpImageFetch %v4uint %20 %30 Lod %24
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_1c562a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_1c562a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_1c562a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_1c562a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_1c562a
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_1c562a
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
index eb20ef7..35f0b07 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1d43ae() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
index eb20ef7..35f0b07 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1d43ae() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.msl
index 6141bcc..bec4f00 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_1d43ae(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.msl
index b341794..f169600 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1d43ae(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1));
+  int4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.spvasm
index f8582ae..273208d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1d43ae.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_1d43ae = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %int_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4int %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %17 %15
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4int %textureLoad_1d43ae
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %23 %22 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %20
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4int %textureLoad_1d43ae
          %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_1d43ae
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.glsl
index ace6dad..8989909 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_1e6baa() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_1e6baa() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
index 012f1d5..aaf2faf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1e6baa() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
index 012f1d5..aaf2faf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1e6baa() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.msl
index 688e6a6..e925ad6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_1e6baa(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.msl
index d132251..106dd90 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_1e6baa(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.spvasm
index f894bfa..5c42b48 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1e6baa.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,29 +41,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1e6baa = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_1e6baa
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_1e6baa
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_1e6baa
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_1e6baa
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.glsl
index 7a20af9..e4b0f8a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_1eb93f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_1eb93f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1eb93f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
index ef9c2b8..4f92297 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1eb93f() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1eb93f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
index ef9c2b8..4f92297 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1eb93f() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1eb93f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.msl
index 0562aac..6ef0100 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_1eb93f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.msl
index 6df6b20..9bed955 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_1eb93f(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.spvasm
index 9ec9051..28cc004 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1eb93f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,59 +60,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1eb93f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_1eb93f
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_1eb93f
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_1eb93f
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_1eb93f
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_1eb93f
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_1eb93f
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.glsl
index c4ef13c..f53084c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_1f2016() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_1f2016() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1f2016() {
-  ivec3 v = ivec3(ivec3(1));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
index 9f5053c..6c995d7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1f2016() {
-  int3 v = int3((int(1)).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1f2016();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
index 9f5053c..6c995d7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1f2016() {
-  int3 v = int3((int(1)).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1f2016();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.msl
index 2eb6cb5..840e619 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_1f2016(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.msl
index 38dbac1..a7df53a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_1f2016(texture3d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.spvasm
index 4929570..88624ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1f2016.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+         %30 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+      %v3int = OpTypeVector %int 3
+         %32 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1f2016 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v3uint %17 %25
+         %29 = OpISub %v3uint %27 %30
+         %31 = OpBitcast %v3uint %32
+         %34 = OpExtInst %v3uint %26 UMin %31 %29
+         %35 = OpImageFetch %v4float %17 %34 Lod %25
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_1f2016
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_1f2016
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%fragment_main = OpFunction %void None %41
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_1f2016
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %43 = OpFunctionCall %v4float %textureLoad_1f2016
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_1f2016
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_1f2016
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.glsl
index b492b60..27c2ce4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_1fde63() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_1fde63() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
index ce16e12..c7acb3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1fde63() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
index ce16e12..c7acb3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1fde63() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.msl
index 192b10e..83f5b54 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_1fde63(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.msl
index 7bad568..b983f540 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_1fde63(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.spvasm
index 94abe23..30f9536 100644
--- a/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/1fde63.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1fde63 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_1fde63
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_1fde63
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_1fde63
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_1fde63
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.glsl
index b775ccd..1f0565f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_206a08() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_206a08() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_206a08() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
index f536dfc..f163a12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_206a08() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_206a08();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
index f536dfc..f163a12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_206a08() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_206a08();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.msl
index 2a564bf..cff9ad6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_206a08(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.msl
index eae7223..33a59f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_206a08(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.spvasm
index 2b21136..08cd60b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/206a08.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +63,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_206a08 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %uint_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageRead %v4uint %20 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_206a08
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_206a08
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_206a08
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_206a08
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_206a08
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %53 = OpFunctionCall %v4uint %textureLoad_206a08
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.glsl
index f97e08d..ccceb57 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_20fa2f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_20fa2f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_20fa2f() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
index f95e1ef..33c89b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_20fa2f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_20fa2f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
index f95e1ef..33c89b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_20fa2f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_20fa2f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.msl
index 68ef344..76a29ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_20fa2f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.msl
index 9a0d01b..a82d236 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_20fa2f(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.spvasm
index 84b9c8f..52dd883 100644
--- a/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/20fa2f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_20fa2f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_20fa2f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_20fa2f
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_20fa2f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_20fa2f
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_20fa2f
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_20fa2f
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.glsl
index cbc8011..e17cbae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_216c37() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_216c37() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_216c37() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
index e8fa3db..48831ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_216c37() {
-  int v = int(1u);
-  uint4 res = uint4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_216c37();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
index e8fa3db..48831ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_216c37() {
-  int v = int(1u);
-  uint4 res = uint4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_216c37();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.msl
index 5fea686..c6544c6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_216c37(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.msl
index a383da0..7399354 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_216c37(texture1d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.spvasm
index a9cfa5d..5556086 100644
--- a/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/216c37.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,64 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_216c37 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %uint_1 Lod %int_1
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %uint %20 %27
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpExtInst %uint %28 UMin %uint_1 %30
+         %32 = OpImageFetch %v4uint %20 %31 Lod %27
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_216c37
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_216c37
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_216c37
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_216c37
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_216c37
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_216c37
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.glsl
index 99d0891..d812720 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_21d1c4() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_21d1c4() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_21d1c4() {
-  ivec3 v = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_2 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
index 212b544..6c7153b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_21d1c4() {
-  int3 v = int3((1u).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_21d1c4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
index 212b544..6c7153b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_21d1c4() {
-  int3 v = int3((1u).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_21d1c4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.msl
index 1853274..6770175 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_21d1c4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.msl
index 53d7d9d..6e8258b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_21d1c4(texture3d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.spvasm
index e3c8b66..837155c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/21d1c4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,61 +56,67 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+     %v3uint = OpTypeVector %uint 3
+         %27 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_21d1c4 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v3uint %17 %22
+         %26 = OpISub %v3uint %24 %27
+         %28 = OpExtInst %v3uint %23 UMin %27 %26
+         %29 = OpImageFetch %v4float %17 %28 Lod %22
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_21d1c4
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_21d1c4
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_21d1c4
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_21d1c4
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_21d1c4
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_21d1c4
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.glsl
index da687b2..128a42a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_223246() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_223246() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_223246() {
-  ivec3 v = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
index 15bb350..7e159ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_223246() {
-  int3 v = int3((1u).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_223246();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
index 15bb350..7e159ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_223246() {
-  int3 v = int3((1u).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_223246();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.msl
index 8220777..1bff21e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_223246(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.msl
index bc14ccc..5c3b455 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_223246(texture3d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.spvasm
index 6c69afc..757700e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/223246.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,63 +59,70 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
+         %32 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_223246 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpISub %v3uint %29 %32
+         %33 = OpExtInst %v3uint %28 UMin %32 %31
+         %34 = OpImageFetch %v4int %20 %33 Lod %27
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_223246
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_223246
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_223246
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_223246
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_223246
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %61 = OpFunctionCall %v4int %textureLoad_223246
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4int %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.glsl
index 5adee6c..b45f659 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_22e963() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_22e963() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_22e963() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
index 72a3d2f..fecf496 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_22e963() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_22e963();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
index 72a3d2f..fecf496 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_22e963() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_22e963();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.msl
index 7cfeeaa..de481fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_22e963(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.msl
index 4973a44..931d026 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_22e963(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.spvasm
index b1e4053..0f2583b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/22e963.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +60,71 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_22e963 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %27 UMin %32 %31
+         %34 = OpCompositeConstruct %v3uint %33 %26
+         %35 = OpImageRead %v4uint %20 %34 None
+               OpStore %res %35
+         %38 = OpLoad %v4uint %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_22e963
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_22e963
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_22e963
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_22e963
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_22e963
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %62 = OpFunctionCall %v4uint %textureLoad_22e963
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4uint %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.glsl
index 16e560b..a903660 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_23007a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_23007a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_23007a() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
index c5eee74..fd51648 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_23007a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23007a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
index c5eee74..fd51648 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_23007a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23007a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.msl
index 25fd702..dcf100e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_23007a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.msl
index cff51fb4..ffc2d81 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_23007a(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.spvasm
index bf8a09b..5e55219 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/23007a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_23007a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_23007a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_23007a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_23007a
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_23007a
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_23007a
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_23007a
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.glsl
index 9e07d4c..771237e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_2363be() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_2363be() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2363be() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
index d6986f4..7d73541 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2363be() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2363be();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
index d6986f4..7d73541 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2363be() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2363be();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.msl
index 3ac5184..4e5dcf8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_2363be(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.msl
index ee2f3dc..77c79aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2363be(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.spvasm
index 282c707..12c1d09 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2363be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,77 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2363be = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageFetch %v4int %20 %25 Lod %uint_1
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %28 %26
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %31 UMin %uint_1 %33
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpExtInst %v2uint %31 UMin %39 %38
+         %41 = OpCompositeConstruct %v3uint %40 %30
+         %42 = OpImageFetch %v4int %20 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_2363be
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_2363be
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_2363be
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_2363be
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_2363be
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_2363be
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.glsl
index cdef1ac..75c6930 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_23ff89() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_23ff89() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_23ff89() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
index 5c4c480..037155a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_23ff89() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23ff89();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
index 5c4c480..037155a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_23ff89() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23ff89();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.msl
index 65ca704..bb04e00 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_23ff89(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.msl
index 564edaa..891d9e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_23ff89(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.spvasm
index 0930d9e..e922304 100644
--- a/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/23ff89.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +60,71 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_23ff89 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %27 UMin %32 %31
+         %34 = OpCompositeConstruct %v3uint %33 %26
+         %35 = OpImageRead %v4uint %20 %34 None
+               OpStore %res %35
+         %38 = OpLoad %v4uint %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_23ff89
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_23ff89
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_23ff89
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_23ff89
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_23ff89
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %62 = OpFunctionCall %v4uint %textureLoad_23ff89
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4uint %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
index cabaf4a..093f5c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_25b67f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
index cabaf4a..093f5c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_25b67f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.msl
index 1f8f0d5..e034c14 100644
--- a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_25b67f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.msl
index 2ea311b..20e66bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_25b67f(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.spvasm
index 092667f..2b8363f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/25b67f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_25b67f = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpExtInst %v2uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_25b67f
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_25b67f
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_25b67f
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_25b67f
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
index 699e0d9..e6296c9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_26b8f6() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
index 699e0d9..e6296c9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_26b8f6() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.msl
index 4aefb2d..11a09a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_26b8f6(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.msl
index 12fae8f..f7275e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_26b8f6(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.spvasm
index 27e7832..78e4828 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/26b8f6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_26b8f6 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpExtInst %v3uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_26b8f6
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_26b8f6
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_26b8f6
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_26b8f6
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.glsl
index e29b789..360f56e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_26c4f8() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1))).zyxw;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_26c4f8() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1))).zyxw;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_26c4f8() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1))).zyxw;
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
index 8f3a237..bab51fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_26c4f8() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26c4f8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
index 8f3a237..bab51fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_26c4f8() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26c4f8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.msl
index e0c79fd..2bc2682 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_26c4f8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.msl
index 6b31d0b..777f3b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_26c4f8(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.spvasm
index 11d996e..50a7150f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/26c4f8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,65 +56,71 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_26c4f8 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-         %23 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+         %32 = OpVectorShuffle %v4float %31 %31 2 1 0 3
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_26c4f8
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_26c4f8
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_26c4f8
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_26c4f8
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_26c4f8
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_26c4f8
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.glsl
index b3ec794..c9f4431 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_26d7f1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_26d7f1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_26d7f1() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
index 90c90a8..bf472a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_26d7f1() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26d7f1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
index 90c90a8..bf472a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_26d7f1() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26d7f1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.msl
index 1587971..bbddabc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_26d7f1(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.msl
index 761d7a1..0ca8b3e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_26d7f1(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.spvasm
index 57c8100..009b1bf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/26d7f1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,67 +60,75 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_26d7f1 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4uint %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_26d7f1
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_26d7f1
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_26d7f1
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_26d7f1
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_26d7f1
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_26d7f1
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.glsl
index 708c7b4..e1d2de0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_272e7a() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_272e7a() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
index e6fb891..8db3004 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_272e7a() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
index e6fb891..8db3004 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_272e7a() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.msl
index 92a92f9..25bf73a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_272e7a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.msl
index 9a1d1ca..c2ab72e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_272e7a(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.spvasm
index b1eb75b..dd7a4cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/272e7a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_272e7a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_272e7a
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_272e7a
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_272e7a
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_272e7a
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.glsl
index ccf4725..2c99189 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_276643() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_276643() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_276643() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
index 5c27a08..270961f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_276643() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276643();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
index 5c27a08..270961f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_276643() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276643();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.msl
index 19c6fb2..0f3cfa2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_276643(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.msl
index b4f2f9d..c21e3cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_276643(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.spvasm
index ff0e914..2a32a7d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/276643.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,56 +62,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_276643 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_276643
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_276643
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_276643
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_276643
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_276643
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_276643
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.glsl
index bf8ba7f..912e53b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_276a2c() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_276a2c() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_276a2c() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
index 8ac92fc..31c48f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_276a2c() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276a2c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
index 8ac92fc..31c48f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_276a2c() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276a2c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.msl
index 5c7bcfc..c54c198 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_276a2c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.msl
index f25f97d..1496ea0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_276a2c(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.spvasm
index 2730bd3..53749e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/276a2c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_276a2c = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %int_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageRead %v4uint %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_276a2c
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4uint %textureLoad_276a2c
          %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_276a2c
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4uint %textureLoad_276a2c
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_276a2c
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.glsl
index 084f94c..7723340 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_2887d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_2887d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2887d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
index aa18b40..17a6a12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2887d7() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2887d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
index aa18b40..17a6a12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2887d7() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2887d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.msl
index b21b9cf..ef0080a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_2887d7(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.msl
index cff1e11..2e9440e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2887d7(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.spvasm
index 14e4d2a..2c35a74 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2887d7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2887d7 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_2887d7
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_2887d7
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_2887d7
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_2887d7
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_2887d7
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.glsl
index ecb3cf1..7e69395 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_2a82d9() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_2a82d9() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2a82d9() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
index 71da84f..e31fa71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2a82d9() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2a82d9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
index 71da84f..e31fa71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2a82d9() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2a82d9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.msl
index 95cc47a..89a045d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_2a82d9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.msl
index dd7ea46..42c67c0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_2a82d9(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.spvasm
index d5744b5..895efca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2a82d9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +61,71 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2a82d9 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageRead %v4int %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4int %20 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_2a82d9
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_2a82d9
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_2a82d9
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_2a82d9
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_2a82d9
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_2a82d9
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.glsl
index 60462ff..c9bc1e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2ae485() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2ae485() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2ae485() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
index 4c57d26..df5f839 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2ae485() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2ae485();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
index 4c57d26..df5f839 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2ae485() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2ae485();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.msl
index 0450027..2226507 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_2ae485(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.msl
index 19a8d80..675fee6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2ae485(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.spvasm
index 1cf56b2..790374d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2ae485.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2ae485 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_2ae485
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_2ae485
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_2ae485
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_2ae485
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_2ae485
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_2ae485
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.glsl
index 22d8976..3c9aa94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2c72ae() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2c72ae() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2c72ae() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
index ff9d994..8452dc2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2c72ae() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2c72ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
index ff9d994..8452dc2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2c72ae() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2c72ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.msl
index 924d4e4..01b8a7b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_2c72ae(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.msl
index bb44ed8..bc1a8b5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_2c72ae(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.spvasm
index 310c96b..cfa7743 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2c72ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2c72ae = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_2c72ae
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_2c72ae
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_2c72ae
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_2c72ae
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_2c72ae
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_2c72ae
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
index 1e00ded..92904a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2cee30() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
index 1e00ded..92904a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2cee30() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.msl
index 1f10a53..905dee5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_2cee30(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.msl
index 5660591..dcfe5b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2cee30(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.spvasm
index d163ee5..7e7dbea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2cee30.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,46 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_2cee30 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %14
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4int %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_2cee30
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_2cee30
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_2cee30
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_2cee30
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.glsl
index 323cb5a..a7059a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_2d479c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_2d479c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2d479c() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
index fe0a121..11755c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2d479c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d479c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
index fe0a121..11755c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2d479c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d479c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.msl
index e5d02e8..78f674f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_2d479c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.msl
index 5945332..3d80d15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2d479c(texture2d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.spvasm
index f04cc8d..367c6c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2d479c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2d479c = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v2uint %17 %22
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %33 = OpExtInst %v2uint %23 UMin %28 %26
+         %34 = OpImageFetch %v4float %17 %33 Lod %22
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_2d479c
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_2d479c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_2d479c
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_2d479c
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_2d479c
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %30
+%vertex_main_inner = OpFunction %VertexOutput None %52
          %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_2d479c
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.glsl
index 103d10c..07feada 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2d6cf7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2d6cf7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2d6cf7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
index 4723047..77a3f57 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2d6cf7() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d6cf7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
index 4723047..77a3f57 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2d6cf7() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d6cf7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.msl
index 454f58c..ff19bfe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_2d6cf7(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.msl
index 14da791..91c0ce3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2d6cf7(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.spvasm
index 5578963..6b1b6ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2d6cf7.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,62 +61,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2d6cf7 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %int_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_2d6cf7
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4int %textureLoad_2d6cf7
          %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_2d6cf7
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4int %textureLoad_2d6cf7
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_2d6cf7
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
index 7f16bb3..843805b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_2dbfc2() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
index 7f16bb3..843805b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_2dbfc2() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.msl
index 01b4185..e37b0e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_2dbfc2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.msl
index fa53f76..74781f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2dbfc2(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.spvasm
index 987fde7..bbf7366 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2dbfc2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 39
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,40 +36,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_2dbfc2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-         %23 = OpVectorShuffle %v4float %22 %22 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+         %32 = OpVectorShuffle %v4float %31 %31 2 1 0 3
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_2dbfc2
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_2dbfc2
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_2dbfc2
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_2dbfc2
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.glsl
index ec5c134..973b47c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_2e09aa() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_2e09aa() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2e09aa() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v, int(1u));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
index fa192d9..ee1c93a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2e09aa() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e09aa();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
index fa192d9..ee1c93a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2e09aa() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e09aa();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.msl
index 3cfc947..641931f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_2e09aa(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.msl
index 7e18ec9..b3e4942 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_2e09aa(texture2d_ms<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.spvasm
index 96d674b..1ab867e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2e09aa.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,59 +58,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2e09aa = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %uint_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageFetch %v4float %17 %24 Sample %uint_1
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_2e09aa
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_2e09aa
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_2e09aa
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_2e09aa
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_2e09aa
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_2e09aa
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.glsl
index c182da0..d41b89f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_2e3552() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_2e3552() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2e3552() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
index 8ec5840..b4960e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2e3552() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e3552();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
index 8ec5840..b4960e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2e3552() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e3552();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.msl
index 7d3a8a6..31e82f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_2e3552(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.msl
index 101c80b..80286a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2e3552(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.spvasm
index 44b07ba..01cc601 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2e3552.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2e3552 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_2e3552
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_2e3552
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_2e3552
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_2e3552
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_2e3552
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_2e3552
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.glsl
index 14b333e..5ae4351 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_2eaf31() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_2eaf31() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
index 4a31b10..8567a11 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2eaf31() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
index 4a31b10..8567a11 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2eaf31() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.msl
index 234fc63..e4fbd6a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_2eaf31(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.msl
index febc864..e5763dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_2eaf31(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)));
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.spvasm
index b9d785d..04d34f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/2eaf31.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_2eaf31 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_2eaf31
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_2eaf31
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_2eaf31
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_2eaf31
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.glsl
index 1949e69..c4237a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_313c73() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_313c73() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_313c73() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
index 010e544..bba4a5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_313c73() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_313c73();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
index 010e544..bba4a5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_313c73() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_313c73();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.msl
index b8d9946..a836144 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_313c73(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.msl
index 4093de4..0c16775 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_313c73(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.spvasm
index fb7c098..2b84cbf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/313c73.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +61,71 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_313c73 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageRead %v4int %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4int %20 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_313c73
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_313c73
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_313c73
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_313c73
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_313c73
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_313c73
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.glsl
index dc31436..33898a4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_31db4b() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_31db4b() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_31db4b() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
index fa41b1a..511bb23 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_31db4b() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_31db4b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
index fa41b1a..511bb23 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_31db4b() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_31db4b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.msl
index 40578ba..931afba 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_31db4b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.msl
index f48037d..3b4f20c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_31db4b(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.spvasm
index fe1a3a4..868796f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/31db4b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +63,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_31db4b = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %uint_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageRead %v4uint %20 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_31db4b
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_31db4b
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_31db4b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_31db4b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_31db4b
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %53 = OpFunctionCall %v4uint %textureLoad_31db4b
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.glsl
index bd3801f..6e8a576 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_321210() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_321210() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_321210() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
index 10219c0..ce59257 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_321210() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_321210();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
index 10219c0..ce59257 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_321210() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_321210();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.msl
index 13722e7..3c6da2a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_321210(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.msl
index 964d2f5..5679a58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_321210(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.spvasm
index 4c1bac9..d62a71f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/321210.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_321210 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %38 = OpExtInst %v2uint %27 UMin %33 %31
+         %39 = OpCompositeConstruct %v3uint %38 %26
+         %40 = OpImageRead %v4uint %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_321210
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_321210
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_321210
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_321210
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_321210
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_321210
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
index a9f102e..978d697 100644
--- a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_32a7b8() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
index a9f102e..978d697 100644
--- a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_32a7b8() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.msl
index 78d247e..32a0946 100644
--- a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_32a7b8(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.msl
index c8bbc05..b41fc79 100644
--- a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_32a7b8(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.spvasm
index 9e706b2..ba0ed7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/32a7b8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,46 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_32a7b8 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %14
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4int %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_32a7b8
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_32a7b8
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_32a7b8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_32a7b8
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.glsl
index 904e331..757c298 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_33d3aa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_33d3aa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_33d3aa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
index 38ce474..828b7b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_33d3aa() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_33d3aa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
index 38ce474..828b7b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_33d3aa() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_33d3aa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.msl
index 00cf238..183b795 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_33d3aa(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.msl
index 7e8e523..7a6f6fc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_33d3aa(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.spvasm
index 9a193f0..70d05b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/33d3aa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_33d3aa = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %uint_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageRead %v4int %20 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4int %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_33d3aa
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_33d3aa
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_33d3aa
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_33d3aa
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_33d3aa
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %54 = OpFunctionCall %v4int %textureLoad_33d3aa
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4int %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.glsl
index 6f428d4..db75aeed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_348827() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_348827() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_348827() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
index 5607724..1ce2e09 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_348827() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_348827();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
index 5607724..1ce2e09 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_348827() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_348827();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.msl
index cf1b99d..0385970 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_348827(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.msl
index 1f9bdee..953d56d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_348827(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.spvasm
index b376846..48b2fe0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/348827.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +60,71 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_348827 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %27 UMin %32 %31
+         %34 = OpCompositeConstruct %v3uint %33 %26
+         %35 = OpImageRead %v4uint %20 %34 None
+               OpStore %res %35
+         %38 = OpLoad %v4uint %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_348827
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_348827
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_348827
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_348827
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_348827
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %62 = OpFunctionCall %v4uint %textureLoad_348827
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4uint %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.glsl
index 46d9d8a..1064717 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_34d97c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_34d97c() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
index d949adf..3dafbf0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_34d97c() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
index d949adf..3dafbf0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_34d97c() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.msl
index 000e52b..efae5b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 uint4 textureLoad_34d97c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.msl
index b284210..b2ee19d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_34d97c(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.spvasm
index 9e175cb..74d541f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/34d97c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,37 +36,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_34d97c = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4uint %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4uint %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_34d97c
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_34d97c
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_34d97c
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_34d97c
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.glsl
index f475914..b0a4cfb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_35a5e2() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_35a5e2() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
index 9b4c9e4..a5b1778 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_35a5e2() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
index 9b4c9e4..a5b1778 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_35a5e2() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.msl
index bfd9708..abea5b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_35a5e2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.msl
index 6124e3a..4d6b59b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_35a5e2(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.spvasm
index 6bbd905..cd3b550 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/35a5e2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,34 +37,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_35a5e2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_35a5e2
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_35a5e2
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_35a5e2
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.glsl
index b4bff9c..e841c81 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_35d464() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_35d464() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_35d464() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
index 6ea0b07..7a567d47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_35d464() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_35d464();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
index 6ea0b07..7a567d47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_35d464() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_35d464();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.msl
index 92c3b9c..a33425b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_35d464(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.msl
index cc8c804..7239e1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_35d464(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.spvasm
index dc3f5e5..b4226b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/35d464.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_35d464 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_35d464
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_35d464
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_35d464
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_35d464
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_35d464
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_35d464
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.glsl
index 47a5c81..3536016 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_374351() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_374351() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_374351() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
index dcdecf2..69b713a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_374351() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_374351();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
index dcdecf2..69b713a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_374351() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_374351();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.msl
index 31393ac..825e210 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_374351(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.msl
index fd6cefc..e89a905 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_374351(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.spvasm
index 756d135..37734f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/374351.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_374351 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpExtInst %v3uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_374351
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_374351
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_374351
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_374351
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_374351
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_374351
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.glsl
index cd0032e..759be6e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_388688() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_388688() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_388688() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
index 7fa0590..8712509 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_388688() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_388688();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
index 7fa0590..8712509 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_388688() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_388688();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.msl
index 4caf175..2137a06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_388688(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.msl
index be27a60..86950e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_388688(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.spvasm
index 94e1c4c..e53913a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/388688.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,56 +61,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_388688 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_388688
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_388688
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_388688
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_388688
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_388688
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_388688
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.glsl
index d4388c0..b2e8027 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_38f8ab() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_38f8ab() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp isampler2DMS arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_38f8ab() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  ivec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
index fdb4b9b..9b3a770 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_38f8ab() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  int4 res = int4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_38f8ab();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
index fdb4b9b..9b3a770 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_38f8ab() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  int4 res = int4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_38f8ab();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.msl
index 428ce86..ca12d49 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_38f8ab(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1u);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.msl
index 528feb8..0b0fe4d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_38f8ab(texture2d_ms<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.spvasm
index d3db016..c5f5c9f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/38f8ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_38f8ab = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Sample %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageFetch %v4int %20 %31 Sample %uint_1
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_38f8ab
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_38f8ab
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_38f8ab
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_38f8ab
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_38f8ab
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_38f8ab
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
index 3de6415..f9c1608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_39016c() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
index 3de6415..f9c1608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_39016c() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.msl
index aff3d10..e161999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_39016c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.msl
index 958624f..c08dc9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_39016c(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.spvasm
index d0fdb4a..c044e97 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/39016c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_39016c = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_39016c
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_39016c
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_39016c
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_39016c
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
index f583010..e3a3a71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_395447() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
index f583010..e3a3a71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_395447() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.msl
index c1d094e..1a29b4f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_395447(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.msl
index cc4d2fb..40dae82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_395447(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.spvasm
index 4414128..232f47b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/395447.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_395447 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_395447
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_395447
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_395447
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_395447
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.glsl
index 2b12404..2e6fe6f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_39ef40() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_39ef40() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_39ef40() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
index ff69c16..b3eb418 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_39ef40() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_39ef40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
index ff69c16..b3eb418 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_39ef40() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_39ef40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.msl
index cb8cd36..a793be9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_39ef40(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.msl
index 939845e..385d90a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_39ef40(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.spvasm
index fdc4443..ea66d5d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/39ef40.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,56 +61,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_39ef40 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_39ef40
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_39ef40
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_39ef40
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_39ef40
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_39ef40
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_39ef40
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
index b72c7cb..095a4f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3a2350() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
index b72c7cb..095a4f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3a2350() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.msl
index f115042..837f548 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_3a2350(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.msl
index cbd342b..1732143 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3a2350(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.spvasm
index b158bea..1be661a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3a2350.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,49 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %26 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_3a2350 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %14
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpBitcast %v2uint %26
+         %30 = OpExtInst %v2uint %19 UMin %25 %23
+         %31 = OpCompositeConstruct %v3uint %30 %18
+         %32 = OpImageRead %v4uint %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_3a2350
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_3a2350
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_3a2350
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_3a2350
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.glsl
index 06982fd..526d9df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_3aea13() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_3aea13() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
index 52781dc..4be218e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_3aea13() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
index 52781dc..4be218e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_3aea13() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.msl
index 5fb1d77..1133e7d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_3aea13(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.msl
index f52e561..6604bca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_3aea13(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.spvasm
index 566db89..d6bc8dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3aea13.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_3aea13 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %13
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %30 = OpExtInst %v2uint %20 UMin %26 %24
+         %31 = OpCompositeConstruct %v3uint %30 %19
+         %32 = OpImageRead %v4int %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_3aea13
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_3aea13
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_3aea13
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_3aea13
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.glsl
index 8645f7d..8d26030 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_3bbc2b() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_3bbc2b() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
index 4feb0dc..448a9af 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3bbc2b() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
index 4feb0dc..448a9af 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3bbc2b() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.msl
index 81fed00..2845ffa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_3bbc2b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.msl
index d38c0e5..20b75bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3bbc2b(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.spvasm
index ee28e85..62c4ef3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3bbc2b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,34 +36,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_3bbc2b = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_3bbc2b
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_3bbc2b
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_3bbc2b
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.glsl
index 86d1bf2..910df06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_3c0d9e() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_3c0d9e() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_3c0d9e() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
index ec8a7a0..bdeeeae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_3c0d9e() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c0d9e();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
index ec8a7a0..bdeeeae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_3c0d9e() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c0d9e();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.msl
index 223ab68..ab2ef77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_3c0d9e(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.msl
index 23401e8..b8ba76b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3c0d9e(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.spvasm
index a8c1b96..adf11e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3c0d9e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c0d9e = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.glsl
index 2683b94..4be8e05 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3c9587() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3c9587() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3c9587() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
index 541ca19..d734144 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c9587() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c9587();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
index 541ca19..d734144 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c9587() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c9587();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.msl
index a4447a4..da4a460 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_3c9587(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.msl
index d8aea7f..d038094 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3c9587(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.spvasm
index 3f8be9a..a91b7a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3c9587.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c9587 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_3c9587
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_3c9587
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_3c9587
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_3c9587
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_3c9587
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_3c9587
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.glsl
index 8e4c871..2e079ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_3c96e8() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_3c96e8() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3c96e8() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  vec4 res = texelFetch(arg_0, v_5, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
index 34940e2..dfff5d8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c96e8() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c96e8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
index 34940e2..dfff5d8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c96e8() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c96e8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.msl
index 885d418..3ed5355 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_3c96e8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.msl
index e75cf3e..6d15e91 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3c96e8(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.spvasm
index c1215eb..677b2ba 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3c96e8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,67 +55,80 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %36 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %63 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c96e8 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %uint_1
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageQuerySizeLod %v3uint %17 %29
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %36
+         %40 = OpExtInst %v2uint %26 UMin %35 %33
+         %41 = OpCompositeConstruct %v3uint %40 %25
+         %42 = OpImageFetch %v4float %17 %41 Lod %29
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_3c96e8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_3c96e8
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_3c96e8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4float %textureLoad_3c96e8
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_3c96e8
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %67 = OpFunctionCall %v4float %textureLoad_3c96e8
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %48
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4float %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
index b6f76cf..7a05ba3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3cfb9c() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
index b6f76cf..7a05ba3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3cfb9c() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.msl
index ca2e445..7b78aa5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_3cfb9c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.msl
index d8ce93e..6735051 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3cfb9c(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(int3(1)));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.spvasm
index 3460af3..02f7d9e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3cfb9c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_3cfb9c = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpBitcast %v3uint %19
+         %23 = OpExtInst %v3uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_3cfb9c
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_3cfb9c
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_3cfb9c
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_3cfb9c
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.glsl
index 1c7dc0e..9eabc27 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_3d001b() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_3d001b() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_3d001b() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
index 0d6daa5..bf2f50e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d001b() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d001b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
index 0d6daa5..bf2f50e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d001b() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d001b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.msl
index 2d7334f..9d56263 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_3d001b(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.msl
index f730b95..8bfb3e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_3d001b(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.spvasm
index 6463807..bc08d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3d001b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d001b = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpBitcast %v3uint %28
+         %31 = OpExtInst %v3uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_3d001b
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_3d001b
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_3d001b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_3d001b
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_3d001b
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_3d001b
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.glsl
index 1c55768..0017ed9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_3d3fd1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_3d3fd1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_3d3fd1() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
index c1f4736..d3cc7dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d3fd1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d3fd1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
index c1f4736..d3cc7dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d3fd1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d3fd1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.msl
index 5185512..79a3805 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_3d3fd1(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.msl
index 4ed3351..ad27eae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_3d3fd1(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.spvasm
index 0448705..6dc6d7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3d3fd1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +60,76 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d3fd1 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageFetch %v4int %20 %23 Lod %int_1
-               OpStore %res %27
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpExtInst %uint %29 UMin %uint_1 %26
+         %30 = OpImageQueryLevels %uint %20
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %34 = OpExtInst %uint %29 UMin %32 %31
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpExtInst %v2uint %29 UMin %39 %38
+         %41 = OpCompositeConstruct %v3uint %40 %28
+         %42 = OpImageFetch %v4int %20 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_3d3fd1
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_3d3fd1
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_3d3fd1
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_3d3fd1
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_3d3fd1
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.glsl
index c3ef4f9..d99b389 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_3d9c90() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_3d9c90() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3d9c90() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
index 541979c..2c6e91d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3d9c90() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d9c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
index 541979c..2c6e91d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3d9c90() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d9c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.msl
index dad0089..5b877ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_3d9c90(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.msl
index 7622140..fed8617 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3d9c90(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.spvasm
index 5a2f4a1..c6ae95a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3d9c90.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d9c90 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_3d9c90
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_3d9c90
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_3d9c90
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_3d9c90
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_3d9c90
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_3d9c90
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.glsl
index de2d458..6749ca6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_3da3ed() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_3da3ed() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3da3ed() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_2 = (uvec2(textureSize(arg_0, int(v_1))).x - 1u);
+  ivec2 v_3 = ivec2(uvec2(min(uint(1), v_2), 0u));
+  vec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
index 6fbeba9..6e09ccc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3da3ed() {
-  int v = int(int(1));
-  float4 res = float4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  float4 res = float4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3da3ed();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
index 6fbeba9..6e09ccc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3da3ed() {
-  int v = int(int(1));
-  float4 res = float4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  float4 res = float4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3da3ed();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.msl
index 46bfd69..b891376 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_3da3ed(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.msl
index 884edb3..0e2bfcf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3da3ed(texture1d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.spvasm
index 94574bf..53f767b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3da3ed.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,62 +56,69 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3da3ed = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %int_1 Lod %uint_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %uint %17 %22
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %23 UMin %26 %25
+         %30 = OpImageFetch %v4float %17 %29 Lod %22
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_3da3ed
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_3da3ed
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_3da3ed
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_3da3ed
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_3da3ed
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_3da3ed
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.glsl
index 78c4ed0..5e069bf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_3e16a8() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_3e16a8() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
index e00fa1b..b8d257a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3e16a8() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
index e00fa1b..b8d257a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3e16a8() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.msl
index e50a761..ecf42dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_3e16a8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.msl
index b7b86b5..73f569e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3e16a8(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.spvasm
index 23fc94d..92a8c9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3e16a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,36 +36,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_3e16a8 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_3e16a8
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_3e16a8
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_3e16a8
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_3e16a8
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.glsl
index 92d7592..387de19 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3e5f6a() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3e5f6a() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3e5f6a() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
index 6cf346e..90b485b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3e5f6a() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3e5f6a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
index 6cf346e..90b485b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3e5f6a() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3e5f6a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.msl
index 9d41be4..c6976fa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_3e5f6a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.msl
index bb118e8..fb7c681 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_3e5f6a(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.spvasm
index 6b0d5f7..4a65964 100644
--- a/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/3e5f6a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3e5f6a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_3e5f6a
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_3e5f6a
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_3e5f6a
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_3e5f6a
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_3e5f6a
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_3e5f6a
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
index 9269308..faecc11 100644
--- a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_40ee8b() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
index 9269308..faecc11 100644
--- a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_40ee8b() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.msl
index 781a6f3..855298b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_40ee8b(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.msl
index ff50029..ca50082 100644
--- a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_40ee8b(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.spvasm
index 7f113cd..cb2c9c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/40ee8b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_40ee8b = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %13
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %30 = OpExtInst %v2uint %20 UMin %26 %24
+         %31 = OpCompositeConstruct %v3uint %30 %19
+         %32 = OpImageRead %v4int %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_40ee8b
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_40ee8b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_40ee8b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_40ee8b
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
index 60d19c6..86a1f58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4212a1() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
index 60d19c6..86a1f58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4212a1() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.msl
index 1c672c3..01cc6d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_4212a1(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.msl
index 89d72ee..33ef0e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4212a1(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)));
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.spvasm
index 0fbdfa9..5422f9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4212a1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4212a1 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %23 = OpExtInst %v2uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_4212a1
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_4212a1
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_4212a1
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_4212a1
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.glsl
index 73436ff..ca93abf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_424afd() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_424afd() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
index 126cdb6..0d97b22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_424afd() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
index 126cdb6..0d97b22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_424afd() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.msl
index ab324e0..044c3b5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 int4 textureLoad_424afd(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.msl
index 1a28889..fcfc0e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_424afd(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.spvasm
index 5a58b1b..04e4192 100644
--- a/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/424afd.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,37 +36,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %15 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_424afd = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3int %15 %int_1
-         %18 = OpImageRead %v4int %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4int %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_424afd
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_424afd
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_424afd
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_424afd
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
index fbdf233..7a07763 100644
--- a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_42a631() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
index fbdf233..7a07763 100644
--- a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_42a631() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.msl
index db67072..cda7596 100644
--- a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_42a631(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.msl
index 12b5a3b..d310218 100644
--- a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_42a631(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.spvasm
index b648c50..ab7740c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/42a631.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,34 +36,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_42a631 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_42a631
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_42a631
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_42a631
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.glsl
index a012081..1870550 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_43484a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_43484a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
index c668072..8acdc8e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43484a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
index c668072..8acdc8e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43484a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.msl
index df77a59..f82d794 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_43484a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.msl
index bbc53cb..e606816 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_43484a(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.spvasm
index 0182cd6..ed77ae0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/43484a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_43484a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_43484a
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_43484a
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_43484a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_43484a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.glsl
index 5301fd1..0f86e7c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_439e2a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_439e2a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_439e2a() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
index b3afd50..4237d31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_439e2a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_439e2a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
index b3afd50..4237d31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_439e2a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_439e2a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.msl
index d8c599a..c3a7612 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_439e2a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.msl
index 19ccaf4..4f28206 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_439e2a(texture2d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.spvasm
index c69a059..713c00f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/439e2a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,63 +56,70 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_439e2a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v2uint %17 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %26 UMin %30 %29
+         %32 = OpImageFetch %v4float %17 %31 Lod %25
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_439e2a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_439e2a
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_439e2a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_439e2a
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_439e2a
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_439e2a
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
index 3f92fce..86ef6eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43cd86() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
index 3f92fce..86ef6eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43cd86() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.msl
index 7d419b3..61513ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_43cd86(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.msl
index 61a2ae5..98489c0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_43cd86(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.spvasm
index 6683a1e..a4f9696 100644
--- a/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/43cd86.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_43cd86 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_43cd86
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_43cd86
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_43cd86
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_43cd86
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.glsl
index bbedbd9..8eb6ba9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_44c826() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_44c826() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_44c826() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
index 3ddef65..f77e505 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_44c826() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_44c826();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
index 3ddef65..f77e505 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_44c826() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_44c826();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.msl
index 91ab5f5..b00b18a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_44c826(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.msl
index 5e7d8c8..08fe703 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_44c826(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.spvasm
index 0df9f3e..a9cc905 100644
--- a/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/44c826.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_44c826 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %uint_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageRead %v4uint %20 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_44c826
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_44c826
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_44c826
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_44c826
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_44c826
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %53 = OpFunctionCall %v4uint %textureLoad_44c826
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
index 78a7ced..94b06d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4542ae() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
index 78a7ced..94b06d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4542ae() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.msl
index 5ae4167..c301b45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_4542ae(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.msl
index a223db6..a54c720 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4542ae(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.spvasm
index 7dc09d5..bbccbc1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4542ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,38 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4542ae = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_4542ae
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_4542ae
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_4542ae
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_4542ae
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.glsl
index 604968f..aac44ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_454347() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_454347() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_454347() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
index 878f6c2..c6fd33b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_454347() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_454347();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
index 878f6c2..c6fd33b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_454347() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_454347();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.msl
index 92e449a..d03e9a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_454347(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.msl
index 6ee9141..f145d60 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_454347(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.spvasm
index 4eea20d..ae51d2c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/454347.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +63,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_454347 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %uint_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageRead %v4uint %20 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_454347
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_454347
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_454347
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_454347
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_454347
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %53 = OpFunctionCall %v4uint %textureLoad_454347
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.glsl
index 7476bfe..73bb127 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_4638a0() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_4638a0() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4638a0() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
index 60bbd55..ffcb7f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4638a0() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4638a0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
index 60bbd55..ffcb7f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4638a0() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4638a0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.msl
index fc7bec2..04256d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_4638a0(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.msl
index 3a145ea..f6daa82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4638a0(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.spvasm
index 65ff3e9..5b2243e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4638a0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,76 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4638a0 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %38 = OpExtInst %v2uint %28 UMin %34 %32
+         %39 = OpCompositeConstruct %v3uint %38 %27
+         %40 = OpImageRead %v4int %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_4638a0
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_4638a0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_4638a0
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_4638a0
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_4638a0
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_4638a0
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.glsl
index 7cf7e20..54fc365 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_469912() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_469912() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
index f680b40..3471bb7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_469912() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
index f680b40..3471bb7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_469912() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.msl
index 1089cbd..e48ab18 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_469912(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.msl
index fa3ae9b..4180a1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_469912(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1));
+  int4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.spvasm
index c42873f..fceb7ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/469912.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,33 +37,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_469912 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %int_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4int %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %17 %15
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4int %textureLoad_469912
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %23 %22 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %20
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4int %textureLoad_469912
          %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_469912
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.glsl
index aa07f60..2e0bfbb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_46a93f() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_46a93f() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_46a93f() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
index f5528ed..e73eacf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46a93f() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46a93f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
index f5528ed..e73eacf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46a93f() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46a93f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.msl
index 6133554..958bccd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_46a93f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.msl
index 3a4b0d8..0ea80d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_46a93f(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.spvasm
index a93e26b..353d5e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/46a93f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,77 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_46a93f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %uint_1
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpExtInst %v2uint %29 UMin %37 %36
+         %39 = OpCompositeConstruct %v3uint %38 %28
+         %40 = OpImageFetch %v4float %17 %39 Lod %32
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_46a93f
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_46a93f
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_46a93f
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%compute_main = OpFunction %void None %46
+         %52 = OpLabel
          %53 = OpFunctionCall %v4float %textureLoad_46a93f
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_46a93f
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.glsl
index 45062e3..665462d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_46dbf5() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_46dbf5() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_46dbf5() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
index f560afb..3040b14 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46dbf5() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46dbf5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
index f560afb..3040b14 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46dbf5() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46dbf5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.msl
index 4cbfe51..7e1f3ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_46dbf5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.msl
index 5c345796..219804a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_46dbf5(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.spvasm
index cd0b9ae..233f218 100644
--- a/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/46dbf5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_46dbf5 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_46dbf5
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_46dbf5
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_46dbf5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_46dbf5
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_46dbf5
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_46dbf5
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
index bce8102..e8f4b66 100644
--- a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_473d3e() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
index bce8102..e8f4b66 100644
--- a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_473d3e() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.msl
index 9212a0a..90bf161 100644
--- a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_473d3e(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.msl
index 795f507..9ce8381 100644
--- a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_473d3e(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.spvasm
index b3a4dca..3690a5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/473d3e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_473d3e = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_473d3e
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_473d3e
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_473d3e
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_473d3e
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.glsl
index 0aed7bd..ebbf272 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_47e818() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_47e818() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_47e818() {
-  ivec3 v = ivec3(uvec3(1u));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_2 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
index 5d7d82d..5c8a147 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_47e818() {
-  int3 v = int3((1u).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_47e818();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
index 5d7d82d..5c8a147 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_47e818() {
-  int3 v = int3((1u).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  int3 v_2 = int3(min((1u).xxx, (v_1.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_47e818();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.msl
index cd5162a..13c1a49 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_47e818(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.msl
index 6d91fd5..425b199 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_47e818(texture3d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.spvasm
index 91f29c4..a83d9b2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/47e818.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,68 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+     %v3uint = OpTypeVector %uint 3
+         %30 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_47e818 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %uint_1
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v3uint %20 %25
+         %29 = OpISub %v3uint %27 %30
+         %31 = OpExtInst %v3uint %26 UMin %30 %29
+         %32 = OpImageFetch %v4int %20 %31 Lod %25
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_47e818
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_47e818
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_47e818
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_47e818
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_47e818
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_47e818
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.glsl
index 90e31b6..77dcf80 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_482627() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_482627() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
index 18559a3..db2f267 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_482627() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
index 18559a3..db2f267 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_482627() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.msl
index 5ec8d6a..cb567ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_482627(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.msl
index fca2d736..2d33b87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_482627(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.spvasm
index 145f914..95d3180 100644
--- a/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/482627.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,35 +38,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_482627 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_482627
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_482627
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_482627
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_482627
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.glsl
index a6477b7..1d72aab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_484344() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_484344() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_484344() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
index d0b9641..4f40885 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_484344() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_484344();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
index d0b9641..4f40885 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_484344() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_484344();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.msl
index c0fdb04..f86e4d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_484344(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.msl
index dca9564..95c9d91 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_484344(texture2d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.spvasm
index de431b1..c3c9a45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/484344.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_484344 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v2uint %17 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %34 = OpExtInst %v2uint %26 UMin %31 %29
+         %35 = OpImageFetch %v4float %17 %34 Lod %25
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_484344
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_484344
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%fragment_main = OpFunction %void None %41
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_484344
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %43 = OpFunctionCall %v4float %textureLoad_484344
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_484344
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_484344
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.glsl
index a2409d3..4a9d282 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_4951bb() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_4951bb() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4951bb() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
index 886b965..f9e02ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4951bb() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4951bb();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
index 886b965..f9e02ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4951bb() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4951bb();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.msl
index aeb617d..7d622cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_4951bb(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.msl
index a6874f4..9df3581 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4951bb(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.spvasm
index e379e66..f0e0628 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4951bb.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4951bb = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_4951bb
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_4951bb
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_4951bb
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_4951bb
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_4951bb
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_4951bb
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.glsl
index c2fa060..ad34119 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_49f76f() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_49f76f() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp usampler2DMS arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_49f76f() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v, int(1u));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
index 4a5aa26..b81bf87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_49f76f() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_49f76f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
index 4a5aa26..b81bf87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_49f76f() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_49f76f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.msl
index 9535f41..d786102 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_49f76f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.msl
index cb7c121..c3be6f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_49f76f(texture2d_ms<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.spvasm
index f836f57..1057a68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/49f76f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,60 +60,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_49f76f = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Sample %uint_1
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageFetch %v4uint %20 %26 Sample %uint_1
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_49f76f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_49f76f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_49f76f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_49f76f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_49f76f
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_49f76f
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
index 5658733..9119642 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4a5c55() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
index 5658733..9119642 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4a5c55() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.msl
index b0328c1..b4d9e5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_4a5c55(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.msl
index 13b1ef1..6bc0c56 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_4a5c55(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(uint3(1u)));
+  int4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.spvasm
index 7312c3d..06ac71b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4a5c55.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_4a5c55 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_4a5c55
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_4a5c55
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_4a5c55
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_4a5c55
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.glsl
index c28d100..91f4b94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_4acb64() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  vec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_4acb64() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  vec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4acb64() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_1));
+  vec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
index bb6a3af..b22e5d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4acb64() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4acb64();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
index bb6a3af..b22e5d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4acb64() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4acb64();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.msl
index a12b2a5..a382caf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_4acb64(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.msl
index 8de21bb..61e7015 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4acb64(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.spvasm
index 81d7f28..81da90d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4acb64.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,67 +55,81 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+        %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %39 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4acb64 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %int_1
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %26 UMin %29 %28
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %39
+         %41 = OpExtInst %v2uint %26 UMin %38 %36
+         %42 = OpCompositeConstruct %v3uint %41 %25
+         %43 = OpImageFetch %v4float %17 %42 Lod %32
+               OpStore %res %43
+         %46 = OpLoad %v4float %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_4acb64
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_4acb64
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_4acb64
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %49
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_4acb64
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_4acb64
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_4acb64
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %49
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
index 540f1f4..3afa942 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4c15b2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
index 540f1f4..3afa942 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4c15b2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.msl
index 486f3a2..6d1c398 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_4c15b2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.msl
index 3dd93fd..e97e740 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4c15b2(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.spvasm
index 3771355..c5997b2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4c15b2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,38 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4c15b2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_4c15b2
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_4c15b2
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_4c15b2
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_4c15b2
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.glsl
index 2a720eb..5c7d75a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4c1a1e() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4c1a1e() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
index e7bbca4..e340417 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4c1a1e() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
index e7bbca4..e340417 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4c1a1e() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.msl
index bfbc674..64e9efb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_4c1a1e(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.msl
index e132fb5..15a09f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_4c1a1e(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(int3(1)));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.spvasm
index 81c1785..40a155e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4c1a1e.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4c1a1e = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpBitcast %v3uint %19
+         %23 = OpExtInst %v3uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_4c1a1e
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_4c1a1e
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_4c1a1e
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_4c1a1e
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.glsl
index 184d4f5..b53ee90 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_4c423f() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_4c423f() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4c423f() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
index dd2ad73..111374c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4c423f() {
-  int v = int(1u);
-  int4 res = int4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c423f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
index dd2ad73..111374c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4c423f() {
-  int v = int(1u);
-  int4 res = int4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  int v_3 = int(min(1u, (v_2.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c423f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.msl
index 9a18455..345b4ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_4c423f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.msl
index 4e6195a..c205312 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_4c423f(texture1d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.spvasm
index 0e4a81b..6a17076 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4c423f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,64 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4c423f = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %uint_1 Lod %int_1
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %uint %20 %27
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpExtInst %uint %28 UMin %uint_1 %30
+         %32 = OpImageFetch %v4int %20 %31 Lod %27
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_4c423f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_4c423f
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_4c423f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_4c423f
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_4c423f
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_4c423f
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.glsl
index 5345c50..42b9be3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_4c67be() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_4c67be() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4c67be() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
index ce99609..ad41f22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4c67be() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c67be();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
index ce99609..ad41f22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4c67be() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c67be();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.msl
index 6936091..5cf6c58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_4c67be(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.msl
index 7553b4f..54550f88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_4c67be(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.spvasm
index 821bb7b..0b49375 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4c67be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4c67be = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_4c67be
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_4c67be
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_4c67be
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_4c67be
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_4c67be
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_4c67be
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.glsl
index 1b55e7d..8104fce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4ccf9a() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4ccf9a() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
index 17b45c6..2b66165 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4ccf9a() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
index 17b45c6..2b66165 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4ccf9a() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.msl
index dd63d79..6897e0d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_4ccf9a(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.msl
index 673ef7f..8fdd619 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_4ccf9a(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.spvasm
index e193605..f9b8cbf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4ccf9a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4ccf9a = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpExtInst %v3uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_4ccf9a
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_4ccf9a
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_4ccf9a
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_4ccf9a
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.glsl
index 7382464..96bbf87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_4cdca5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_4cdca5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4cdca5() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
index 5178be3..a7f0ebe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4cdca5() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4cdca5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
index 5178be3..a7f0ebe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4cdca5() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4cdca5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.msl
index 48147d8..54923dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_4cdca5(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.msl
index bc7bca0..a90740b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4cdca5(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.spvasm
index e84360d..34be42c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4cdca5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,76 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4cdca5 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %38 = OpExtInst %v2uint %28 UMin %34 %32
+         %39 = OpCompositeConstruct %v3uint %38 %27
+         %40 = OpImageRead %v4int %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_4cdca5
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_4cdca5
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_4cdca5
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_4cdca5
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_4cdca5
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_4cdca5
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.glsl
index a466a0c..047ad5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_4db25c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v_1, int(1u)).x;
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_4db25c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v_1, int(1u)).x;
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_4db25c() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v, int(1u)).x;
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
index e149331..057013f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_4db25c() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(v, int(1u)).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float res = arg_0.Load(v_1, int(1u)).x;
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4db25c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
index e149331..057013f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_4db25c() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(v, int(1u)).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float res = arg_0.Load(v_1, int(1u)).x;
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4db25c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.msl
index 8dadba7..11ecb45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float textureLoad_4db25c(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.msl
index 637ee5f..ebd3bc8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float textureLoad_4db25c(depth2d_ms<float, access::read> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.spvasm
index 7daeb62..bbf123a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4db25c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,61 +58,64 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4db25c = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %uint_1
-         %23 = OpCompositeExtract %float %18 0
-               OpStore %res %23
-         %26 = OpLoad %float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageFetch %v4float %17 %24 Sample %uint_1
+         %27 = OpCompositeExtract %float %26 0
+               OpStore %res %27
+         %30 = OpLoad %float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %float %textureLoad_4db25c
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %float %textureLoad_4db25c
+         %36 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_4db25c
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %float %textureLoad_4db25c
+         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %50 = OpFunctionCall %float %textureLoad_4db25c
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %54 = OpFunctionCall %float %textureLoad_4db25c
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %float %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
index 462c480..a470a87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4e2c5c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
index 462c480..a470a87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4e2c5c() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.msl
index f352380..229aa04 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_4e2c5c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.msl
index a0c09de..85fd6ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4e2c5c(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.spvasm
index ed54024..9c92524 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4e2c5c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,40 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_4e2c5c = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_4e2c5c
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_4e2c5c
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_4e2c5c
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_4e2c5c
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.glsl
index 1e889f7..e1acf98 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_4f5496() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_4f5496() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
index df85245..d7fc208 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4f5496() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
index df85245..d7fc208 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4f5496() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.msl
index 78606c1..6fdcc06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 uint4 textureLoad_4f5496(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.msl
index c30f574..956cf4b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_4f5496(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.spvasm
index 5c8b5e7..884e3ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4f5496.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4f5496 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4uint %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4uint %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_4f5496
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_4f5496
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_4f5496
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_4f5496
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
index 264b7f2..3f0a25d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4f90bb() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
index 264b7f2..3f0a25d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4f90bb() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.msl
index 3c05ec2..7c2b35e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_4f90bb(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.msl
index 6eb8afb..2f73282 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4f90bb(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.spvasm
index 5590e55..1be8302 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4f90bb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,44 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4f90bb = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-         %18 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+         %27 = OpVectorShuffle %v4float %26 %26 2 1 0 3
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_4f90bb
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_4f90bb
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_4f90bb
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_4f90bb
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.glsl
index 23fa330..f39c63b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_4fa6ae() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_4fa6ae() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4fa6ae() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
index 3c628d0..6a3747d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4fa6ae() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fa6ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
index 3c628d0..6a3747d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4fa6ae() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fa6ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.msl
index 968f5e5..52a728c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_4fa6ae(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.msl
index 7fd6f8d..0435af2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_4fa6ae(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.spvasm
index 787c9c4..af8b28a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4fa6ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,60 +59,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4fa6ae = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-         %23 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+         %27 = OpVectorShuffle %v4float %26 %26 2 1 0 3
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_4fa6ae
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_4fa6ae
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_4fa6ae
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_4fa6ae
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_4fa6ae
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_4fa6ae
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.glsl
index a2782c7..aa60458 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_4fd803() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_4fd803() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4fd803() {
-  ivec3 v = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
index 2906ffd..d9db64d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4fd803() {
-  int3 v = int3((int(1)).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fd803();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
index 2906ffd..d9db64d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_4fd803() {
-  int3 v = int3((int(1)).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fd803();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.msl
index f649fbb..00d14f4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_4fd803(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.msl
index a862032..1aeaf14 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4fd803(texture3d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.spvasm
index 088c492..5bbef47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/4fd803.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+         %32 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+      %v3int = OpTypeVector %int 3
+         %34 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4fd803 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %int_1
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpISub %v3uint %29 %32
+         %33 = OpBitcast %v3uint %34
+         %36 = OpExtInst %v3uint %28 UMin %33 %31
+         %37 = OpImageFetch %v4int %20 %36 Lod %27
+               OpStore %res %37
+         %40 = OpLoad %v4int %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_4fd803
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_4fd803
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%fragment_main = OpFunction %void None %43
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_4fd803
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v4int %textureLoad_4fd803
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4int %textureLoad_4fd803
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %55
          %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %64 = OpFunctionCall %v4int %textureLoad_4fd803
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4int %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.glsl
index a3c220f..ae7b9a9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_505aa2() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_505aa2() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_505aa2() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
index ef1ee41..47edaa3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_505aa2() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_505aa2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
index ef1ee41..47edaa3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_505aa2() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_505aa2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.msl
index d2a7a54..1a5dbd3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_505aa2(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.msl
index 20396f2..b90e525 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_505aa2(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.spvasm
index 54f795c..97c92a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/505aa2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_505aa2 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpBitcast %v3uint %28
+         %31 = OpExtInst %v3uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_505aa2
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_505aa2
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_505aa2
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_505aa2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_505aa2
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_505aa2
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.glsl
index f435655..5e59e98 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_50915c() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_50915c() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_50915c() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
index 8a73ac7..04d1961 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_50915c() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_50915c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
index 8a73ac7..04d1961 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_50915c() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_50915c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.msl
index 9a91910..b8eff79 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_50915c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.msl
index 4d4a1f7..7b593ba 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_50915c(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.spvasm
index b3b72b4..7d5e8ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/50915c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_50915c = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpExtInst %v3uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_50915c
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_50915c
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_50915c
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_50915c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_50915c
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_50915c
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
index db5090f..1c30dee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5154e1() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
index db5090f..1c30dee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5154e1() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.msl
index 6e9dcaa..1d5b32a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_5154e1(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.msl
index d4d8bca..4b0017c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5154e1(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.spvasm
index e436d08..d61f612 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5154e1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5154e1 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_5154e1
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_5154e1
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_5154e1
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_5154e1
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.glsl
index 25ba7d3..107a066 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_519ab5() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_519ab5() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_519ab5() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
index 8117d0a..9297181 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_519ab5() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_519ab5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
index 8117d0a..9297181 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_519ab5() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_519ab5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.msl
index f3117c0..800ef1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_519ab5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.msl
index 60f0a6e..0c8ecc1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_519ab5(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.spvasm
index 61b41a8..6ace38f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/519ab5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_519ab5 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_519ab5
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_519ab5
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_519ab5
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_519ab5
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_519ab5
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.glsl
index 1c86e03..beda284 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_53378a() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_53378a() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_53378a() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
index 3d43e80..9350a9d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_53378a() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53378a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
index 3d43e80..9350a9d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_53378a() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53378a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.msl
index 001fcef..8b13220 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_53378a(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.msl
index 1403be2..5e882a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_53378a(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.spvasm
index 462c0e8..1e32bd2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/53378a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +60,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_53378a = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_53378a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_53378a
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_53378a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_53378a
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_53378a
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_53378a
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
index 2aa6554..9bbd060 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_53941c() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
index 2aa6554..9bbd060 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_53941c() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.msl
index f642a8f..dc94810 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_53941c(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.msl
index 9b1ed0e..5f2be4a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_53941c(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.spvasm
index bcc304d..2140911 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/53941c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_53941c = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4int %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4int %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_53941c
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_53941c
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_53941c
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_53941c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.glsl
index 0890e87..591c092 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_53e142() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_53e142() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_53e142() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
index f88532c..ea9bc7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_53e142() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53e142();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
index f88532c..ea9bc7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_53e142() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53e142();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.msl
index 87b28c9..54fb20c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_53e142(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v, v_1);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.msl
index 9cfc6ef..c508dea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_53e142(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.spvasm
index e645846..c58db60 100644
--- a/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/53e142.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,67 +58,79 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_53e142 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageFetch %v4uint %20 %25 Lod %int_1
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %27 %25
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %20 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpExtInst %v2uint %31 UMin %40 %39
+         %42 = OpCompositeConstruct %v3uint %41 %30
+         %43 = OpImageFetch %v4uint %20 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4uint %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_53e142
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4uint %textureLoad_53e142
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_53e142
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %49
+         %55 = OpLabel
          %56 = OpFunctionCall %v4uint %textureLoad_53e142
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %57 %56 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %69 = OpFunctionCall %v4uint %textureLoad_53e142
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4uint %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.glsl
index 5c210dc..dd98dae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_54a59b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  vec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_54a59b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  vec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_54a59b() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
index a8ce864..e516b1d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54a59b() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54a59b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
index a8ce864..e516b1d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54a59b() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(v_3))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54a59b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.msl
index 3e95fd2..bf034c6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_54a59b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v, v_1);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.msl
index b44d675..86e7ac0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_54a59b(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.spvasm
index c080bbe..ea2929d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/54a59b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %62 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_54a59b = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %int_1
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %29 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v3uint %17 %33
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpExtInst %v2uint %29 UMin %38 %37
+         %40 = OpCompositeConstruct %v3uint %39 %28
+         %41 = OpImageFetch %v4float %17 %40 Lod %33
+               OpStore %res %41
+         %44 = OpLoad %v4float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_54a59b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_54a59b
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_54a59b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %47
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_54a59b
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_54a59b
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %66 = OpFunctionCall %v4float %textureLoad_54a59b
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %47
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.glsl
index 006843c..30919e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_54e0ce() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_54e0ce() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_54e0ce() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
index cbe2497..3b9252c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54e0ce() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54e0ce();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
index cbe2497..3b9252c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54e0ce() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54e0ce();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.msl
index f9c20f2..18bed24 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_54e0ce(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.msl
index 4aa0eb0..f965c05 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_54e0ce(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.spvasm
index 041c36e..1a0aed1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/54e0ce.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,60 +59,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_54e0ce = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-         %23 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+         %27 = OpVectorShuffle %v4float %26 %26 2 1 0 3
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_54e0ce
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_54e0ce
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_54e0ce
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_54e0ce
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_54e0ce
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_54e0ce
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.glsl
index 36f264b..4737481 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_54fb38() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_54fb38() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
index 203e04f..5d1ad55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_54fb38() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
index 203e04f..5d1ad55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_54fb38() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.msl
index 1c686b7..cc4a84c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_54fb38(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.msl
index 78546ec..554c542 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_54fb38(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.spvasm
index 6328aaa..0de8e5b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/54fb38.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %15 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_54fb38 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3uint %15 %uint_1
-         %18 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpExtInst %v2uint %19 UMin %24 %23
+         %26 = OpCompositeConstruct %v3uint %25 %18
+         %27 = OpImageRead %v4uint %12 %26 None
+               OpStore %res %27
+         %30 = OpLoad %v4uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_54fb38
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_54fb38
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_54fb38
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_54fb38
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.glsl
index 5608b3d..b7e9142 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_55e745() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_55e745() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_55e745() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
index 679b3c9..4d182c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_55e745() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_55e745();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
index 679b3c9..4d182c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_55e745() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_55e745();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.msl
index 836502e..0874216 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_55e745(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.msl
index 42bb3ca..0cb7e2a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_55e745(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.spvasm
index 1a21b22..cc97bf8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/55e745.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_55e745 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4int %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_55e745
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_55e745
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_55e745
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_55e745
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_55e745
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_55e745
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.glsl
index 4432746..f34b95b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_560573() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_560573() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_560573() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
index ded1c9c..a42df3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_560573() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_560573();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
index ded1c9c..a42df3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_560573() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_560573();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.msl
index 3a8fc25..9f6865d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_560573(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.msl
index 0f9235b..0f78fe7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_560573(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.spvasm
index cf9b542..05ef1a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/560573.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_560573 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageRead %v4int %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4int %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4int %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_560573
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_560573
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_560573
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_560573
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_560573
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.glsl
index 6491e75..4059f70 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_56a000() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_56a000() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
index f30703c..218fcf6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_56a000() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
index f30703c..218fcf6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_56a000() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.msl
index 6247d28..883492a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_56a000(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.msl
index ef5ff1d..ae15cb8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_56a000(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.spvasm
index a428218..633acd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/56a000.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,34 +37,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_56a000 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_56a000
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_56a000
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_56a000
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.glsl
index cbfcab8..97e5037 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_582015() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_582015() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_582015() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
index 946c6e6..4189bdc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_582015() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_582015();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
index 946c6e6..4189bdc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_582015() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_582015();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.msl
index 92887a4..37466a7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_582015(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.msl
index 40c7b2b..27b56b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_582015(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.spvasm
index dd3197d..e5bf59d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/582015.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_582015 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageRead %v4int %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4int %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4int %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_582015
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_582015
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_582015
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_582015
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_582015
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.glsl
index ffc433d..000a92e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_589eaa() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_589eaa() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_589eaa() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
index aed7ca5..89eed16 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_589eaa() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_589eaa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
index aed7ca5..89eed16 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_589eaa() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_589eaa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.msl
index ee367f3..bc4e13d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_589eaa(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.msl
index 6113d21..fa133d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_589eaa(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.spvasm
index 9305106..7223024 100644
--- a/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/589eaa.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_589eaa = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_589eaa
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_589eaa
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_589eaa
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_589eaa
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_589eaa
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_589eaa
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.glsl
index 87d66cf..c68d64f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_5a2f9d() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_5a2f9d() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_5a2f9d() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
index 3e205ea..8937c69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5a2f9d() {
-  int v = int(int(1));
-  int4 res = int4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5a2f9d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
index 3e205ea..8937c69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5a2f9d() {
-  int v = int(int(1));
-  int4 res = int4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5a2f9d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.msl
index f8c0969..c7e8558 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_5a2f9d(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.msl
index 97fd833..4a2bbdf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5a2f9d(texture1d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.spvasm
index 2c41f47..8722342 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5a2f9d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5a2f9d = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %int_1 Lod %int_1
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %uint %20 %27
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %28 UMin %31 %30
+         %33 = OpImageFetch %v4int %20 %32 Lod %27
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_5a2f9d
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_5a2f9d
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_5a2f9d
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_5a2f9d
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_5a2f9d
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_5a2f9d
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.glsl
index 88fbfc2..db49062 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5abbf2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5abbf2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5abbf2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
index 771abd0..5fd0293 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5abbf2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5abbf2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
index 771abd0..5fd0293 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5abbf2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5abbf2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.msl
index 249243c..c116f10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_5abbf2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.msl
index 245299e..e3f30f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_5abbf2(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.spvasm
index 4a06368..dcc7847 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5abbf2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,56 +62,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5abbf2 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_5abbf2
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_5abbf2
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_5abbf2
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_5abbf2
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_5abbf2
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_5abbf2
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
index fcf1f4b..b35952e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5b0f5b() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
index fcf1f4b..b35952e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5b0f5b() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.msl
index c2a7a69..980e097 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_5b0f5b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.msl
index 13da579..d51e796 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5b0f5b(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(int3(1)));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.spvasm
index 8445d22..0d558ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5b0f5b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_5b0f5b = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpBitcast %v3uint %19
+         %23 = OpExtInst %v3uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_5b0f5b
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_5b0f5b
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_5b0f5b
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_5b0f5b
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
index fc0e5e0..b022efb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5b4947() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
index fc0e5e0..b022efb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5b4947() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.msl
index bb07fdd..4506798 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_5b4947(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.msl
index 1e65995..62dc4d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5b4947(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.spvasm
index 954e71a..1eae2239 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5b4947.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,44 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5b4947 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-         %18 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+         %27 = OpVectorShuffle %v4float %26 %26 2 1 0 3
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_5b4947
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_5b4947
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_5b4947
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_5b4947
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.glsl
index a18af79..6d4ed53 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_5bb7fb() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_5bb7fb() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5bb7fb() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
index 63a7102..36b9a77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5bb7fb() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5bb7fb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
index 63a7102..36b9a77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5bb7fb() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5bb7fb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.msl
index a1f060d..c17a5dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_5bb7fb(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.msl
index dad5cf4..f62eb2d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5bb7fb(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.spvasm
index 415cade..af03134 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5bb7fb.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,62 +61,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5bb7fb = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %int_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageRead %v4uint %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_5bb7fb
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4uint %textureLoad_5bb7fb
          %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_5bb7fb
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4uint %textureLoad_5bb7fb
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_5bb7fb
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
index 35f912b..9e169ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5c69f8() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
index 35f912b..9e169ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5c69f8() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.msl
index 462b630..6bf5808 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_5c69f8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.msl
index 7943f4a..11581be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_5c69f8(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.spvasm
index f10d8c0..8f03eed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5c69f8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,33 +38,36 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_5c69f8 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-         %18 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+         %22 = OpVectorShuffle %v4float %21 %21 2 1 0 3
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_5c69f8
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_5c69f8
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_5c69f8
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_5c69f8
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.glsl
index f879ddd..865300e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_5cd3fc() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_5cd3fc() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
index 0af0ea9..848192b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5cd3fc() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
index 0af0ea9..848192b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5cd3fc() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.msl
index ea134da..ec8e3c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_5cd3fc(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.msl
index 4f42afe..5a75c8b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5cd3fc(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)));
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.spvasm
index a49d548..c7161b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5cd3fc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5cd3fc = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %23 = OpExtInst %v2uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_5cd3fc
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_5cd3fc
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_5cd3fc
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_5cd3fc
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.glsl
index 82415e5..0e850c6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5cee3b() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5cee3b() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5cee3b() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
index c9ba82e..810ee10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5cee3b() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5cee3b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
index c9ba82e..810ee10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5cee3b() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5cee3b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.msl
index c9197ef..9f82003 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_5cee3b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.msl
index 3b52a15..dee66b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_5cee3b(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.spvasm
index 3c4621e..c5b7740 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5cee3b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5cee3b = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpExtInst %v3uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_5cee3b
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_5cee3b
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_5cee3b
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_5cee3b
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_5cee3b
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_5cee3b
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.glsl
index 49d36ae..1a3edb7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_5d0a2f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_5d0a2f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5d0a2f() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
index 95eb04e..90f1645 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5d0a2f() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d0a2f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
index 95eb04e..90f1645 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5d0a2f() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d0a2f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.msl
index 121b5d7..29d1abf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_5d0a2f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.msl
index 1d95d2c..084b1a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5d0a2f(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.spvasm
index 3837e49..676b42f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5d0a2f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5d0a2f = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageRead %v4uint %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4uint %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_5d0a2f
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_5d0a2f
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.glsl
index af4c65f..c6ece8c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_5d4042() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_5d4042() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5d4042() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
index 79c1caa..ac920a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5d4042() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d4042();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
index 79c1caa..ac920a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5d4042() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d4042();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.msl
index 7ff9142..1b50610 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_5d4042(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.msl
index ee88cfa..8e7d5ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5d4042(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.spvasm
index 9fc69be..0d07019 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5d4042.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5d4042 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_5d4042
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_5d4042
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_5d4042
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_5d4042
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_5d4042
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_5d4042
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.glsl
index 28130d6..acbe063 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5dd4c7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5dd4c7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5dd4c7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
index 62e729c..af4f013 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5dd4c7() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5dd4c7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
index 62e729c..af4f013 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5dd4c7() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5dd4c7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.msl
index f530454..3412fc6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_5dd4c7(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.msl
index ca8257d..321968f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5dd4c7(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.spvasm
index ef1debc..c356962 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5dd4c7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5dd4c7 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_5dd4c7
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_5dd4c7
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_5dd4c7
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_5dd4c7
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_5dd4c7
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_5dd4c7
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
index 6deb3ce..73bc6fb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5e17a7() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
index 6deb3ce..73bc6fb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5e17a7() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.msl
index 44f2921..5e53851 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_5e17a7(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.msl
index 9aa0961..ce2c05a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5e17a7(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1));
+  int4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.spvasm
index afbd947..41031c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5e17a7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5e17a7 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %int_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4int %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %17 %15
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4int %textureLoad_5e17a7
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %23 %22 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %20
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4int %textureLoad_5e17a7
          %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_5e17a7
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
index 8726944..02ef43c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5e1843() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
index 8726944..02ef43c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5e1843() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.msl
index 4f01b64..7ce83ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_5e1843(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.msl
index fdaf9bd..c3d678d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_5e1843(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.spvasm
index 47659c2..2b5d7a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5e1843.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,43 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %15 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_5e1843 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3uint %15 %uint_1
-         %18 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpExtInst %v2uint %19 UMin %24 %23
+         %26 = OpCompositeConstruct %v3uint %25 %18
+         %27 = OpImageRead %v4uint %12 %26 None
+               OpStore %res %27
+         %30 = OpLoad %v4uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_5e1843
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_5e1843
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_5e1843
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_5e1843
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.glsl
index 9b92a77..5745e87 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_5e8d3f() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_5e8d3f() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_5e8d3f() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
index 560df1b..6ae9669 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5e8d3f() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5e8d3f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
index 560df1b..6ae9669 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5e8d3f() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5e8d3f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.msl
index 3bf9f91..e398bd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_5e8d3f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.msl
index 8d505dc..bc6c0f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_5e8d3f(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.spvasm
index 00738a4..e62cd85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5e8d3f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5e8d3f = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpExtInst %v3uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_5e8d3f
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_5e8d3f
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_5e8d3f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_5e8d3f
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_5e8d3f
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_5e8d3f
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.glsl
index 037e22a..a435f9b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_5ed6ad() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_5ed6ad() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, r8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5ed6ad() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
index b931505..12652b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5ed6ad() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5ed6ad();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
index b931505..12652b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5ed6ad() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5ed6ad();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.msl
index 691fe4d..a64b155 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_5ed6ad(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.msl
index 3c030ab..0e6874b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_5ed6ad(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.spvasm
index 76b81af..21b441c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5ed6ad.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5ed6ad = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_5ed6ad
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_5ed6ad
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_5ed6ad
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_5ed6ad
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_5ed6ad
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_5ed6ad
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.glsl
index 7812c33..7ddb08d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5f4473() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5f4473() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5f4473() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
index 02d5eb9..a80d14c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5f4473() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5f4473();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
index 02d5eb9..a80d14c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5f4473() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5f4473();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.msl
index dd6c5fc..db3af94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_5f4473(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.msl
index 1c70364..21fbf55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_5f4473(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.spvasm
index f126c11..cc7dca5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5f4473.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5f4473 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpExtInst %v3uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_5f4473
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_5f4473
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_5f4473
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_5f4473
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_5f4473
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_5f4473
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.glsl
index fe144c3..f4d4af3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5feb4d() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5feb4d() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5feb4d() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
index 45bb608..6fe269f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5feb4d() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5feb4d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
index 45bb608..6fe269f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5feb4d() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5feb4d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.msl
index c88e049..a5b4ea7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_5feb4d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.msl
index d49c097..c10934f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_5feb4d(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.spvasm
index 1a201ab..7ce72b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/5feb4d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,56 +61,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5feb4d = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_5feb4d
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_5feb4d
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_5feb4d
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_5feb4d
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_5feb4d
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_5feb4d
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.glsl
index 99162b2..09a1143 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6154d4() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6154d4() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6154d4() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
index 1f67e3d..1d3cad4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6154d4() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6154d4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
index 1f67e3d..1d3cad4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6154d4() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6154d4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.msl
index 357494d..684b74c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_6154d4(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.msl
index bcefdea..d4f613d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6154d4(texture2d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.spvasm
index df3041f..3bf5d37 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6154d4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6154d4 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %int_1
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %36 = OpExtInst %v2uint %28 UMin %33 %31
+         %37 = OpImageFetch %v4uint %20 %36 Lod %27
+               OpStore %res %37
+         %40 = OpLoad %v4uint %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_6154d4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_6154d4
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%fragment_main = OpFunction %void None %43
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_6154d4
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v4uint %textureLoad_6154d4
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4uint %textureLoad_6154d4
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %55
          %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %64 = OpFunctionCall %v4uint %textureLoad_6154d4
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4uint %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.glsl
index 5eb27a2..57af65f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_61e2e8() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_61e2e8() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
index f242a12..cf67bfd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_61e2e8() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
index f242a12..cf67bfd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_61e2e8() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.msl
index 0c8b83a..909aad4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_61e2e8(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.msl
index 8b2299c..2c624d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_61e2e8(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(uint3(1u)));
+  int4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.spvasm
index 766ff1e..a62b9a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/61e2e8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_61e2e8 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_61e2e8
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_61e2e8
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_61e2e8
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_61e2e8
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.glsl
index 760e33d..a28cf5c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_620caa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_620caa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_620caa() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
index 1564475..f5a1eec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_620caa() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_620caa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
index 1564475..f5a1eec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_620caa() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_620caa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.msl
index 93286a1..9cbd094 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_620caa(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.msl
index 10ee7b5..7b21c94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_620caa(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.spvasm
index c3ebe9f..f9a85eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/620caa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,60 +63,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_620caa = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_620caa
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_620caa
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_620caa
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_620caa
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_620caa
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_620caa
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
index 53a5b62..21ac807 100644
--- a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_622278() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
index 53a5b62..21ac807 100644
--- a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_622278() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.msl
index 3d4a2a9..41d6493 100644
--- a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_622278(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.msl
index 807c0aa..a49b294 100644
--- a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_622278(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(int3(1)));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.spvasm
index 143bb8f..a3fdd19 100644
--- a/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/622278.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_622278 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpBitcast %v3uint %19
+         %23 = OpExtInst %v3uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_622278
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_622278
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_622278
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_622278
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.glsl
index f1f2360..99460e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_6273b1() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  float res = texelFetch(arg_0, v_2, int(1)).x;
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_6273b1() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  float res = texelFetch(arg_0, v_2, int(1)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_6273b1() {
-  ivec2 v = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v, int(1)).x;
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  float res = texelFetch(arg_0, v_1, int(1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
index 52ecf3e..05e80a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_6273b1() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(v, int(int(1))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float res = arg_0.Load(v_2, int(int(1))).x;
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6273b1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
index 52ecf3e..05e80a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_6273b1() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(v, int(int(1))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float res = arg_0.Load(v_2, int(int(1))).x;
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6273b1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.msl
index fcdf6d0..0add337 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_6273b1(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.msl
index 21e80c2..19e16e0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_6273b1(depth2d_ms<float, access::read> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.spvasm
index 3d480b6..cacf108 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6273b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,72 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6273b1 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %int_1
-         %23 = OpCompositeExtract %float %18 0
-               OpStore %res %23
-         %26 = OpLoad %float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageFetch %v4float %17 %29 Sample %int_1
+         %32 = OpCompositeExtract %float %31 0
+               OpStore %res %32
+         %35 = OpLoad %float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %float %textureLoad_6273b1
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %float %textureLoad_6273b1
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %37 = OpLabel
-         %38 = OpFunctionCall %float %textureLoad_6273b1
-         %39 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %float %textureLoad_6273b1
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_6273b1
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %59 = OpFunctionCall %float %textureLoad_6273b1
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.glsl
index 6246887..1207991 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_62d125() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_62d125() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_62d125() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
index 921b8d0..b688f71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_62d125() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d125();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
index 921b8d0..b688f71 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_62d125() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d125();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.msl
index fad5d80..34a3789 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_62d125(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.msl
index 8557dfd..694913d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_62d125(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.spvasm
index 4829b86..b71b9a4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/62d125.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_62d125 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_62d125
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_62d125
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_62d125
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_62d125
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_62d125
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_62d125
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.glsl
index a619901..0690f43a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_62d1de() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_62d1de() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_62d1de() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_2 = (uvec2(textureSize(arg_0, int(v_1))).x - 1u);
+  ivec2 v_3 = ivec2(uvec2(min(uint(1), v_2), 0u));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
index 0987243..374b2e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_62d1de() {
-  int v = int(int(1));
-  int4 res = int4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  int4 res = int4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d1de();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
index 0987243..374b2e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_62d1de() {
-  int v = int(int(1));
-  int4 res = int4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  int4 res = int4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d1de();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.msl
index 319461b..df37e74 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_62d1de(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.msl
index 55b9317..913f608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_62d1de(texture1d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.spvasm
index 4bde99d..fdf306d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/62d1de.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,69 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %int_1 = OpConstant %int 1
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
+      %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_62d1de = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %int_1 Lod %uint_1
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %uint %20 %25
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %31 = OpExtInst %uint %26 UMin %29 %28
+         %32 = OpImageFetch %v4int %20 %31 Lod %25
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_62d1de
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_62d1de
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_62d1de
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_62d1de
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_62d1de
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_62d1de
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.glsl
index b22cc00..fd1f2cf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_639962() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_639962() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp isampler2DMS arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_639962() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v, int(1u));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
index e8b0a48..e184941 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_639962() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_639962();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
index e8b0a48..e184941 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_639962() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_1, int(1u)));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_639962();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.msl
index fd08121..e8003c0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_639962(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.msl
index 58860d6..cfbe944 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_639962(texture2d_ms<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.spvasm
index be4c8b8..5eaf4c3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/639962.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_639962 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Sample %uint_1
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageFetch %v4int %20 %27 Sample %uint_1
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_639962
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_639962
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_639962
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_639962
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_639962
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_639962
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.glsl
index 7ed08e5..e67b198 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_63be18() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_63be18() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_63be18() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
index f60b2a5..9333a33 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_63be18() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_63be18();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
index f60b2a5..9333a33 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_63be18() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_63be18();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.msl
index a7b7c2f..fd9aa50 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_63be18(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.msl
index 34a18c9..16115f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_63be18(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.spvasm
index 5789b9e..a8a7200 100644
--- a/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/63be18.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,63 +62,71 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_63be18 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageRead %v4int %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4int %20 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_63be18
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_63be18
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_63be18
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_63be18
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_63be18
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_63be18
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
index c4786e3..c31feb0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_64c372() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
index c4786e3..c31feb0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_64c372() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.msl
index 7bbca49..ebd490f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 uint4 textureLoad_64c372(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.msl
index 6ef1b37..845eba7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_64c372(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.spvasm
index 8b5a416..70206cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/64c372.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_64c372 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4uint %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4uint %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_64c372
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_64c372
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_64c372
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_64c372
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.glsl
index f6f277c..e41ebf8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_656d76() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_656d76() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_656d76() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
index 41471c8..f368b95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_656d76() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_656d76();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
index 41471c8..f368b95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_656d76() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_656d76();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.msl
index 736db50..c3d9f81 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_656d76(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.msl
index aadeabf..d71d074 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_656d76(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.spvasm
index 381421f..0b3574f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/656d76.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,81 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
-      %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %41 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_656d76 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageFetch %v4uint %20 %23 Lod %uint_1
-               OpStore %res %27
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %27 %25
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %31 UMin %uint_1 %33
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %41
+         %43 = OpExtInst %v2uint %31 UMin %40 %38
+         %44 = OpCompositeConstruct %v3uint %43 %30
+         %45 = OpImageFetch %v4uint %20 %44 Lod %34
+               OpStore %res %45
+         %48 = OpLoad %v4uint %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_656d76
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_656d76
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_656d76
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %51
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_656d76
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %55 = OpFunctionCall %v4uint %textureLoad_656d76
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_656d76
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.glsl
index a5c460b..fe951e0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_65a4d0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_65a4d0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_65a4d0() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
index 5415c62..b6ea6c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_65a4d0() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_65a4d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
index 5415c62..b6ea6c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_65a4d0() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_65a4d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.msl
index 4bf4fe3..dd0d80a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_65a4d0(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.msl
index d281d8b..381a337 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_65a4d0(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.spvasm
index 2786b6f..97708a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/65a4d0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_65a4d0 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_65a4d0
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_65a4d0
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_65a4d0
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_65a4d0
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_65a4d0
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_65a4d0
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
index 8bb2ddf..902372f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_666010() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
index 8bb2ddf..902372f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_666010() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.msl
index 01c5d8d..88f81cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_666010(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.msl
index 69135d7..4264f25 100644
--- a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_666010(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.spvasm
index e28d5a1..19fe3cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/666010.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_666010 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_666010
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_666010
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_666010
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_666010
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.glsl
index da4586b..c1b33a4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_6678b6() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_6678b6() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_6678b6() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
index b2a498e..4093eff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_6678b6() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6678b6();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
index b2a498e..4093eff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_6678b6() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6678b6();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.msl
index 70c2927..079a520 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_6678b6(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.msl
index 35b86af..a45264b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_6678b6(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.spvasm
index f6cd4ed..bf54c16 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6678b6.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6678b6 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %int_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_6678b6
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4int %textureLoad_6678b6
          %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_6678b6
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4int %textureLoad_6678b6
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_6678b6
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.glsl
index f1478fb..c83f3e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_66be47() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_3)).x;
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_66be47() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_66be47() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  float res = texelFetch(arg_0, v_5, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
index 15497cd..831e099 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_66be47() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_66be47();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
index 15497cd..831e099 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_66be47() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_66be47();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.msl
index c89e878..8af88e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_66be47(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.msl
index f8c75ec..cf1b3c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_66be47(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.spvasm
index 923e902..8d69518 100644
--- a/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/66be47.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,69 +55,82 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %36 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %46 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_66be47 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %uint_1
-         %28 = OpCompositeExtract %float %27 0
-               OpStore %res %28
-         %31 = OpLoad %float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageQuerySizeLod %v3uint %17 %29
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %36
+         %40 = OpExtInst %v2uint %26 UMin %35 %33
+         %41 = OpCompositeConstruct %v3uint %40 %25
+         %42 = OpImageFetch %v4float %17 %41 Lod %29
+         %43 = OpCompositeExtract %float %42 0
+               OpStore %res %43
+         %46 = OpLoad %float %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %float %textureLoad_66be47
-         %37 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %float %textureLoad_66be47
+         %52 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %float %textureLoad_66be47
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %49
+         %55 = OpLabel
+         %56 = OpFunctionCall %float %textureLoad_66be47
+         %57 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %55 = OpFunctionCall %float %textureLoad_66be47
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %69 = OpFunctionCall %float %textureLoad_66be47
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %float %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %49
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %float %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.glsl
index ca987d0..3542d04 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_67d826() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_67d826() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
index 738d6d7..772446a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_67d826() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
index 738d6d7..772446a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_67d826() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.msl
index 8e2f4c9..8664772 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_67d826(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.msl
index ac29354..2a8514f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_67d826(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.spvasm
index 770ad53..dc65694 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/67d826.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,40 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_67d826 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_67d826
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_67d826
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_67d826
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_67d826
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.glsl
index d721635..89bdd8d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_67edca() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_67edca() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_67edca() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
index 7d3a453..9a0fc1e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_67edca() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_67edca();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
index 7d3a453..9a0fc1e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_67edca() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_67edca();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.msl
index 4622547..e0c6c00 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_67edca(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.msl
index 02fd790..68d49e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_67edca(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.spvasm
index 7dc7781..17b1dfd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/67edca.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_67edca = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpBitcast %v3uint %27
+         %31 = OpExtInst %v3uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_67edca
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_67edca
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_67edca
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_67edca
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_67edca
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_67edca
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
index 9b9124e..2ead684 100644
--- a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_68d273() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
index 9b9124e..2ead684 100644
--- a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_68d273() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.msl
index 6cf1315..1686676 100644
--- a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_68d273(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.msl
index 443de54..d1ad2b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_68d273(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(uint3(1u)));
+  int4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.spvasm
index f7f4dd7..79686b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/68d273.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_68d273 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_68d273
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_68d273
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_68d273
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_68d273
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.glsl
index 550e945..9f5c49e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_6925bc() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  float res = texelFetch(arg_0, v_2, int(1u)).x;
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_6925bc() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  float res = texelFetch(arg_0, v_2, int(1u)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_6925bc() {
-  ivec2 v = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v, int(1u)).x;
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  float res = texelFetch(arg_0, v_1, int(1u)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
index c56ffd2..a665f88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_6925bc() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(v, int(1u)).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float res = arg_0.Load(v_2, int(1u)).x;
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6925bc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
index c56ffd2..a665f88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_6925bc() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(v, int(1u)).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float res = arg_0.Load(v_2, int(1u)).x;
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6925bc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.msl
index 4e55dad..c1b6629 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_6925bc(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1u);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.msl
index 5ee8e34..79b257f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_6925bc(depth2d_ms<float, access::read> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.spvasm
index 5bf037c..1695c67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6925bc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,72 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %43 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6925bc = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %uint_1
-         %25 = OpCompositeExtract %float %18 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageFetch %v4float %17 %29 Sample %uint_1
+         %32 = OpCompositeExtract %float %31 0
+               OpStore %res %32
+         %35 = OpLoad %float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_6925bc
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %float %textureLoad_6925bc
+         %41 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_6925bc
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %float %textureLoad_6925bc
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_6925bc
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %59 = OpFunctionCall %float %textureLoad_6925bc
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.glsl
index d0bf408..c092bd5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_69fee5() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_69fee5() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
index c980e99..61c1a36 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_69fee5() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
index c980e99..61c1a36 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_69fee5() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.msl
index 515c898..552dff8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_69fee5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.msl
index 0e4991b..59878a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_69fee5(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.spvasm
index 1cbb814..4448acf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/69fee5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_69fee5 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_69fee5
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_69fee5
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_69fee5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_69fee5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
index 63e30f2..41212e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6a6871() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
index 63e30f2..41212e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6a6871() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.msl
index 8c51cf2..b249416 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_6a6871(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.msl
index 90540f3..6e50d47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6a6871(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.spvasm
index b013595..aae4962 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6a6871.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6a6871 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_6a6871
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_6a6871
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_6a6871
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_6a6871
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.glsl
index e0b434d..d45d890 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6b77d4() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6b77d4() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6b77d4() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_2 = (uvec2(textureSize(arg_0, int(v_1))).x - 1u);
+  ivec2 v_3 = ivec2(uvec2(min(uint(1), v_2), 0u));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
index fa8502c..834cba7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6b77d4() {
-  int v = int(int(1));
-  uint4 res = uint4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  uint4 res = uint4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6b77d4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
index fa8502c..834cba7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6b77d4() {
-  int v = int(int(1));
-  uint4 res = uint4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  uint v_2 = (v_1.x - 1u);
+  int v_3 = int(min(uint(int(1)), v_2));
+  uint4 res = uint4(arg_0.Load(int2(v_3, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6b77d4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.msl
index 62f9f3b..fcd26ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_6b77d4(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.msl
index 8b8187e..a7e42f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6b77d4(texture1d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.spvasm
index 44a6657..5ffe2dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6b77d4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,69 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6b77d4 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %int_1 Lod %uint_1
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %uint %20 %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %int_1
+         %31 = OpExtInst %uint %25 UMin %28 %27
+         %32 = OpImageFetch %v4uint %20 %31 Lod %24
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_6b77d4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_6b77d4
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_6b77d4
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_6b77d4
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_6b77d4
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_6b77d4
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
index c3d6572..487f2f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6b8ba6() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
index c3d6572..487f2f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6b8ba6() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.msl
index 1585f92..c046225 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_6b8ba6(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.msl
index 94258d3..c832367 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_6b8ba6(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.spvasm
index 669f705..cf40d94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6b8ba6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6b8ba6 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_6b8ba6
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_6b8ba6
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6b8ba6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_6b8ba6
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
index 15e7837..1c6e6fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6ba9ab() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
index 15e7837..1c6e6fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6ba9ab() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.msl
index fa18670..1a70d9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_6ba9ab(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.msl
index 8ffcbbc..04b0df7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_6ba9ab(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.spvasm
index b178855..e7a145d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6ba9ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6ba9ab = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_6ba9ab
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_6ba9ab
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6ba9ab
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_6ba9ab
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
index e05e61d9..cb1fead 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6bf3e2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
index e05e61d9..cb1fead 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6bf3e2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.msl
index 86b5358..8ba57bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_6bf3e2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.msl
index fc1f6f5..a288600 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6bf3e2(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.spvasm
index f7005c4..d2501a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf3e2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 39
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,41 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6bf3e2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-         %23 = OpVectorShuffle %v4float %22 %22 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+         %34 = OpVectorShuffle %v4float %33 %33 2 1 0 3
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_6bf3e2
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_6bf3e2
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_6bf3e2
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_6bf3e2
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.glsl
index 966b99e..6827dbe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_6bf4b7() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_6bf4b7() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6bf4b7() {
-  ivec3 v = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_2 = (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u));
+  ivec3 v_3 = ivec3(min(uvec3(ivec3(1)), v_2));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
index f5a834b..b840f0f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6bf4b7() {
-  int3 v = int3((int(1)).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6bf4b7();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
index f5a834b..b840f0f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_6bf4b7() {
-  int3 v = int3((int(1)).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6bf4b7();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.msl
index 72d37b5..d6b034f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_6bf4b7(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1u);
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.msl
index 9008dca..cb2b1da 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6bf4b7(texture3d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.spvasm
index 8449d2e..1d2fc94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6bf4b7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
-     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6bf4b7 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v3uint %20 %24
+         %28 = OpISub %v3uint %26 %29
+         %30 = OpBitcast %v3uint %31
+         %35 = OpExtInst %v3uint %25 UMin %30 %28
+         %36 = OpImageFetch %v4uint %20 %35 Lod %24
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.glsl
index 31ab246..f827df0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_6d1fb4() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_6d1fb4() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
index 25d0393..6561a8b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_6d1fb4() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
index 25d0393..6561a8b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_6d1fb4() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.msl
index 37b3da4..5332999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_6d1fb4(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.msl
index 869b455..b9d31e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_6d1fb4(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.spvasm
index d12a7de..64f5e4c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6d1fb4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,43 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %15 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_6d1fb4 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3uint %15 %uint_1
-         %18 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpExtInst %v2uint %19 UMin %24 %23
+         %26 = OpCompositeConstruct %v3uint %25 %18
+         %27 = OpImageRead %v4uint %12 %26 None
+               OpStore %res %27
+         %30 = OpLoad %v4uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_6d1fb4
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_6d1fb4
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_6d1fb4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_6d1fb4
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.glsl
index 87cbaef..24ec9d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_6d376a() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_6d376a() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_6d376a() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_1))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
index 56b7161..a718242 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6d376a() {
-  int v = int(1u);
-  float4 res = float4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6d376a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
index 56b7161..a718242 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6d376a() {
-  int v = int(1u);
-  float4 res = float4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6d376a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.msl
index de2f349..fd724e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_6d376a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.msl
index 02a51ef..cb35c8c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_6d376a(texture1d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.spvasm
index b55c8da..1b348d2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6d376a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,56 +60,62 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6d376a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %uint_1 Lod %uint_1
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %uint %17 %22
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %23 UMin %uint_1 %25
+         %27 = OpImageFetch %v4float %17 %26 Lod %22
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_6d376a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_6d376a
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_6d376a
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_6d376a
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_6d376a
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_6d376a
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
index 7c878c2..b771133 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6d7bb5() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
index 7c878c2..b771133 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6d7bb5() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.msl
index a8a9f9a..fe053f7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_6d7bb5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.msl
index cc65909..23a3c1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6d7bb5(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.spvasm
index 67941f3..5055255 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6d7bb5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6d7bb5 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_6d7bb5
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_6d7bb5
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_6d7bb5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_6d7bb5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
index d54bb4a..bfe07df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_6e903f() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
index d54bb4a..bfe07df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_6e903f() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.msl
index 2d5d9d5..3e8ec64 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_6e903f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.msl
index 1825935..3bdce99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_6e903f(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(int3(1)));
+  int4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.spvasm
index 04eda78..23be681 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6e903f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6e903f = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %23 = OpExtInst %v3uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_6e903f
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_6e903f
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_6e903f
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_6e903f
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.glsl
index 3ae1e9da..d267c5b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_6f0370() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_6f0370() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_6f0370() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
index b8b3ab8..d53db2a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f0370() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f0370();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
index b8b3ab8..d53db2a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f0370() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f0370();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.msl
index 933a6d7..71f5973 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_6f0370(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.msl
index 0d4c250..5e80235 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_6f0370(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.spvasm
index 655e19b..8d46147 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0370.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,59 +60,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6f0370 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_6f0370
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_6f0370
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_6f0370
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_6f0370
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_6f0370
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_6f0370
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
index a76f5f7..464e59c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f0ea8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
index a76f5f7..464e59c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f0ea8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.msl
index 7f2a09b..eac7500 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_6f0ea8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.msl
index 4952ee6..4aa71ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6f0ea8(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.spvasm
index 8dbd3eb..f42ffcc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6f0ea8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6f0ea8 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_6f0ea8
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_6f0ea8
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_6f0ea8
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_6f0ea8
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.glsl
index 7f42e63..89bb80a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_6f1750() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_6f1750() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_6f1750() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
index 6e8b90d..0f0e471 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f1750() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f1750();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
index 6e8b90d..0f0e471 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f1750() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f1750();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.msl
index 2353b91..bf8883e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_6f1750(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.msl
index d91442e..1ea7999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_6f1750(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.spvasm
index 5f8257a..0b389d1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6f1750.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6f1750 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_6f1750
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_6f1750
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_6f1750
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_6f1750
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_6f1750
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_6f1750
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
index cc0777e..0f20a13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f8927() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
index cc0777e..0f20a13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f8927() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.msl
index 7e681c3..fb2f93a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_6f8927(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.msl
index f1db0a0..60a2ff9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6f8927(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.spvasm
index da88363..e683e3b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/6f8927.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,40 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6f8927 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_6f8927
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_6f8927
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_6f8927
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_6f8927
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.glsl
index 5160bea..24b1303 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_714471() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_714471() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_714471() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
index 683fefb..1bcfcbf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_714471() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_714471();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
index 683fefb..1bcfcbf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_714471() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_714471();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.msl
index 6fd8171..712c4eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_714471(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.msl
index ecd1ea1..0cf37ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_714471(texture2d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.spvasm
index feed88f..2c1ba06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/714471.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,68 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_714471 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %uint_1
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v2uint %20 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %26 UMin %30 %29
+         %32 = OpImageFetch %v4int %20 %31 Lod %25
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_714471
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_714471
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_714471
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_714471
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_714471
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_714471
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.glsl
index d8baf3a..b64e88e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_72bb3c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_72bb3c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_72bb3c() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
index 32cad97..be8f37c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_72bb3c() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_72bb3c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
index 32cad97..be8f37c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_72bb3c() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_72bb3c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.msl
index e4b6af7..6772d8b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_72bb3c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.msl
index e8a1035..578b383 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_72bb3c(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.spvasm
index ae508d9..3cbc5f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/72bb3c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_72bb3c = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_72bb3c
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_72bb3c
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_72bb3c
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_72bb3c
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_72bb3c
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_72bb3c
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.glsl
index b2b21f2..fc427ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_72c9c3() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_72c9c3() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
index f583959..7c77b7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_72c9c3() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
index f583959..7c77b7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_72c9c3() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.msl
index c2fcdc9..a23accc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_72c9c3(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.msl
index 7eeb7e1..aebf0ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_72c9c3(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.spvasm
index 6d20516..0759809 100644
--- a/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/72c9c3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,40 +36,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_72c9c3 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_72c9c3
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_72c9c3
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_72c9c3
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_72c9c3
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
index e6e97b7..fb5eaee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_742f1b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
index e6e97b7..fb5eaee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_742f1b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.msl
index 3f95f73..56fbf1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_742f1b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.msl
index 9d66902..bd951ed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_742f1b(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.spvasm
index e849fb6..68dd529 100644
--- a/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/742f1b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_742f1b = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_742f1b
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_742f1b
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_742f1b
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_742f1b
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.glsl
index 0fcb02a..12edffe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_749704() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_749704() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_749704() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
index 7a2aa2b..b5d2199 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_749704() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_749704();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
index 7a2aa2b..b5d2199 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_749704() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_749704();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.msl
index da98853..7d1c6b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_749704(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.msl
index 5fc245e..e9e7a6f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_749704(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.spvasm
index 082cf2f..eefa8ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/749704.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_749704 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_749704
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_749704
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_749704
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_749704
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_749704
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_749704
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
index bce9552..4b9e40e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_74a387() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
index bce9552..4b9e40e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_74a387() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.msl
index 26ece70..02fe185 100644
--- a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_74a387(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.msl
index 6580cd9..a81ead22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_74a387(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1u));
+  int4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.spvasm
index 540eec2..697dfd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/74a387.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_74a387 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4int %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4int %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4int %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4int %textureLoad_74a387
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4int %textureLoad_74a387
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_74a387
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_74a387
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.glsl
index e6bd583..65ac62c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_773c46() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_773c46() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_773c46() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
index 731d80c..3c7a3ed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_773c46() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_773c46();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
index 731d80c..3c7a3ed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_773c46() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_773c46();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.msl
index 72aa683..04f38ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_773c46(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.msl
index af86f90..cb82c92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_773c46(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.spvasm
index 28edeec..5b0fd60 100644
--- a/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/773c46.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_773c46 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_773c46
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_773c46
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_773c46
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_773c46
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_773c46
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_773c46
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.glsl
index 09c4753..9e46619 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_789045() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  vec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_789045() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  vec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_789045() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
index e2d3a88..a18d136 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_789045() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_789045();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
index e2d3a88..a18d136 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_789045() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_789045();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.msl
index 776488c..e2ae27a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_789045(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.msl
index a87502a..18abc2b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_789045(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.spvasm
index 44f40c2..078a41c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/789045.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,81 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
-      %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %39 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_789045 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %uint_1
-               OpStore %res %24
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %39
+         %41 = OpExtInst %v2uint %29 UMin %38 %36
+         %42 = OpCompositeConstruct %v3uint %41 %28
+         %43 = OpImageFetch %v4float %17 %42 Lod %32
+               OpStore %res %43
+         %46 = OpLoad %v4float %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_789045
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_789045
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_789045
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_789045
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %32
+%compute_main = OpFunction %void None %49
          %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+         %56 = OpFunctionCall %v4float %textureLoad_789045
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_789045
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.glsl
index bc72061..a883b73 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.glsl
@@ -2,15 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_79e697() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_79e697() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_79e697() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
index 0f99eee..ee1a559 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_79e697() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_79e697();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
index 0f99eee..ee1a559 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_79e697() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_79e697();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.msl
index b1eb98b..25ebd09 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.ir.msl
@@ -17,7 +17,10 @@
 };
 
 int4 textureLoad_79e697(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_2), v, v_1);
   return res;
 }
 
@@ -40,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.msl
index 79f34bd..00173e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_79e697(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.spvasm
index 233c90a..bebe254 100644
--- a/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/79e697.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 80
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,82 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %42 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %67 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %70 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_79e697 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageFetch %v4int %20 %22 Lod %int_1
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %28 %26
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %20 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %42
+         %44 = OpExtInst %v2uint %31 UMin %41 %39
+         %45 = OpCompositeConstruct %v3uint %44 %30
+         %46 = OpImageFetch %v4int %20 %45 Lod %35
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_79e697
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_79e697
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_79e697
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_79e697
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %32
+%compute_main = OpFunction %void None %52
          %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+         %59 = OpFunctionCall %v4int %textureLoad_79e697
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %60 %59 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %70 None
+         %71 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %72 = OpFunctionCall %v4int %textureLoad_79e697
+               OpStore %71 %72 None
+         %73 = OpLoad %VertexOutput %out None
+               OpReturnValue %73
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %75 = OpLabel
+         %76 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %77 = OpCompositeExtract %v4float %76 0
+               OpStore %vertex_main_position_Output %77 None
+         %78 = OpCompositeExtract %v4int %76 1
+               OpStore %vertex_main_loc0_Output %78 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.glsl
index 4b064eb..5392a24 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7ab4df() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7ab4df() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_7ab4df() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_1));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
index 08f3365..37c52cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_7ab4df() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7ab4df();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
index 08f3365..37c52cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_7ab4df() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7ab4df();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.msl
index fe3cc8f..c6118b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_7ab4df(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.msl
index 9706a86..d7e0b5b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_7ab4df(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.spvasm
index 1c4f56b..a06e524 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7ab4df.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,67 +58,81 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+        %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %41 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7ab4df = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageFetch %v4uint %20 %25 Lod %int_1
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQueryLevels %uint %20
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_1
+         %34 = OpExtInst %uint %28 UMin %31 %30
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %41
+         %43 = OpExtInst %v2uint %28 UMin %40 %38
+         %44 = OpCompositeConstruct %v3uint %43 %27
+         %45 = OpImageFetch %v4uint %20 %44 Lod %34
+               OpStore %res %45
+         %48 = OpLoad %v4uint %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_7ab4df
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_7ab4df
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_7ab4df
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %51
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_7ab4df
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_7ab4df
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_7ab4df
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.glsl
index daa0f1a..6ef9a43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.glsl
@@ -2,15 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_7b63e0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 void main() {
@@ -18,15 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_7b63e0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_7b63e0() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u))));
+  ivec3 v_4 = ivec3(v_3, int(v_1));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
index 82453e6..a34b868 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_7b63e0() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7b63e0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
index 82453e6..a34b868 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_7b63e0() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7b63e0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.msl
index cfd045f..672303e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float textureLoad_7b63e0(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1u);
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.msl
index 9858232..13ef27a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float textureLoad_7b63e0(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.spvasm
index 8bfaf57..dd5a14a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7b63e0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,75 @@
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %43 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7b63e0 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %uint_1
-         %25 = OpCompositeExtract %float %24 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageQuerySizeLod %v3uint %17 %29
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpExtInst %v2uint %26 UMin %34 %33
+         %36 = OpCompositeConstruct %v3uint %35 %25
+         %37 = OpImageFetch %v4float %17 %36 Lod %29
+         %38 = OpCompositeExtract %float %37 0
+               OpStore %res %38
+         %41 = OpLoad %float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_7b63e0
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %float %textureLoad_7b63e0
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_7b63e0
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %44
+         %50 = OpLabel
+         %51 = OpFunctionCall %float %textureLoad_7b63e0
+         %52 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_7b63e0
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %64 = OpFunctionCall %float %textureLoad_7b63e0
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.glsl
index 384d5d2..39cbd4d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_7bee94() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_7bee94() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp isampler2DMS arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_7bee94() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   ivec4 res = texelFetch(arg_0, v, int(1));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
index b9fc2b7..e442080 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_7bee94() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7bee94();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
index b9fc2b7..e442080 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_7bee94() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7bee94();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.msl
index 81c05f9..0bef9ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_7bee94(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.msl
index 6afa9f9..69f8cfd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_7bee94(texture2d_ms<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.spvasm
index 8f1df10..61a3f00 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7bee94.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,61 +61,64 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7bee94 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Sample %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageFetch %v4int %20 %27 Sample %int_1
+               OpStore %res %29
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_7bee94
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_7bee94
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_7bee94
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_7bee94
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_7bee94
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_7bee94
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.glsl
index 6442881..be8365c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.glsl
@@ -2,15 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7c90e5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7c90e5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_7c90e5() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
index 6c6ceaf..226a220 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_7c90e5() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7c90e5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
index 6c6ceaf..226a220 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_7c90e5() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7c90e5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.msl
index 8a2f85c..8a31d46 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.ir.msl
@@ -17,7 +17,10 @@
 };
 
 uint4 textureLoad_7c90e5(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_2), v, v_1);
   return res;
 }
 
@@ -40,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.msl
index d91abcd..d7f0dc7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_7c90e5(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.spvasm
index 567aaf6..268dc83 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7c90e5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 80
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,82 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %42 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %67 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %70 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7c90e5 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageFetch %v4uint %20 %23 Lod %int_1
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %27 %25
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %20 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %42
+         %44 = OpExtInst %v2uint %31 UMin %41 %39
+         %45 = OpCompositeConstruct %v3uint %44 %30
+         %46 = OpImageFetch %v4uint %20 %45 Lod %35
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_7c90e5
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_7c90e5
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_7c90e5
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %55 = OpFunctionCall %v4uint %textureLoad_7c90e5
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %33
+%compute_main = OpFunction %void None %52
          %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+         %59 = OpFunctionCall %v4uint %textureLoad_7c90e5
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %60 %59 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %70 None
+         %71 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %72 = OpFunctionCall %v4uint %textureLoad_7c90e5
+               OpStore %71 %72 None
+         %73 = OpLoad %VertexOutput %out None
+               OpReturnValue %73
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %75 = OpLabel
+         %76 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %77 = OpCompositeExtract %v4float %76 0
+               OpStore %vertex_main_position_Output %77 None
+         %78 = OpCompositeExtract %v4uint %76 1
+               OpStore %vertex_main_loc0_Output %78 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.glsl
index 617b574..8c58243 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_7dab57() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_7dab57() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_7dab57() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
index d4ae10a..0a5f1ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_7dab57() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7dab57();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
index d4ae10a..0a5f1ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_7dab57() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7dab57();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.msl
index cc4ca9b..5b2361c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_7dab57(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.msl
index e26b9d8..50f273c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_7dab57(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.spvasm
index 0482c94..5e28054 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7dab57.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,66 +61,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7dab57 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4int %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_7dab57
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_7dab57
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_7dab57
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_7dab57
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_7dab57
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_7dab57
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.glsl
index 325ba49..584e0a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_7dd3d5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_7dd3d5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
index 13c00b4..9b8b2b6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7dd3d5() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
index 13c00b4..9b8b2b6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7dd3d5() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.msl
index 3aabe8d..5ef46cf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_7dd3d5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.msl
index 1dcf976..e577fa2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_7dd3d5(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.spvasm
index 5917fb8..db0c135 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7dd3d5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_7dd3d5 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_7dd3d5
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_7dd3d5
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_7dd3d5
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_7dd3d5
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
index 67f427e..f1a92a5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7e5cbc() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
index 67f427e..f1a92a5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7e5cbc() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.msl
index fe26df9..af65274 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_7e5cbc(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.msl
index a66b8ee..23364cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_7e5cbc(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.spvasm
index 9f67265..75a642a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7e5cbc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,30 +40,33 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_7e5cbc = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-         %16 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %16
-         %19 = OpLoad %v4float %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+         %20 = OpVectorShuffle %v4float %19 %19 2 1 0 3
+               OpStore %res %20
+         %23 = OpLoad %v4float %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4float %textureLoad_7e5cbc
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4float %textureLoad_7e5cbc
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_7e5cbc
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_7e5cbc
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.glsl
index eb36095..368766d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_7fd822() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_4, int(v_3)).x;
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_7fd822() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_4, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_7fd822() {
-  ivec2 v = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v, int(1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
index e723a8d..4434b3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_7fd822() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(int3(v, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_3, int(v_1))).x;
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7fd822();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
index e723a8d..4434b3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_7fd822() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(int3(v, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_3, int(v_1))).x;
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7fd822();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.msl
index 80f01c3..f99cccd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_7fd822(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.msl
index 19c2a47..aa7fb92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float textureLoad_7fd822(depth2d<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.spvasm
index 204bbf3..eab14a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/7fd822.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,65 +56,72 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7fd822 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-         %25 = OpCompositeExtract %float %18 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v2uint %17 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %26 UMin %30 %29
+         %32 = OpImageFetch %v4float %17 %31 Lod %25
+         %33 = OpCompositeExtract %float %32 0
+               OpStore %res %33
+         %36 = OpLoad %float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_7fd822
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %float %textureLoad_7fd822
+         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_7fd822
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %float %textureLoad_7fd822
+         %48 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_7fd822
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %60 = OpFunctionCall %float %textureLoad_7fd822
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
index 39c54df..cea7214 100644
--- a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_80dae1() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
index 39c54df..cea7214 100644
--- a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_80dae1() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.msl
index ec5ac61..6491ae0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_80dae1(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.msl
index 36689ce..54d2aa5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_80dae1(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1u));
+  int4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.spvasm
index a096905..86c38c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/80dae1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_80dae1 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4int %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4int %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4int %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4int %textureLoad_80dae1
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4int %textureLoad_80dae1
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_80dae1
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_80dae1
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.glsl
index ccaef92..da29927 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_81c381() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_81c381() {
-  ivec2 v_1 = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(1), v_4), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_81c381() {
-  ivec2 v = ivec2(ivec2(1, 0));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(1), v_3), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
index c395289..1db44dd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_81c381() {
-  int v = int(int(1));
-  float4 res = float4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_81c381();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
index c395289..1db44dd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_81c381() {
-  int v = int(int(1));
-  float4 res = float4(arg_0.Load(int2(v, int(int(1)))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint v_1 = min(uint(int(1)), (v.y - 1u));
+  uint2 v_2 = (0u).xx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y);
+  uint v_3 = (v_2.x - 1u);
+  int v_4 = int(min(uint(int(1)), v_3));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_81c381();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.msl
index 0b975ac..d220bcd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_81c381(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.msl
index 145308e..8321749 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_81c381(texture1d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.spvasm
index 405f69c..cd3f34b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/81c381.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,62 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_81c381 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %int_1 Lod %int_1
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %uint %17 %25
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %26 UMin %29 %28
+         %31 = OpImageFetch %v4float %17 %30 Lod %25
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_81c381
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_81c381
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_81c381
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_81c381
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
-         %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_81c381
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_81c381
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.glsl
index 286e5a7..aba4706 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_83162f() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_83162f() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_83162f() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
index 592f425..534d94c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_83162f() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83162f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
index 592f425..534d94c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_83162f() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83162f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.msl
index db69f86..b61cfa7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_83162f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.msl
index f3d3e02..36fa686 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_83162f(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.spvasm
index d7cec83..5b3abc5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/83162f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,59 +60,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_83162f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_83162f
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_83162f
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_83162f
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_83162f
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_83162f
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_83162f
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.glsl
index 585421e..e72cd97 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_83cea4() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_83cea4() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_83cea4() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
index b31ae33..64fb47b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_83cea4() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83cea4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
index b31ae33..64fb47b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_83cea4() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83cea4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.msl
index 5434ba1..b1120ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_83cea4(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.msl
index 7444234..ef6830d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_83cea4(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.spvasm
index a78dca39..6a80e92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/83cea4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_83cea4 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %int_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4uint %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageRead %v4uint %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_83cea4
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4uint %textureLoad_83cea4
          %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_83cea4
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4uint %textureLoad_83cea4
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_83cea4
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.glsl
index 0330ecf..8b17c74 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_83d6e3() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_83d6e3() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
index 60828e7..52ebf18 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_83d6e3() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
index 60828e7..52ebf18 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_83d6e3() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.msl
index 8f49775..809ca7e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_83d6e3(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.msl
index 2ade633..99a9448 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_83d6e3(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.spvasm
index 2a365cf..719ea0f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/83d6e3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_83d6e3 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4uint %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpImageRead %v4uint %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4uint %textureLoad_83d6e3
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4uint %textureLoad_83d6e3
          %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_83d6e3
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
index c9b1465..4ce39a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_848d85() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
index c9b1465..4ce39a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_848d85() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.msl
index 702a673..d87393f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_848d85(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.msl
index 815bb78..3b750be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_848d85(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.spvasm
index 5eeba06..66d13de 100644
--- a/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/848d85.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_848d85 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_848d85
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_848d85
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_848d85
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_848d85
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
index be74ecc..c9e6a7e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_84a438() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
index be74ecc..c9e6a7e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_84a438() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.msl
index b9e9c34..e943e83 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_84a438(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.msl
index 8c397e5..47222c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_84a438(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.spvasm
index c414ec5..fe8ebdf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/84a438.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_84a438 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpBitcast %v2uint %19
+         %23 = OpExtInst %v2uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_84a438
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_84a438
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_84a438
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_84a438
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.glsl
index 96fc682..6f6ae1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_84c728() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_84c728() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_84c728() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
index 7b4d339..ee988f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84c728() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84c728();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
index 7b4d339..ee988f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84c728() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84c728();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.msl
index f447264..0b1667d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_84c728(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.msl
index 7e6ef58..42791f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_84c728(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.spvasm
index 6a597e9..80bba48 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/84c728.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,56 +61,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_84c728 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_84c728
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_84c728
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_84c728
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_84c728
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_84c728
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_84c728
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.glsl
index e8598b4..0040fc0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_84dee1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_84dee1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_84dee1() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
index 7b53386..886bb7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84dee1() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84dee1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
index 7b53386..886bb7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84dee1() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84dee1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.msl
index 8da8e06..785e8d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_84dee1(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.msl
index c1167f0..14f5b15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_84dee1(texture2d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.spvasm
index e51346d..5894fc3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/84dee1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,61 +56,67 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_84dee1 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v2uint %17 %22
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %23 UMin %27 %26
+         %29 = OpImageFetch %v4float %17 %28 Lod %22
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_84dee1
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_84dee1
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_84dee1
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_84dee1
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_84dee1
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_84dee1
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.glsl
index 5932c26..ad112e0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.glsl
@@ -2,15 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_8527b1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_8527b1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_8527b1() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u))));
+  ivec3 v_4 = ivec3(v_3, int(v_1));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
index b7c6359..a1eeb28 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_8527b1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8527b1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
index b7c6359..a1eeb28 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_8527b1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8527b1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.msl
index 27aa68f..5c2087d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_8527b1(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.msl
index 68ae4f3..2b569b2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_8527b1(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.spvasm
index edd8457..6cce136 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8527b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,63 +59,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8527b1 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageFetch %v4uint %20 %22 Lod %uint_1
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQueryLevels %uint %20
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpExtInst %uint %28 UMin %uint_1 %30
+         %32 = OpImageQuerySizeLod %v3uint %20 %31
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpExtInst %v2uint %28 UMin %36 %35
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageFetch %v4uint %20 %38 Lod %31
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_8527b1
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_8527b1
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_8527b1
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %45
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_8527b1
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_8527b1
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_8527b1
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.glsl
index 0419c3d..190f7bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_862833() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_862833() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_862833() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
index 8fd8288..5b9b315 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_862833() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_862833();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
index 8fd8288..5b9b315 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_862833() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_862833();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.msl
index fc2657e..0f9f313 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_862833(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.msl
index e68c6bd..cd194c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_862833(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.spvasm
index e94e6ea..a741137 100644
--- a/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/862833.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_862833 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_862833
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_862833
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_862833
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_862833
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_862833
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_862833
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
index d720714..eeace6d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_878e24() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
index d720714..eeace6d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_878e24() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.msl
index 2fb4a39..71d912e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_878e24(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.msl
index 1315e0e..a249209 100644
--- a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_878e24(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.spvasm
index e3fe0a7..3b7b2c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/878e24.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_878e24 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_878e24
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_878e24
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_878e24
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_878e24
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.glsl
index f3e2012..f9fd8b3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.glsl
@@ -2,15 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_87be85() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  vec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 void main() {
@@ -18,15 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_87be85() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  vec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_87be85() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  vec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
index 6e182ab..df7df3e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_87be85() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_87be85();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
index 6e182ab..df7df3e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_87be85() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_3))));
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_87be85();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.msl
index 16e5a12..09da330 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.ir.msl
@@ -17,7 +17,10 @@
 };
 
 float4 textureLoad_87be85(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_2), v, v_1);
   return res;
 }
 
@@ -40,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.msl
index d93bda2..f7e7891 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_87be85(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.spvasm
index 5fa00ad..de6113d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/87be85.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,82 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %40 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %65 = OpConstantNull %VertexOutput
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_87be85 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %int_1
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %29 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v3uint %17 %33
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpBitcast %v2uint %40
+         %42 = OpExtInst %v2uint %29 UMin %39 %37
+         %43 = OpCompositeConstruct %v3uint %42 %28
+         %44 = OpImageFetch %v4float %17 %43 Lod %33
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_87be85
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_87be85
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
          %52 = OpFunctionCall %v4float %textureLoad_87be85
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%compute_main = OpFunction %void None %50
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4float %textureLoad_87be85
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %58 %57 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %69 = OpFunctionCall %v4float %textureLoad_87be85
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %50
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4float %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
index 668aae8..e57244f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_87f0a6() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
index 668aae8..e57244f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_87f0a6() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.msl
index 2d54185..f548382 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 uint4 textureLoad_87f0a6(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.msl
index 6001acd..9a3402d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_87f0a6(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.spvasm
index ad59727..65632bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/87f0a6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_87f0a6 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4uint %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4uint %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_87f0a6
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_87f0a6
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_87f0a6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_87f0a6
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.glsl
index cdf794f..0729e1c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_881349() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_881349() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
index e0630b9..fe77cb3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_881349() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
index e0630b9..fe77cb3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_881349() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.msl
index 85e57ef..ab3b1cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_881349(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.msl
index 0d606d0..31c6dec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_881349(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.spvasm
index acadaba..dd180db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/881349.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_881349 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_881349
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_881349
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_881349
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_881349
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.glsl
index 6972768..6500b1d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_89620b() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1))).zyxw;
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2))).zyxw;
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_89620b() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1))).zyxw;
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_89620b() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1))).zyxw;
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
index f5d0d68..a7f1399 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_89620b() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_89620b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
index f5d0d68..a7f1399 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_89620b() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_89620b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.msl
index a4032a6..f062995 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_89620b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.msl
index 8e86d50..71446b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_89620b(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.spvasm
index cbfb1cd..1206e995 100644
--- a/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/89620b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,79 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %62 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_89620b = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-         %25 = OpVectorShuffle %v4float %24 %24 2 1 0 3
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+         %40 = OpVectorShuffle %v4float %39 %39 2 1 0 3
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_89620b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_89620b
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_89620b
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_89620b
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_89620b
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %66 = OpFunctionCall %v4float %textureLoad_89620b
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %46
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.glsl
index 70efc88..57b6517 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_897cf3() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_897cf3() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_897cf3() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
index 280dc18..804c0dd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_897cf3() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_897cf3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
index 280dc18..804c0dd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_897cf3() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_897cf3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.msl
index a48b5d3..076ffc6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_897cf3(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.msl
index 71369db..642a986 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_897cf3(texture2d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.spvasm
index a3f52a6..f7e0470 100644
--- a/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/897cf3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,68 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_897cf3 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %uint_1
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+         %28 = OpISub %v2uint %26 %29
+         %30 = OpExtInst %v2uint %25 UMin %29 %28
+         %31 = OpImageFetch %v4uint %20 %30 Lod %24
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_897cf3
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_897cf3
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_897cf3
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_897cf3
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_897cf3
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_897cf3
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.glsl
index 48da83c..8fa5a0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_8a291b() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u))).zyxw;
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1))).zyxw;
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_8a291b() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u))).zyxw;
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_8a291b() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u))).zyxw;
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
index 676c46e..e23cf57 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8a291b() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a291b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
index 676c46e..e23cf57 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8a291b() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a291b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.msl
index ec2785f..cb405bf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_8a291b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.msl
index ad4f5f6..4fb5f09 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_8a291b(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.spvasm
index 53c44cc..24e4a96 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8a291b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,68 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8a291b = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-         %28 = OpVectorShuffle %v4float %27 %27 2 1 0 3
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+         %39 = OpVectorShuffle %v4float %38 %38 2 1 0 3
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_8a291b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_8a291b
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_8a291b
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_8a291b
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_8a291b
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_8a291b
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.glsl
index 3660eb2..4886945 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_8a9988() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_8a9988() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_8a9988() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
index 5223ec7..c2931ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8a9988() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a9988();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
index 5223ec7..c2931ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8a9988() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a9988();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.msl
index a68eea7..79f225a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_8a9988(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.msl
index 6fcb3ef..cdbc756 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_8a9988(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.spvasm
index 14a479c..d9805a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8a9988.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,60 +63,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8a9988 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpExtInst %v3uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_8a9988
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_8a9988
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_8a9988
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_8a9988
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_8a9988
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_8a9988
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.glsl
index a6ad95e..a28c474 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.glsl
@@ -106,7 +106,7 @@
 }
 vec4 textureLoad_8acf41() {
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, uvec2(ivec2(1)));
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(ivec2(1)), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 void main() {
@@ -218,7 +218,7 @@
 }
 vec4 textureLoad_8acf41() {
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, uvec2(ivec2(1)));
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(ivec2(1)), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -333,7 +333,7 @@
 }
 vec4 textureLoad_8acf41() {
   tint_ExternalTextureParams v_16 = tint_convert_tint_ExternalTextureParams(v_1.inner);
-  vec4 res = tint_TextureLoadExternal(v_16, uvec2(ivec2(1)));
+  vec4 res = tint_TextureLoadExternal(v_16, min(uvec2(ivec2(1)), ((v_16.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
index 2a86317..f18cb88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
@@ -60,78 +60,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_8acf41() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, uint2((int(1)).xx));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, uint2((int(1)).xx));
   return res;
 }
 
@@ -148,13 +161,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8acf41();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
index 2a86317..f18cb88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
@@ -60,78 +60,91 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_8acf41() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, uint2((int(1)).xx));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, uint2((int(1)).xx));
   return res;
 }
 
@@ -148,13 +161,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8acf41();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.msl
index d01f25f..07f19d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.ir.msl
@@ -125,7 +125,7 @@
 
 float4 textureLoad_8acf41(tint_module_vars_struct tint_module_vars) {
   tint_ExternalTextureParams const v_19 = tint_load_struct_packed_vec3(tint_module_vars.arg_0_params);
-  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, uint2(int2(1)));
+  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, min(uint2(int2(1)), ((v_19.apparentSize + uint2(1u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.msl
index 68648cc..e030412 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.msl
@@ -93,6 +93,10 @@
   return select(uint2(4294967295u), select(uint2(v), uint2(0u), (v < float2(0.0f))), (v <= float2(4294967040.0f)));
 }
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float3 gammaCorrection(float3 v, GammaTransferParams params) {
   bool3 const cond = (fabs(v) < float3(params.D));
   float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F));
@@ -119,7 +123,7 @@
 }
 
 float4 textureLoad_8acf41(texture2d<float, access::sample> tint_symbol_1, texture2d<float, access::sample> tint_symbol_2, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_3) {
-  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, int2(1), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
+  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, tint_clamp(int2(1), int2(0), int2((((*(tint_symbol_3)).apparentSize + uint2(1u)) - uint2(1u)))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.spvasm
index cec327f..e8ff34e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8acf41.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 185
+; Bound: 190
 ; Schema: 0
                OpCapability Shader
-         %85 = OpExtInstImport "GLSL.std.450"
+         %50 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -187,26 +187,27 @@
 %mat3v3float = OpTypeMatrix %v3float 3
 %mat3v2float = OpTypeMatrix %v2float 3
 %tint_ExternalTextureParams = OpTypeStruct %uint %uint %mat3v4float %tint_GammaTransferParams %tint_GammaTransferParams %mat3v3float %mat3v2float %mat3v2float %v2float %v2float %v2float %v2float %v2uint %v2float
+     %uint_1 = OpConstant %uint 1
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %40 = OpConstantComposite %v2int %int_1 %int_1
+         %45 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %51 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %62 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %66 = OpConstantNull %VertexOutput
-         %68 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
-         %77 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
+         %73 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %v4float
+         %83 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
        %bool = OpTypeBool
-        %126 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+        %131 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %159 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %164 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
 %textureLoad_8acf41 = OpFunction %v4float None %26
          %27 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
@@ -215,160 +216,164 @@
          %30 = OpAccessChain %_ptr_Uniform_tint_ExternalTextureParams_std140 %10 %uint_0
          %33 = OpLoad %tint_ExternalTextureParams_std140 %30 None
          %34 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %33
-         %39 = OpBitcast %v2uint %40
-         %44 = OpFunctionCall %v4float %tint_TextureLoadExternal %28 %29 %34 %39
-               OpStore %res %44
-         %48 = OpLoad %v4float %res None
-               OpReturnValue %48
+         %39 = OpCompositeExtract %v2uint %34 12
+         %40 = OpIAdd %v2uint %39 %41
+         %43 = OpISub %v2uint %40 %41
+         %44 = OpBitcast %v2uint %45
+         %49 = OpExtInst %v2uint %50 UMin %44 %43
+         %51 = OpFunctionCall %v4float %tint_TextureLoadExternal %28 %29 %34 %49
+               OpStore %res %51
+         %55 = OpLoad %v4float %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %51
-         %52 = OpLabel
-         %53 = OpFunctionCall %v4float %textureLoad_8acf41
-         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %54 %53 None
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4float %textureLoad_8acf41
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %51
-         %57 = OpLabel
-         %58 = OpFunctionCall %v4float %textureLoad_8acf41
-         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %59 %58 None
+%compute_main = OpFunction %void None %58
+         %64 = OpLabel
+         %65 = OpFunctionCall %v4float %textureLoad_8acf41
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %66 %65 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %62
-         %63 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %66
-         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %67 %68 None
-         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %71 = OpFunctionCall %v4float %textureLoad_8acf41
-               OpStore %69 %71 None
-         %72 = OpLoad %VertexOutput %out None
-               OpReturnValue %72
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %77 = OpFunctionCall %v4float %textureLoad_8acf41
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %77
+%tint_TextureLoadExternal = OpFunction %v4float None %83
     %plane_0 = OpFunctionParameter %8
     %plane_1 = OpFunctionParameter %8
      %params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2uint
-         %78 = OpLabel
-         %79 = OpCompositeExtract %uint %params 1
-         %80 = OpCompositeExtract %mat3v4float %params 2
-         %81 = OpCompositeExtract %mat3v2float %params 7
-         %82 = OpCompositeExtract %v2uint %params 12
-         %83 = OpCompositeExtract %v2float %params 13
-         %84 = OpExtInst %v2uint %85 UMin %coords %82
-         %86 = OpConvertUToF %v2float %84
-         %87 = OpCompositeConstruct %v3float %86 %float_1
-         %89 = OpMatrixTimesVector %v2float %81 %87
-         %90 = OpExtInst %v2float %85 RoundEven %89
-         %91 = OpConvertFToU %v2uint %90
-         %92 = OpCompositeExtract %uint %params 0
-         %93 = OpIEqual %bool %92 %uint_1
-               OpSelectionMerge %95 None
-               OpBranchConditional %93 %96 %97
-         %96 = OpLabel
-         %98 = OpImageFetch %v4float %plane_0 %91 Lod %uint_0
-         %99 = OpVectorShuffle %v3float %98 %98 0 1 2
-        %100 = OpCompositeExtract %float %98 3
-               OpBranch %95
-         %97 = OpLabel
-        %101 = OpImageFetch %v4float %plane_0 %91 Lod %uint_0
-        %102 = OpCompositeExtract %float %101 0
-        %103 = OpFMul %v2float %90 %83
-        %104 = OpConvertFToU %v2uint %103
-        %105 = OpImageFetch %v4float %plane_1 %104 Lod %uint_0
-        %106 = OpVectorShuffle %v2float %105 %105 0 1
-        %107 = OpCompositeConstruct %v4float %102 %106 %float_1
-        %108 = OpVectorTimesMatrix %v3float %107 %80
-               OpBranch %95
-         %95 = OpLabel
-        %109 = OpPhi %v3float %99 %96 %108 %97
-        %110 = OpPhi %float %100 %96 %float_1 %97
-        %111 = OpIEqual %bool %79 %uint_0
-               OpSelectionMerge %112 None
-               OpBranchConditional %111 %113 %114
-        %113 = OpLabel
-        %115 = OpCompositeExtract %tint_GammaTransferParams %params 3
-        %116 = OpCompositeExtract %tint_GammaTransferParams %params 4
-        %117 = OpCompositeExtract %mat3v3float %params 5
-        %118 = OpFunctionCall %v3float %tint_GammaCorrection %109 %115
-        %120 = OpMatrixTimesVector %v3float %117 %118
-        %121 = OpFunctionCall %v3float %tint_GammaCorrection %120 %116
-               OpBranch %112
-        %114 = OpLabel
-               OpBranch %112
-        %112 = OpLabel
-        %122 = OpPhi %v3float %121 %113 %109 %114
-        %123 = OpCompositeConstruct %v4float %122 %110
-               OpReturnValue %123
+         %84 = OpLabel
+         %85 = OpCompositeExtract %uint %params 1
+         %86 = OpCompositeExtract %mat3v4float %params 2
+         %87 = OpCompositeExtract %mat3v2float %params 7
+         %88 = OpCompositeExtract %v2uint %params 12
+         %89 = OpCompositeExtract %v2float %params 13
+         %90 = OpExtInst %v2uint %50 UMin %coords %88
+         %91 = OpConvertUToF %v2float %90
+         %92 = OpCompositeConstruct %v3float %91 %float_1
+         %94 = OpMatrixTimesVector %v2float %87 %92
+         %95 = OpExtInst %v2float %50 RoundEven %94
+         %96 = OpConvertFToU %v2uint %95
+         %97 = OpCompositeExtract %uint %params 0
+         %98 = OpIEqual %bool %97 %uint_1
+               OpSelectionMerge %100 None
+               OpBranchConditional %98 %101 %102
+        %101 = OpLabel
+        %103 = OpImageFetch %v4float %plane_0 %96 Lod %uint_0
+        %104 = OpVectorShuffle %v3float %103 %103 0 1 2
+        %105 = OpCompositeExtract %float %103 3
+               OpBranch %100
+        %102 = OpLabel
+        %106 = OpImageFetch %v4float %plane_0 %96 Lod %uint_0
+        %107 = OpCompositeExtract %float %106 0
+        %108 = OpFMul %v2float %95 %89
+        %109 = OpConvertFToU %v2uint %108
+        %110 = OpImageFetch %v4float %plane_1 %109 Lod %uint_0
+        %111 = OpVectorShuffle %v2float %110 %110 0 1
+        %112 = OpCompositeConstruct %v4float %107 %111 %float_1
+        %113 = OpVectorTimesMatrix %v3float %112 %86
+               OpBranch %100
+        %100 = OpLabel
+        %114 = OpPhi %v3float %104 %101 %113 %102
+        %115 = OpPhi %float %105 %101 %float_1 %102
+        %116 = OpIEqual %bool %85 %uint_0
+               OpSelectionMerge %117 None
+               OpBranchConditional %116 %118 %119
+        %118 = OpLabel
+        %120 = OpCompositeExtract %tint_GammaTransferParams %params 3
+        %121 = OpCompositeExtract %tint_GammaTransferParams %params 4
+        %122 = OpCompositeExtract %mat3v3float %params 5
+        %123 = OpFunctionCall %v3float %tint_GammaCorrection %114 %120
+        %125 = OpMatrixTimesVector %v3float %122 %123
+        %126 = OpFunctionCall %v3float %tint_GammaCorrection %125 %121
+               OpBranch %117
+        %119 = OpLabel
+               OpBranch %117
+        %117 = OpLabel
+        %127 = OpPhi %v3float %126 %118 %114 %119
+        %128 = OpCompositeConstruct %v4float %127 %115
+               OpReturnValue %128
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %126
+%tint_GammaCorrection = OpFunction %v3float None %131
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-        %127 = OpLabel
-        %128 = OpCompositeExtract %float %params_0 0
-        %129 = OpCompositeExtract %float %params_0 1
-        %130 = OpCompositeExtract %float %params_0 2
-        %131 = OpCompositeExtract %float %params_0 3
-        %132 = OpCompositeExtract %float %params_0 4
-        %133 = OpCompositeExtract %float %params_0 5
-        %134 = OpCompositeExtract %float %params_0 6
-        %135 = OpCompositeConstruct %v3float %128 %128 %128
-        %136 = OpCompositeConstruct %v3float %132 %132 %132
-        %137 = OpExtInst %v3float %85 FAbs %v
-        %138 = OpExtInst %v3float %85 FSign %v
-        %139 = OpFOrdLessThan %v3bool %137 %136
-        %141 = OpVectorTimesScalar %v3float %137 %131
-        %142 = OpCompositeConstruct %v3float %134 %134 %134
-        %143 = OpFAdd %v3float %141 %142
-        %144 = OpFMul %v3float %138 %143
-        %145 = OpVectorTimesScalar %v3float %137 %129
-        %146 = OpCompositeConstruct %v3float %130 %130 %130
-        %147 = OpFAdd %v3float %145 %146
-        %148 = OpExtInst %v3float %85 Pow %147 %135
-        %149 = OpCompositeConstruct %v3float %133 %133 %133
-        %150 = OpFAdd %v3float %148 %149
-        %151 = OpFMul %v3float %138 %150
-        %152 = OpSelect %v3float %139 %144 %151
-               OpReturnValue %152
+        %132 = OpLabel
+        %133 = OpCompositeExtract %float %params_0 0
+        %134 = OpCompositeExtract %float %params_0 1
+        %135 = OpCompositeExtract %float %params_0 2
+        %136 = OpCompositeExtract %float %params_0 3
+        %137 = OpCompositeExtract %float %params_0 4
+        %138 = OpCompositeExtract %float %params_0 5
+        %139 = OpCompositeExtract %float %params_0 6
+        %140 = OpCompositeConstruct %v3float %133 %133 %133
+        %141 = OpCompositeConstruct %v3float %137 %137 %137
+        %142 = OpExtInst %v3float %50 FAbs %v
+        %143 = OpExtInst %v3float %50 FSign %v
+        %144 = OpFOrdLessThan %v3bool %142 %141
+        %146 = OpVectorTimesScalar %v3float %142 %136
+        %147 = OpCompositeConstruct %v3float %139 %139 %139
+        %148 = OpFAdd %v3float %146 %147
+        %149 = OpFMul %v3float %143 %148
+        %150 = OpVectorTimesScalar %v3float %142 %134
+        %151 = OpCompositeConstruct %v3float %135 %135 %135
+        %152 = OpFAdd %v3float %150 %151
+        %153 = OpExtInst %v3float %50 Pow %152 %140
+        %154 = OpCompositeConstruct %v3float %138 %138 %138
+        %155 = OpFAdd %v3float %153 %154
+        %156 = OpFMul %v3float %143 %155
+        %157 = OpSelect %v3float %144 %149 %156
+               OpReturnValue %157
                OpFunctionEnd
-%vertex_main = OpFunction %void None %51
-        %154 = OpLabel
-        %155 = OpFunctionCall %VertexOutput %vertex_main_inner
-        %156 = OpCompositeExtract %v4float %155 0
-               OpStore %vertex_main_position_Output %156 None
-        %157 = OpCompositeExtract %v4float %155 1
-               OpStore %vertex_main_loc0_Output %157 None
+%vertex_main = OpFunction %void None %58
+        %159 = OpLabel
+        %160 = OpFunctionCall %VertexOutput %vertex_main_inner
+        %161 = OpCompositeExtract %v4float %160 0
+               OpStore %vertex_main_position_Output %161 None
+        %162 = OpCompositeExtract %v4float %160 1
+               OpStore %vertex_main_loc0_Output %162 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %159
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %164
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %160 = OpLabel
-        %161 = OpCompositeExtract %uint %tint_input 0
-        %162 = OpCompositeExtract %uint %tint_input 1
-        %163 = OpCompositeExtract %mat3v4float %tint_input 2
-        %164 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %165 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %166 = OpCompositeExtract %v3float %tint_input 5
-        %167 = OpCompositeExtract %v3float %tint_input 6
-        %168 = OpCompositeExtract %v3float %tint_input 7
-        %169 = OpCompositeConstruct %mat3v3float %166 %167 %168
-        %170 = OpCompositeExtract %v2float %tint_input 8
-        %171 = OpCompositeExtract %v2float %tint_input 9
-        %172 = OpCompositeExtract %v2float %tint_input 10
-        %173 = OpCompositeConstruct %mat3v2float %170 %171 %172
-        %174 = OpCompositeExtract %v2float %tint_input 11
-        %175 = OpCompositeExtract %v2float %tint_input 12
-        %176 = OpCompositeExtract %v2float %tint_input 13
-        %177 = OpCompositeConstruct %mat3v2float %174 %175 %176
-        %178 = OpCompositeExtract %v2float %tint_input 14
-        %179 = OpCompositeExtract %v2float %tint_input 15
-        %180 = OpCompositeExtract %v2float %tint_input 16
-        %181 = OpCompositeExtract %v2float %tint_input 17
-        %182 = OpCompositeExtract %v2uint %tint_input 18
-        %183 = OpCompositeExtract %v2float %tint_input 19
-        %184 = OpCompositeConstruct %tint_ExternalTextureParams %161 %162 %163 %164 %165 %169 %173 %177 %178 %179 %180 %181 %182 %183
-               OpReturnValue %184
+        %165 = OpLabel
+        %166 = OpCompositeExtract %uint %tint_input 0
+        %167 = OpCompositeExtract %uint %tint_input 1
+        %168 = OpCompositeExtract %mat3v4float %tint_input 2
+        %169 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %170 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %171 = OpCompositeExtract %v3float %tint_input 5
+        %172 = OpCompositeExtract %v3float %tint_input 6
+        %173 = OpCompositeExtract %v3float %tint_input 7
+        %174 = OpCompositeConstruct %mat3v3float %171 %172 %173
+        %175 = OpCompositeExtract %v2float %tint_input 8
+        %176 = OpCompositeExtract %v2float %tint_input 9
+        %177 = OpCompositeExtract %v2float %tint_input 10
+        %178 = OpCompositeConstruct %mat3v2float %175 %176 %177
+        %179 = OpCompositeExtract %v2float %tint_input 11
+        %180 = OpCompositeExtract %v2float %tint_input 12
+        %181 = OpCompositeExtract %v2float %tint_input 13
+        %182 = OpCompositeConstruct %mat3v2float %179 %180 %181
+        %183 = OpCompositeExtract %v2float %tint_input 14
+        %184 = OpCompositeExtract %v2float %tint_input 15
+        %185 = OpCompositeExtract %v2float %tint_input 16
+        %186 = OpCompositeExtract %v2float %tint_input 17
+        %187 = OpCompositeExtract %v2uint %tint_input 18
+        %188 = OpCompositeExtract %v2float %tint_input 19
+        %189 = OpCompositeConstruct %tint_ExternalTextureParams %166 %167 %168 %169 %170 %174 %178 %182 %183 %184 %185 %186 %187 %188
+               OpReturnValue %189
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
index 9759328..81bfa58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8b62fb() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
index 9759328..81bfa58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8b62fb() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.msl
index 3195b61..4bd4ce9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_8b62fb(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.msl
index c2d3ff7..6ce0d1c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_8b62fb(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.spvasm
index e673055..9841de7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8b62fb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,33 +38,36 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_8b62fb = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-         %18 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+         %22 = OpVectorShuffle %v4float %21 %21 2 1 0 3
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_8b62fb
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_8b62fb
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_8b62fb
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_8b62fb
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.glsl
index c9d827a..c3061b3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_8bf8c2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_8bf8c2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
index dfcdb0d..ec6152f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8bf8c2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
index dfcdb0d..ec6152f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8bf8c2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.msl
index 7536a43..f5082e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_8bf8c2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.msl
index 69c62d2..7006860 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_8bf8c2(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.spvasm
index f33474c..3717ea3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8bf8c2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_8bf8c2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_8bf8c2
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_8bf8c2
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_8bf8c2
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_8bf8c2
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.glsl
index 32f9799..7fb67f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8c6176() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8c6176() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
index d1e972b..55d855e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8c6176() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
index d1e972b..55d855e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8c6176() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.msl
index c5db531..24de91d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_8c6176(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.msl
index cda045c..01025ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_8c6176(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.spvasm
index b1e3041..0ebff67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8c6176.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
          %10 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_8c6176 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpExtInst %v2uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_8c6176
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_8c6176
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_8c6176
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_8c6176
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.glsl
index 7c3f109..075d646 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_8ccbe3() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_8ccbe3() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_8ccbe3() {
-  ivec2 v = ivec2(ivec2(1));
-  float res = texelFetch(arg_0, v, int(1u)).x;
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  float res = texelFetch(arg_0, v_3, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
index 97d3cf4..dddb39a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_8ccbe3() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(int3(v, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float res = arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))).x;
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ccbe3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
index 97d3cf4..dddb39a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_8ccbe3() {
-  int2 v = int2((int(1)).xx);
-  float res = arg_0.Load(int3(v, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float res = arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))).x;
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ccbe3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.msl
index 68affe5..3e8b374 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_8ccbe3(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.msl
index e5f1ba1..cb85c83 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_8ccbe3(depth2d<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.spvasm
index 264e8ee..4599563 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8ccbe3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,66 +55,75 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %43 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8ccbe3 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-         %25 = OpCompositeExtract %float %18 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v2uint %17 %22
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %33 = OpExtInst %v2uint %23 UMin %28 %26
+         %34 = OpImageFetch %v4float %17 %33 Lod %22
+         %35 = OpCompositeExtract %float %34 0
+               OpStore %res %35
+         %38 = OpLoad %float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_8ccbe3
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %float %textureLoad_8ccbe3
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_8ccbe3
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %float %textureLoad_8ccbe3
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_8ccbe3
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %62 = OpFunctionCall %float %textureLoad_8ccbe3
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.glsl
index 23a2ca5..bb5fb24 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8d64c3() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8d64c3() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
index 1e4f71a..664d4e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8d64c3() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
index 1e4f71a..664d4e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8d64c3() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.msl
index 166d044..844aa58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_8d64c3(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.msl
index e1ae120..d4e823f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_8d64c3(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.spvasm
index 701021c..32c78b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8d64c3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_8d64c3 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpBitcast %v2uint %19
+         %23 = OpExtInst %v2uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_8d64c3
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_8d64c3
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_8d64c3
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_8d64c3
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.glsl
index 8501d61..0cdebe9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_8db0ce() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_8db0ce() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_8db0ce() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
index 672ad18..14d6b93b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8db0ce() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8db0ce();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
index 672ad18..14d6b93b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8db0ce() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8db0ce();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.msl
index b28f999..35aeca83 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_8db0ce(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.msl
index 757494f..0c1ba82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_8db0ce(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.spvasm
index 89cd566..51f8a13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8db0ce.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +61,71 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8db0ce = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageRead %v4int %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4int %20 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_8db0ce
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_8db0ce
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_8db0ce
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_8db0ce
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_8db0ce
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_8db0ce
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.glsl
index e08f5d1..7aeafae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_8e5032() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_8e5032() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_8e5032() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
index 39a95b6..2a15b1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_8e5032() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8e5032();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
index 39a95b6..2a15b1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_8e5032() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8e5032();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.msl
index bddad29..4d15704 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_8e5032(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.msl
index 8f1ddd2..ecde775 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_8e5032(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.spvasm
index 0e8bb55..1596e58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8e5032.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8e5032 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageRead %v4uint %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4uint %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_8e5032
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_8e5032
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_8e5032
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_8e5032
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_8e5032
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
index 2c6bddc..fe704ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_8e68c9() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
index 2c6bddc..fe704ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_8e68c9() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.msl
index 87a1d9c..0842435 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_8e68c9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.msl
index a1d0365..d360c4b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_8e68c9(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(uint3(1u)));
+  int4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.spvasm
index 2983810..b6d9ba6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8e68c9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_8e68c9 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_8e68c9
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_8e68c9
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_8e68c9
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_8e68c9
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
index 4e3da74..dcdf7cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8fc29b() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
index 4e3da74..dcdf7cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8fc29b() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.msl
index 4591023..dedac0a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_8fc29b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.msl
index e259089..d8a0875 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_8fc29b(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.spvasm
index 866f763..37a651c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8fc29b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,34 +36,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_8fc29b = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_8fc29b
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_8fc29b
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_8fc29b
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.glsl
index 179674b..d7e4c1b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_8ff033() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_8ff033() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_8ff033() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
index f6f49db..db70d9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8ff033() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ff033();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
index f6f49db..db70d9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8ff033() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ff033();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.msl
index 9e6c069..1b4239b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_8ff033(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.msl
index 48558ca..cc7bd64 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_8ff033(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.spvasm
index 6069f5d..ef51d0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/8ff033.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8ff033 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_8ff033
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_8ff033
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_8ff033
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_8ff033
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_8ff033
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_8ff033
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.glsl
index 69c792b..6f0015c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_91ede5() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_91ede5() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
index 5d3e7b7..413a202 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_91ede5() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
index 5d3e7b7..413a202 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_91ede5() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.msl
index a7a744e..2428f49 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_91ede5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.msl
index 2fa2ca4..1e8b9d2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_91ede5(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.spvasm
index 4155a77..a0e78c0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/91ede5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_91ede5 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_91ede5
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_91ede5
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_91ede5
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_91ede5
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
index b6fcadc..69c8ea5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9242e7() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
index b6fcadc..69c8ea5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9242e7() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.msl
index 340f73b..6794bbe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_9242e7(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.msl
index 9851843..b7b34f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_9242e7(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.spvasm
index d73fdb4..ce7a3ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9242e7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9242e7 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpExtInst %v2uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_9242e7
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_9242e7
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_9242e7
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_9242e7
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.glsl
index 1249f51..faa1b49 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_92dd61() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_92dd61() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
index 9c4cf30..6e53dbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_92dd61() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
index 9c4cf30..6e53dbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_92dd61() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.msl
index e8804a5..17740c3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_92dd61(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.msl
index c69e747..56b5aae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_92dd61(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.spvasm
index aa7d0bc..cfa3710 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/92dd61.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,29 +41,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_92dd61 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_92dd61
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_92dd61
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_92dd61
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_92dd61
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.glsl
index 13506de..9f06efb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_92eb1f() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_92eb1f() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_92eb1f() {
-  ivec3 v = ivec3(uvec3(1u));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
index 5b0ec6f..9a7ab92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_92eb1f() {
-  int3 v = int3((1u).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_92eb1f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
index 5b0ec6f..9a7ab92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_92eb1f() {
-  int3 v = int3((1u).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_92eb1f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.msl
index b100e12..d2c71ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_92eb1f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.msl
index fae211a..60d21d1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_92eb1f(texture3d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.spvasm
index a29582f..01d45bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/92eb1f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,71 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
+         %32 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_92eb1f = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpISub %v3uint %29 %32
+         %33 = OpExtInst %v3uint %28 UMin %32 %31
+         %34 = OpImageFetch %v4uint %20 %33 Lod %27
+               OpStore %res %34
+         %37 = OpLoad %v4uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_92eb1f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_92eb1f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_92eb1f
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_92eb1f
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_92eb1f
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %61 = OpFunctionCall %v4uint %textureLoad_92eb1f
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.glsl
index 29a574a..ac5444e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_936952() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_936952() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_936952() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
index 11df67a..cbdec1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_936952() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_936952();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
index 11df67a..cbdec1f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_936952() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_936952();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.msl
index dbb7a89..cf842fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_936952(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.msl
index c998494..3bfc032 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_936952(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.spvasm
index 9a86446..0cfd118 100644
--- a/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/936952.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_936952 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_936952
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_936952
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_936952
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_936952
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_936952
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_936952
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.glsl
index 1437041..6963efb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_93f23e() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_93f23e() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
index c797401..632ff9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_93f23e() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
index c797401..632ff9c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_93f23e() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.msl
index ff4508c..9371f1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_93f23e(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.msl
index 5d09965..1aedc4c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_93f23e(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.spvasm
index e977318..3bfa660 100644
--- a/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/93f23e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_93f23e = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpExtInst %v2uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_93f23e
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_93f23e
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_93f23e
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_93f23e
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.glsl
index 40f705b..6eb28b3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_947107() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_947107() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_947107() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
index 757e956..d131fab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_947107() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_947107();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
index 757e956..d131fab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_947107() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_947107();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.msl
index 3d1cdc9..3f8537f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_947107(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.msl
index cb4b3f4..23d4054 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_947107(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.spvasm
index 534155b..a1b9bce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/947107.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_947107 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_947107
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_947107
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_947107
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_947107
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_947107
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.glsl
index 4d94b92..251797b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.glsl
@@ -2,15 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_96efd5() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_96efd5() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_96efd5() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u))));
+  ivec3 v_4 = ivec3(v_3, int(v_1));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
index cbe509d..ee52827 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_96efd5() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_96efd5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
index cbe509d..ee52827 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_96efd5() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_96efd5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.msl
index 10a9d96..125e9ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_96efd5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.msl
index 9810600..659d722 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_96efd5(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.spvasm
index 5479206..de26d85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/96efd5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,73 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_96efd5 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %uint_1
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %26 UMin %uint_1 %28
+         %30 = OpImageQuerySizeLod %v3uint %17 %29
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpExtInst %v2uint %26 UMin %34 %33
+         %36 = OpCompositeConstruct %v3uint %35 %25
+         %37 = OpImageFetch %v4float %17 %36 Lod %29
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_96efd5
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_96efd5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_96efd5
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%compute_main = OpFunction %void None %43
+         %49 = OpLabel
          %50 = OpFunctionCall %v4float %textureLoad_96efd5
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_96efd5
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %43
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.glsl
index fba99b8..43777a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_970308() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_970308() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_970308() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
index 26932fe..dec79f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_970308() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_970308();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
index 26932fe..dec79f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_970308() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_970308();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.msl
index 1361a1d..2b17f2b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_970308(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.msl
index c1c920f..fdf8ea1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_970308(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.spvasm
index 4a671c9..50559df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/970308.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_970308 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %38 = OpExtInst %v2uint %27 UMin %33 %31
+         %39 = OpCompositeConstruct %v3uint %38 %26
+         %40 = OpImageRead %v4uint %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_970308
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_970308
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_970308
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_970308
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_970308
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_970308
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.glsl
index 1ffba03..cbb2cb7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.glsl
@@ -2,15 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9885b0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9885b0() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9885b0() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u))));
+  ivec3 v_4 = ivec3(v_3, int(v_1));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
index d9d3590..903f44a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9885b0() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9885b0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
index d9d3590..903f44a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,15 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9885b0() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int v_4 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_3, v_4, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9885b0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.msl
index be99925..235fdb2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_9885b0(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.msl
index f433d90..6b55dce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_9885b0(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.spvasm
index eef1e51..00bdf94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9885b0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +60,74 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9885b0 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageFetch %v4int %20 %23 Lod %uint_1
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpExtInst %uint %29 UMin %uint_1 %26
+         %30 = OpImageQueryLevels %uint %20
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %20 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpExtInst %v2uint %29 UMin %37 %36
+         %39 = OpCompositeConstruct %v3uint %38 %28
+         %40 = OpImageFetch %v4int %20 %39 Lod %32
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_9885b0
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_9885b0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_9885b0
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %46
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_9885b0
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_9885b0
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %66 = OpFunctionCall %v4int %textureLoad_9885b0
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %46
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4int %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.glsl
index 12a523e..6aaaa6b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_99d8fa() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_99d8fa() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
index 68ddb04..21e16db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_99d8fa() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
index 68ddb04..21e16db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_99d8fa() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.msl
index b56040d..2d90c2a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_99d8fa(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.msl
index aea7573..a537ede 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_99d8fa(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.spvasm
index f7814fd..abf158e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/99d8fa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,36 +36,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_99d8fa = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_99d8fa
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_99d8fa
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_99d8fa
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_99d8fa
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.glsl
index 8e6f9aa..817a0dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_9a7c90() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_9a7c90() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_9a7c90() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
index 65c5e86..01579b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9a7c90() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a7c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
index 65c5e86..01579b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9a7c90() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a7c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.msl
index 7467edf..ce2f89f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_9a7c90(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.msl
index 05d8f05..cfaf5f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9a7c90(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.spvasm
index f22d054..36b1b78 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9a7c90.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9a7c90 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpBitcast %v3uint %27
+         %31 = OpExtInst %v3uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_9a7c90
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_9a7c90
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_9a7c90
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_9a7c90
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_9a7c90
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_9a7c90
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.glsl
index 65bf970..ca66889 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_9a8c1e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_9a8c1e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9a8c1e() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
index 2400428..d3993e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9a8c1e() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a8c1e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
index 2400428..d3993e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9a8c1e() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a8c1e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.msl
index 3107738..9cc8ded 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_9a8c1e(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.msl
index 3e75b02..cfdbf7c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9a8c1e(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.spvasm
index 2885fb0..3e3fd55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9a8c1e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9a8c1e = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %22
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4int %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_9a8c1e
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_9a8c1e
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9a8c1e
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_9a8c1e
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_9a8c1e
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_9a8c1e
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.glsl
index 5a02973..bf72eb9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_9aa733() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_9aa733() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9aa733() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
index b9fd81b..31150ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9aa733() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9aa733();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
index b9fd81b..31150ad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9aa733() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9aa733();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.msl
index da12e6f..6e7e339 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_9aa733(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.msl
index d46baa5..d2cbbe3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 int4 textureLoad_9aa733(texture2d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.spvasm
index 181cc72..5688729 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9aa733.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,63 +59,70 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9aa733 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %28 UMin %32 %31
+         %34 = OpImageFetch %v4int %20 %33 Lod %27
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_9aa733
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_9aa733
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_9aa733
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_9aa733
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_9aa733
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %61 = OpFunctionCall %v4int %textureLoad_9aa733
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4int %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.glsl
index f32bcd0..6e26e3d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.glsl
@@ -2,15 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_9b2667() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  float res = texelFetch(arg_0, v_8, int(v_5)).x;
   return res;
 }
 void main() {
@@ -18,15 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_9b2667() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(ivec2(1)), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_3));
+  float res = texelFetch(arg_0, v_8, int(v_5)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_9b2667() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  float res = texelFetch(arg_0, v_7, int(v_4)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
index addfd3a..21b047e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_9b2667() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_3))).x;
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b2667();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
index addfd3a..21b047e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,18 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_9b2667() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  uint2 v_5 = (v_4.xy - (1u).xx);
+  int2 v_6 = int2(min(uint2((int(1)).xx), v_5));
+  int v_7 = int(v_1);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_3))).x;
   return res;
 }
 
@@ -31,13 +40,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b2667();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.msl
index d246479..b02c388 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.ir.msl
@@ -17,7 +17,10 @@
 };
 
 float textureLoad_9b2667(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_2), v, v_1);
   return res;
 }
 
@@ -40,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.msl
index 8f3f310..8d8cf58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_9b2667(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.spvasm
index 2e65139..fd9c533 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9b2667.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,68 +55,84 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %40 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %44 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9b2667 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %int_1
-         %25 = OpCompositeExtract %float %24 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %29 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v3uint %17 %33
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpBitcast %v2uint %40
+         %42 = OpExtInst %v2uint %29 UMin %39 %37
+         %43 = OpCompositeConstruct %v3uint %42 %28
+         %44 = OpImageFetch %v4float %17 %43 Lod %33
+         %45 = OpCompositeExtract %float %44 0
+               OpStore %res %45
+         %48 = OpLoad %float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_9b2667
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %float %textureLoad_9b2667
+         %54 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %float %textureLoad_9b2667
-         %41 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %41 %40 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %54 = OpFunctionCall %float %textureLoad_9b2667
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %31
+%compute_main = OpFunction %void None %51
          %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+         %58 = OpFunctionCall %float %textureLoad_9b2667
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %59 %58 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %71 = OpFunctionCall %float %textureLoad_9b2667
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.glsl
index 33c7ad9..66186d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_9b5343() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_9b5343() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_9b5343() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
index 16c7dbd..e3745f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9b5343() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b5343();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
index 16c7dbd..e3745f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9b5343() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b5343();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.msl
index 49ea09a..c4d6bac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_9b5343(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.msl
index f122b88..71e1731 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9b5343(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.spvasm
index ec03f4e..e790b0d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9b5343.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,75 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9b5343 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4uint %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_9b5343
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_9b5343
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_9b5343
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_9b5343
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_9b5343
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_9b5343
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.glsl
index 036f0cd..6ae4c58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_9c2376() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_9c2376() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_9c2376() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
index a027482..87288e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2376() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2376();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
index a027482..87288e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2376() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2376();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.msl
index 824eb54..fa4a36a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_9c2376(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.msl
index ef350a9..384063a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9c2376(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.spvasm
index 99df8e0..4fba456 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2376.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9c2376 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_9c2376
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_9c2376
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_9c2376
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_9c2376
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_9c2376
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_9c2376
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.glsl
index efe654b..46c99d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_9c2a14() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_9c2a14() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_9c2a14() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
index d433def..df226ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2a14() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2a14();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
index d433def..df226ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2a14() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2a14();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.msl
index 270ae53..69443eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_9c2a14(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.msl
index a6b95cb..a143d1a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9c2a14(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.spvasm
index 5bf41ed..190b273 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9c2a14.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9c2a14 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_9c2a14
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_9c2a14
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_9c2a14
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_9c2a14
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_9c2a14
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_9c2a14
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.glsl
index a833620..8e5a387 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_9cf7df() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_9cf7df() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9cf7df() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
index d0c6d4b..4f18472 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9cf7df() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9cf7df();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
index d0c6d4b..4f18472 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9cf7df() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9cf7df();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.msl
index 0d6d74c..cf6c0d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_9cf7df(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.msl
index 42bdf87..788b6f4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9cf7df(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.spvasm
index 27d3263..1ebc882 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9cf7df.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,66 +61,76 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9cf7df = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %38 = OpExtInst %v2uint %28 UMin %34 %32
+         %39 = OpCompositeConstruct %v3uint %38 %27
+         %40 = OpImageRead %v4int %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_9cf7df
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_9cf7df
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9cf7df
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_9cf7df
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_9cf7df
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_9cf7df
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.glsl
index 1237250..7ac2944 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9d70e9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9d70e9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9d70e9() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
index 9c47674..c175acc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9d70e9() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9d70e9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
index 9c47674..c175acc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9d70e9() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9d70e9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.msl
index 2fb8f83..6da5d2c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_9d70e9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.msl
index f8a4dcd..a91dccf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9d70e9(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.spvasm
index e7eeb60..79e4640 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9d70e9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,66 +58,81 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
-      %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %41 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9d70e9 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageFetch %v4int %20 %22 Lod %uint_1
-               OpStore %res %26
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %28 %26
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %31 UMin %uint_1 %33
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %41
+         %43 = OpExtInst %v2uint %31 UMin %40 %38
+         %44 = OpCompositeConstruct %v3uint %43 %30
+         %45 = OpImageFetch %v4int %20 %44 Lod %34
+               OpStore %res %45
+         %48 = OpLoad %v4int %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_9d70e9
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_9d70e9
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_9d70e9
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %51
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_9d70e9
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_9d70e9
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_9d70e9
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.glsl
index 052e4a7..2c767ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_9de6f5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_9de6f5() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_9de6f5() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
index 6bae045..7097af4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9de6f5() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9de6f5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
index 6bae045..7097af4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9de6f5() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9de6f5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.msl
index 8c1bb07..82e676d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_9de6f5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.msl
index 1d1c622..a37153a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9de6f5(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.spvasm
index a4c135d..884d011 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9de6f5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9de6f5 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_9de6f5
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_9de6f5
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_9de6f5
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_9de6f5
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_9de6f5
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_9de6f5
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.glsl
index 4c241c6..04e1623 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_9ed19e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_9ed19e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_9ed19e() {
-  ivec2 v = ivec2(uvec2(1u));
-  float res = texelFetch(arg_0, v, int(1u)).x;
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_2, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
index 51dd464..10d3e85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_9ed19e() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(int3(v, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))).x;
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9ed19e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
index 51dd464..10d3e85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D arg_0 : register(t0, space1);
 float textureLoad_9ed19e() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(int3(v, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_2, int(min(1u, (v.z - 1u))))).x;
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9ed19e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.msl
index aadcde8..955f13d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float textureLoad_9ed19e(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.msl
index 067b14f..9afd8a7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float textureLoad_9ed19e(depth2d<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.spvasm
index 49aca3d..ac26287 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9ed19e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,63 +56,69 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %41 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9ed19e = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %uint_1
-         %23 = OpCompositeExtract %float %18 0
-               OpStore %res %23
-         %26 = OpLoad %float %res None
-               OpReturnValue %26
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageQuerySizeLod %v2uint %17 %22
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %23 UMin %27 %26
+         %29 = OpImageFetch %v4float %17 %28 Lod %22
+         %30 = OpCompositeExtract %float %29 0
+               OpStore %res %30
+         %33 = OpLoad %float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %float %textureLoad_9ed19e
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %float %textureLoad_9ed19e
+         %39 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_9ed19e
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %float %textureLoad_9ed19e
+         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %50 = OpFunctionCall %float %textureLoad_9ed19e
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %57 = OpFunctionCall %float %textureLoad_9ed19e
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
index b2aca00..0c045d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fa9fd() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
index b2aca00..0c045d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fa9fd() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.msl
index 81a7f7f..2cc822a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_9fa9fd(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.msl
index b50c6e6..7bb0950 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_9fa9fd(texture3d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.spvasm
index f7e0c09..6a630e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9fa9fd.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9fa9fd = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpISub %v3uint %13 %16
+         %18 = OpExtInst %v3uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_9fa9fd
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_9fa9fd
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_9fa9fd
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_9fa9fd
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.glsl
index ebc5fc5..2ffb733 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9fbfd9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9fbfd9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9fbfd9() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2)).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
index a09e27c..53b4428 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9fbfd9() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9fbfd9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
index a09e27c..53b4428 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_9fbfd9() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_1.w - 1u))), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_1.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9fbfd9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.msl
index 56c1c77..b001baa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_9fbfd9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.msl
index b649a8e..c18aee3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9fbfd9(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.spvasm
index 78ab231..5aaef8ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9fbfd9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,79 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %39 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9fbfd9 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageFetch %v4int %20 %25 Lod %uint_1
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpExtInst %uint %29 UMin %uint_1 %26
+         %30 = OpImageQueryLevels %uint %20
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %20 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %39
+         %42 = OpExtInst %v2uint %29 UMin %38 %36
+         %43 = OpCompositeConstruct %v3uint %42 %28
+         %44 = OpImageFetch %v4int %20 %43 Lod %32
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_9fbfd9
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_9fbfd9
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9fbfd9
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %50
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4int %textureLoad_9fbfd9
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_9fbfd9
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %70 = OpFunctionCall %v4int %textureLoad_9fbfd9
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4int %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
index 8ac7fa1..47c0e43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fd7be() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
index 8ac7fa1..47c0e43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fd7be() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.msl
index 447c7ca..fd18bd5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 uint4 textureLoad_9fd7be(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.msl
index ce7f641..b797384 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9fd7be(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.spvasm
index b20e4b5..3693842 100644
--- a/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/9fd7be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9fd7be = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4uint %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4uint %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_9fd7be
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_9fd7be
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_9fd7be
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_9fd7be
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.glsl
index a1199bd..cfa28b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_a03af1() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_a03af1() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a03af1() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
index 3f0b605..fd7cbb9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a03af1() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a03af1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
index 3f0b605..fd7cbb9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a03af1() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a03af1();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.msl
index 3a1b596..0220055 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_a03af1(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.msl
index b9bdf97..f9009b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a03af1(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.spvasm
index 1130518..4f0c052 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a03af1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,67 +56,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a03af1 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %36 = OpExtInst %v2uint %25 UMin %31 %29
+         %37 = OpCompositeConstruct %v3uint %36 %24
+         %38 = OpImageRead %v4float %17 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_a03af1
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_a03af1
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_a03af1
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_a03af1
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_a03af1
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_a03af1
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.glsl
index 911d6b0..2d89c84 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_a24be1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_a24be1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  uvec4 res = texelFetch(arg_0, v_2, int(1u));
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_3));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_a24be1() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_2));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
index 57578ac..e8d05cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a24be1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a24be1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
index 57578ac..e8d05cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a24be1() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  uint4 res = uint4(arg_0.Load(int4(v, v_1, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(v_1);
+  uint4 res = uint4(arg_0.Load(int4(v_4, v_5, int(min(1u, (v_2.w - 1u))))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a24be1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.msl
index f52528b..37bfc08 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_a24be1(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.msl
index 49c6cc0..183ce02 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a24be1(texture2d_array<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.spvasm
index 4ea81aa..dccde22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a24be1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,67 +58,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a24be1 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageFetch %v4uint %20 %25 Lod %uint_1
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %30 = OpExtInst %uint %31 UMin %27 %25
+         %32 = OpImageQueryLevels %uint %20
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %31 UMin %uint_1 %33
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpExtInst %v2uint %31 UMin %39 %38
+         %41 = OpCompositeConstruct %v3uint %40 %30
+         %42 = OpImageFetch %v4uint %20 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4uint %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_a24be1
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_a24be1
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_a24be1
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_a24be1
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_a24be1
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_a24be1
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
index baf9dee..b91a720 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a2b3f4() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
index baf9dee..b91a720 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a2b3f4() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.msl
index b84e679..6ba48b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_a2b3f4(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.msl
index 2179243..a5b3e5b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_a2b3f4(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.spvasm
index 9c14c9b..b8d37e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a2b3f4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,43 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %15 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a2b3f4 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3uint %15 %uint_1
-         %18 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpExtInst %v2uint %19 UMin %24 %23
+         %26 = OpCompositeConstruct %v3uint %25 %18
+         %27 = OpImageRead %v4uint %12 %26 None
+               OpStore %res %27
+         %30 = OpLoad %v4uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_a2b3f4
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_a2b3f4
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_a2b3f4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_a2b3f4
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
index 63c7822..d70fe43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3733f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
index 63c7822..d70fe43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3733f() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.msl
index 8dd7dc3..d28346d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_a3733f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.msl
index 37a9224..e07b8cf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a3733f(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.spvasm
index 2ac01ac..2bf1732 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a3733f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %19 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a3733f = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpBitcast %v2uint %19
+         %23 = OpExtInst %v2uint %24 UMin %18 %15
+         %25 = OpImageRead %v4uint %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4uint %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_a3733f
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4uint %textureLoad_a3733f
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_a3733f
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_a3733f
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
index 4f02bdb..98cc686 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3f122() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
index 4f02bdb..98cc686 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3f122() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.msl
index 49fe300..0209705 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_a3f122(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.msl
index 730a26c..43a8e4d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_a3f122(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.spvasm
index 70c3891..fce84ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a3f122.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,43 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %15 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a3f122 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3uint %15 %uint_1
-         %18 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpExtInst %v2uint %19 UMin %24 %23
+         %26 = OpCompositeConstruct %v3uint %25 %18
+         %27 = OpImageRead %v4uint %12 %26 None
+               OpStore %res %27
+         %30 = OpLoad %v4uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_a3f122
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_a3f122
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_a3f122
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_a3f122
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
index d5d2109..e2f02bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a548a8() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
index d5d2109..e2f02bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a548a8() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.msl
index 2cbecbc..c5daa24 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_a548a8(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.msl
index 47f7aa7..defc5b5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a548a8(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.spvasm
index fe8a669..2e10d0e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a548a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a548a8 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4uint %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpImageRead %v4uint %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4uint %textureLoad_a548a8
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4uint %textureLoad_a548a8
          %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_a548a8
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
index 62e142c..a613257 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a54e11() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
index 62e142c..a613257 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a54e11() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.msl
index 46af265..564ac66 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_a54e11(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.msl
index 87d1c993..f1f011d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a54e11(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.spvasm
index 626e91d..52bd83e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a54e11.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_a54e11 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %13
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %30 = OpExtInst %v2uint %20 UMin %26 %24
+         %31 = OpCompositeConstruct %v3uint %30 %19
+         %32 = OpImageRead %v4int %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_a54e11
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_a54e11
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_a54e11
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_a54e11
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.glsl
index f1d1dec..bd67d3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_a583c9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_a583c9() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a583c9() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  vec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
index bfeb752..bc92f5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a583c9() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float4 res = float4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a583c9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
index bfeb752..bc92f5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a583c9() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float4 res = float4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a583c9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.msl
index 144fbb7..805a95a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_a583c9(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.msl
index 2562267..89f4a0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a583c9(texture2d_ms<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.spvasm
index 98cbab1..68a5a4a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a583c9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a583c9 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %int_1
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageFetch %v4float %17 %29 Sample %int_1
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_a583c9
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_a583c9
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_a583c9
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_a583c9
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_a583c9
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_a583c9
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.glsl
index 6c9f05c..91f50a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_a5c4e2() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_a5c4e2() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
index 4f87565..2553b6d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a5c4e2() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
index 4f87565..2553b6d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a5c4e2() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.msl
index d1f0023..4406bb7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_a5c4e2(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.msl
index 5c89c07..5a7f1ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a5c4e2(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.spvasm
index 83aeeec..bb354ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a5c4e2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,33 +37,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a5c4e2 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4uint %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpImageRead %v4uint %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4uint %textureLoad_a5c4e2
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4uint %textureLoad_a5c4e2
          %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_a5c4e2
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.glsl
index b6c3ac0..1c0f7d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_a5e0a5() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_a5e0a5() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
index 7245503..cb03df3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a5e0a5() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
index 7245503..cb03df3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a5e0a5() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.msl
index f795571..a104883 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_a5e0a5(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.msl
index 5a5b82f..7f9e59a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_a5e0a5(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.spvasm
index 5a4e0f9..5e3139e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a5e0a5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a5e0a5 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_a5e0a5
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_a5e0a5
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_a5e0a5
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_a5e0a5
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
index 49e2856..95b78cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a64b1d() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
index 49e2856..95b78cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a64b1d() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.msl
index e7c1725..b25e36e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_a64b1d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.msl
index 5e079bb..07a5ed4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_a64b1d(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(uint3(1u)));
+  float4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.spvasm
index 4542b8f..686ecee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a64b1d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a64b1d = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_a64b1d
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_a64b1d
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_a64b1d
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_a64b1d
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.glsl
index f4a9651..0d8b66b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a6a85a() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a6a85a() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a6a85a() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
index 7fdaf92..5bc47ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a6a85a() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6a85a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
index 7fdaf92..5bc47ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a6a85a() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6a85a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.msl
index 53a9b44..1ec3f3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_a6a85a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.msl
index 1a2e10d..dc24b40 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a6a85a(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.spvasm
index 09544cd..7411aa6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a6a85a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a6a85a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_a6a85a
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_a6a85a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_a6a85a
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_a6a85a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_a6a85a
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_a6a85a
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.glsl
index 0db772a..04f261b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_a6b61d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_a6b61d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_a6b61d() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
index 1dbcd96..27504f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a6b61d() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6b61d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
index 1dbcd96..27504f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a6b61d() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6b61d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.msl
index acb5e19..24629e7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_a6b61d(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.msl
index ee2c9df..d977721 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a6b61d(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.spvasm
index 030dc3e..000e538 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a6b61d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a6b61d = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageRead %v4int %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4int %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4int %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_a6b61d
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_a6b61d
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_a6b61d
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_a6b61d
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_a6b61d
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.glsl
index ae66958..947c6fa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_a7444c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_a7444c() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_a7444c() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
index 43821bb..a61770a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a7444c() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7444c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
index 43821bb..a61770a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a7444c() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7444c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.msl
index 246e973..4a69819 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_a7444c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.msl
index 3fb2b7f..0f8320a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_a7444c(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.spvasm
index 191fde3..6b9f431 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a7444c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,63 +60,71 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a7444c = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %27 UMin %32 %31
+         %34 = OpCompositeConstruct %v3uint %33 %26
+         %35 = OpImageRead %v4uint %20 %34 None
+               OpStore %res %35
+         %38 = OpLoad %v4uint %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_a7444c
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_a7444c
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_a7444c
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_a7444c
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_a7444c
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %62 = OpFunctionCall %v4uint %textureLoad_a7444c
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4uint %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.glsl
index 65ebf05..3757f5e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_a7a3c3() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_a7a3c3() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_a7a3c3() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
index bca11c0..e0450d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a7a3c3() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7a3c3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
index bca11c0..e0450d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a7a3c3() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7a3c3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.msl
index 5f583f5..928527b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_a7a3c3(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.msl
index e86230b..69b2b94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a7a3c3(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.spvasm
index 09e375f..0a64f45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a7a3c3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a7a3c3 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpBitcast %v3uint %28
+         %31 = OpExtInst %v3uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_a7a3c3
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_a7a3c3
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_a7a3c3
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_a7a3c3
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_a7a3c3
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_a7a3c3
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
index 3667007..83f2bdd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a7bcb4() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
index 3667007..83f2bdd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a7bcb4() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.msl
index db509d4..86a41ac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_a7bcb4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.msl
index 6951cfe..d3bebb1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_a7bcb4(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.spvasm
index c0b3d98..9714814 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a7bcb4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a7bcb4 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_a7bcb4
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_a7bcb4
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_a7bcb4
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_a7bcb4
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
index 35c2fe4..e379a81 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a7c171() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
index 35c2fe4..e379a81 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a7c171() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.msl
index 4984a59..89b5d98 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_a7c171(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.msl
index 8d6866d..0f8b5ea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_a7c171(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)));
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.spvasm
index cf2e6c4..250de25 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a7c171.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_a7c171 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_a7c171
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_a7c171
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_a7c171
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_a7c171
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.glsl
index ac236e4..96183ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a8549b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a8549b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a8549b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
index da47555..01aa2ac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a8549b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a8549b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
index da47555..01aa2ac 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a8549b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a8549b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.msl
index a06fcad..9da4fb0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_a8549b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.msl
index 484231c..c4f9d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_a8549b(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.spvasm
index 2ea1489..8a853a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a8549b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a8549b = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_a8549b
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_a8549b
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_a8549b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_a8549b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_a8549b
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_a8549b
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
index f7269b8..149e4cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a92b18() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
index f7269b8..149e4cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a92b18() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.msl
index aa7f6cb..5141ad3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_a92b18(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.msl
index 1fb0ccf..95045b3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a92b18(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.spvasm
index 4494a6b5..21f00fb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a92b18.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a92b18 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_a92b18
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_a92b18
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_a92b18
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_a92b18
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.glsl
index bffb815..a0b8a96 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_a9a9f5() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_a9a9f5() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(ivec3(1)), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_a9a9f5() {
-  ivec3 v = ivec3(ivec3(1));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
index 3163978..d52e32f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a9a9f5() {
-  int3 v = int3((int(1)).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a9a9f5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
index 3163978..d52e32f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_a9a9f5() {
-  int3 v = int3((int(1)).xxx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  uint3 v_3 = (v_2.xyz - (1u).xxx);
+  int3 v_4 = int3(min(uint3((int(1)).xxx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a9a9f5();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.msl
index ec614c3..b62eb35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_a9a9f5(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.msl
index e5d09fa..b9d9e12 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a9a9f5(texture3d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.spvasm
index e003456..252f43a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/a9a9f5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+         %32 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+      %v3int = OpTypeVector %int 3
+         %34 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a9a9f5 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %int_1
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v3uint %20 %27
+         %31 = OpISub %v3uint %29 %32
+         %33 = OpBitcast %v3uint %34
+         %36 = OpExtInst %v3uint %28 UMin %33 %31
+         %37 = OpImageFetch %v4uint %20 %36 Lod %27
+               OpStore %res %37
+         %40 = OpLoad %v4uint %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%fragment_main = OpFunction %void None %43
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %55
          %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %64 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4uint %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
index 01b3789..de7b00e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_aa2579() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
index 01b3789..de7b00e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_aa2579() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.msl
index 7e46fc0..522fb0a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_aa2579(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.msl
index 03dd847..47b76e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_aa2579(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.spvasm
index dc3cb13..ad903c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aa2579.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,47 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_aa2579 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %13
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4uint %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_aa2579
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_aa2579
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_aa2579
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_aa2579
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.glsl
index c3ee375..c8ee682 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_aa6130() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_aa6130() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
index 359fde1..e9c8996 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_aa6130() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
index 359fde1..e9c8996 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_aa6130() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.msl
index ee33959..1f38e62 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_aa6130(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.msl
index 85d5c5d..012ce3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_aa6130(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)));
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.spvasm
index f0de8f6..d804f59 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aa6130.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_aa6130 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %23 = OpExtInst %v2uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_aa6130
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_aa6130
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_aa6130
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_aa6130
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.glsl
index 830381c..bade265 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aa8a0d() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aa8a0d() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_aa8a0d() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
index 7276643..84bd7fc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aa8a0d() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aa8a0d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
index 7276643..84bd7fc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aa8a0d() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aa8a0d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.msl
index 8b2f0b8..8946bdf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_aa8a0d(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.msl
index 0c9f3f8..ca16635 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_aa8a0d(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.spvasm
index 4083747..8912e64 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aa8a0d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aa8a0d = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.glsl
index 44918e9..475dd67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_aae7f6() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_aae7f6() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_aae7f6() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
index a8d375e..1605cf9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_aae7f6() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aae7f6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
index a8d375e..1605cf9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_aae7f6() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aae7f6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.msl
index 35d2b88..42694cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_aae7f6(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.msl
index 38867d8..143d283 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_aae7f6(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.spvasm
index 45dca31..80798b2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aae7f6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,76 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aae7f6 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageRead %v4int %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %38 = OpExtInst %v2uint %28 UMin %34 %32
+         %39 = OpCompositeConstruct %v3uint %38 %27
+         %40 = OpImageRead %v4int %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_aae7f6
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_aae7f6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_aae7f6
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_aae7f6
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_aae7f6
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_aae7f6
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
index 0372d64..ef6b604 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_aae9c3() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
index 0372d64..ef6b604 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_aae9c3() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.msl
index e49c916..7e608aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_aae9c3(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.msl
index 3a1482e..cddef15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_aae9c3(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.spvasm
index 50a0722..b216fdc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aae9c3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,40 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_aae9c3 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_aae9c3
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_aae9c3
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_aae9c3
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_aae9c3
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.glsl
index 90b285b..42e68b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_ac64f7() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u))).zyxw;
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_ac64f7() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u))).zyxw;
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_ac64f7() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u))).zyxw;
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
index dedb6496..3ca7e62 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ac64f7() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ac64f7();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
index dedb6496..3ca7e62 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ac64f7() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ac64f7();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.msl
index 39d9690..a343334 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_ac64f7(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.msl
index 81c8c63..1d214db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_ac64f7(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.spvasm
index 0b21a94..f40e9ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ac64f7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,63 +58,71 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ac64f7 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-         %25 = OpVectorShuffle %v4float %24 %24 2 1 0 3
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+         %34 = OpVectorShuffle %v4float %33 %33 2 1 0 3
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_ac64f7
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_ac64f7
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_ac64f7
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_ac64f7
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_ac64f7
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_ac64f7
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
index 2205441..79ca8eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_acf22f() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
index 2205441..79ca8eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_acf22f() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.msl
index b16becc..e405b35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_acf22f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.msl
index e4977a3..925946e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_acf22f(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.spvasm
index d53d14b..73347bb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/acf22f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_acf22f = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_acf22f
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_acf22f
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_acf22f
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_acf22f
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.glsl
index b4f3c58..077acf7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_ad551e() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_ad551e() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
index 01dec26..2a6110b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_ad551e() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
index 01dec26..2a6110b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_ad551e() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.msl
index 7612a08..f6e767a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_ad551e(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.msl
index b57d7a7..2651847 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_ad551e(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1u));
+  uint4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.spvasm
index 7d63854..0e1fc82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ad551e.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,29 +39,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_ad551e = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %uint_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4uint %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpExtInst %uint %17 UMin %uint_1 %14
+         %18 = OpImageRead %v4uint %12 %16 None
+               OpStore %res %18
+         %21 = OpLoad %v4uint %res None
+               OpReturnValue %21
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4uint %textureLoad_ad551e
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %23 %22 None
+%fragment_main = OpFunction %void None %24
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4uint %textureLoad_ad551e
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %27 %26 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %20
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_ad551e
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%compute_main = OpFunction %void None %24
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4uint %textureLoad_ad551e
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.glsl
index 89e70c0..2037505 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_aeae73() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_aeae73() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_aeae73() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
index d340a2a..7d98c95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aeae73() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aeae73();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
index d340a2a..7d98c95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aeae73() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aeae73();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.msl
index f414988..3e77453 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_aeae73(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.msl
index a5afc2e..c14d290 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_aeae73(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.spvasm
index 75eefd8..3a9ebe1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aeae73.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,75 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aeae73 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4uint %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_aeae73
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_aeae73
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_aeae73
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_aeae73
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_aeae73
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_aeae73
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.glsl
index aa340d4..8fd1e10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aebc09() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aebc09() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_aebc09() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
index e6ac68e..819c209 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aebc09() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aebc09();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
index e6ac68e..819c209 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aebc09() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aebc09();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.msl
index fdc31d4..8501b86 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_aebc09(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.msl
index aca9d9f..52a84f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_aebc09(texture1d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.spvasm
index 9c3a4e4..0aae392 100644
--- a/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/aebc09.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,57 +63,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aebc09 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %uint_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageRead %v4uint %20 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4uint %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_aebc09
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_aebc09
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_aebc09
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_aebc09
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_aebc09
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %53 = OpFunctionCall %v4uint %textureLoad_aebc09
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %32
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4uint %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.glsl
index 39f77dc..40ea7f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_af0507() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_af0507() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
index d855e6a..f0e406c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_af0507() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
index d855e6a..f0e406c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_af0507() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.msl
index 5f634c4..9a142f4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_af0507(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.msl
index e037c51..95c50ce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_af0507(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.spvasm
index 990870e..4009b8f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/af0507.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,40 +36,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_af0507 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_af0507
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_af0507
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_af0507
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_af0507
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.glsl
index b9d49ee..471636f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_b1bf79() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_b1bf79() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b1bf79() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
index a6f0b97..20392e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b1bf79() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b1bf79();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
index a6f0b97..20392e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b1bf79() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b1bf79();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.msl
index 1b4c8e6..726c644 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_b1bf79(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.msl
index 87194a7..201d5db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b1bf79(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.spvasm
index cd76107..7edf496 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b1bf79.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b1bf79 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpBitcast %v3uint %28
+         %31 = OpExtInst %v3uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_b1bf79
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_b1bf79
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_b1bf79
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_b1bf79
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_b1bf79
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_b1bf79
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.glsl
index f176fc0..199a526 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_b1ca35() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_b1ca35() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
index 0caf047..cbd662d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b1ca35() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
index 0caf047..cbd662d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b1ca35() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.msl
index c801285..86ccab2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_b1ca35(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.msl
index ce73034..8f7fa40 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_b1ca35(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.spvasm
index 762cd96..4045210 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b1ca35.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,35 +38,43 @@
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_b1ca35 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4int %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4int %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_b1ca35
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_b1ca35
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_b1ca35
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_b1ca35
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.glsl
index 4a41edd..e831d17 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_b24d27() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_b24d27() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b24d27() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
index 2de1072..871e62a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b24d27() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b24d27();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
index 2de1072..871e62a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b24d27() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b24d27();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.msl
index c4d3a29..7105708 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_b24d27(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.msl
index 274f434..d09a079 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_b24d27(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.spvasm
index 01a6d37..9c4095f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b24d27.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b24d27 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_b24d27
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_b24d27
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_b24d27
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_b24d27
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_b24d27
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_b24d27
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.glsl
index 5fbe872..ae4d88a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_b25644() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_b25644() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
index ade782b..9663c10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b25644() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
index ade782b..9663c10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b25644() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.msl
index abfae8b..3d849f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_b25644(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.msl
index ccafc68..98f88cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b25644(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.spvasm
index fa3ccc6..f22f836 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b25644.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,49 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %26 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_b25644 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %14
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpBitcast %v2uint %26
+         %30 = OpExtInst %v2uint %19 UMin %25 %23
+         %31 = OpCompositeConstruct %v3uint %30 %18
+         %32 = OpImageRead %v4uint %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_b25644
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_b25644
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_b25644
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_b25644
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.glsl
index 16c62b1..152cc79 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_b27c33() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_b27c33() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
index ba1fcf4..543c5be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b27c33() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
index ba1fcf4..543c5be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b27c33() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.msl
index 37e3790..16ebc65 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_b27c33(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.msl
index eb9c071..fe4f6f2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b27c33(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(int3(1)));
+  int4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.spvasm
index 989686a..fa2b700 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b27c33.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_b27c33 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %23 = OpExtInst %v3uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_b27c33
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_b27c33
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_b27c33
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_b27c33
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.glsl
index f560e07..ac7ae7e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_b29f71() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_b29f71() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  ivec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b29f71() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_1));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
index 065c7de..c8bfe31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b29f71() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b29f71();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
index 065c7de..c8bfe31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b29f71() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  int4 res = int4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  int4 res = int4(arg_0.Load(int4(v_5, v_6, int(v_2))));
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b29f71();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.msl
index 589da46..b687ee4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_b29f71(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.msl
index 6624dde..c5200f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b29f71(texture2d_array<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.spvasm
index 2a4b7ad..1959ebf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b29f71.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,80 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %41 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %47 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b29f71 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %21
-         %29 = OpImageFetch %v4int %20 %25 Lod %int_1
-               OpStore %res %29
-         %32 = OpLoad %v4int %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySizeLod %v3uint %20 %uint_0
+         %25 = OpCompositeExtract %uint %21 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpExtInst %uint %29 UMin %uint_1 %26
+         %30 = OpImageQueryLevels %uint %20
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %34 = OpExtInst %uint %29 UMin %32 %31
+         %35 = OpImageQuerySizeLod %v3uint %20 %34
+         %36 = OpVectorShuffle %v2uint %35 %35 0 1
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %41
+         %43 = OpExtInst %v2uint %29 UMin %40 %38
+         %44 = OpCompositeConstruct %v3uint %43 %28
+         %45 = OpImageFetch %v4int %20 %44 Lod %34
+               OpStore %res %45
+         %48 = OpLoad %v4int %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_b29f71
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_b29f71
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_b29f71
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %51
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_b29f71
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_b29f71
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_b29f71
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.glsl
index d4d1f37..27688e0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_b4d6c4() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_b4d6c4() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
index 947f998..597c608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b4d6c4() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
index 947f998..597c608 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b4d6c4() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.msl
index a9830ad..20ab658 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_b4d6c4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.msl
index 9c583ab..8ce904b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_b4d6c4(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.spvasm
index 63fb975..7b24450 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b4d6c4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_b4d6c4 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_b4d6c4
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_b4d6c4
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_b4d6c4
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_b4d6c4
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.glsl
index f0033cd..3bf7942 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_b58c6d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_b58c6d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, r32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_b58c6d() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
index 21aed7b..ab53696 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b58c6d() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b58c6d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
index 21aed7b..ab53696 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b58c6d() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b58c6d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.msl
index d56a710..4ea40c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_b58c6d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.msl
index 2acce8b..7a2bb0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b58c6d(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.spvasm
index 2aa593a..44c0027 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b58c6d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b58c6d = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_b58c6d
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_b58c6d
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_b58c6d
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_b58c6d
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_b58c6d
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_b58c6d
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
index c51de25..fa0c4c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b60a86() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
index c51de25..fa0c4c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b60a86() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.msl
index bb8e6a5..31013b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_b60a86(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.msl
index e9d34d9..c8a5969 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b60a86(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.spvasm
index ef1d647..9aeb355 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b60a86.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_b60a86 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4uint %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpImageRead %v4uint %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4uint %textureLoad_b60a86
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4uint %textureLoad_b60a86
          %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_b60a86
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
index 985a69c..41029ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b60db7() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
index 985a69c..41029ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b60db7() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.msl
index 0160a74..322751b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_b60db7(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.msl
index c32b692..6dad4da 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_b60db7(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.spvasm
index ae8720d..d0e2d4a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b60db7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,36 +37,44 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_b60db7 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-         %20 = OpVectorShuffle %v4float %19 %19 2 1 0 3
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+         %29 = OpVectorShuffle %v4float %28 %28 2 1 0 3
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_b60db7
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_b60db7
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_b60db7
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_b60db7
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.glsl
index 46694d3..115906a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_b6ba5d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  float res = texelFetch(arg_0, v_7, int(v_5)).x;
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_b6ba5d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_5 = min(uint(1), v_4);
+  ivec2 v_6 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  float res = texelFetch(arg_0, v_7, int(v_5)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_b6ba5d() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
index 657c421..8235035 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_b6ba5d() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  float res = arg_0.Load(int4(v_5, v_6, int(v_3))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6ba5d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
index 657c421..8235035 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_b6ba5d() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint v_3 = min(uint(int(1)), (v_2.w - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_3), v_4.x, v_4.y, v_4.z, v_4.w);
+  int2 v_5 = int2(min((1u).xx, (v_4.xy - (1u).xx)));
+  int v_6 = int(v_1);
+  float res = arg_0.Load(int4(v_5, v_6, int(v_3))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6ba5d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.msl
index 70b075c..ff6cc3b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float textureLoad_b6ba5d(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_1 = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v, v_1);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.msl
index 55d602e..18fc42e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_b6ba5d(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.spvasm
index af3819e..b2d69af 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b6ba5d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,68 +56,80 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %46 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b6ba5d = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %int_1
-         %28 = OpCompositeExtract %float %27 0
-               OpStore %res %28
-         %31 = OpLoad %float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %29 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v3uint %17 %33
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpExtInst %v2uint %29 UMin %38 %37
+         %40 = OpCompositeConstruct %v3uint %39 %28
+         %41 = OpImageFetch %v4float %17 %40 Lod %33
+         %42 = OpCompositeExtract %float %41 0
+               OpStore %res %42
+         %45 = OpLoad %float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %float %textureLoad_b6ba5d
-         %37 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %float %textureLoad_b6ba5d
+         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %float %textureLoad_b6ba5d
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %43 %42 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_float %out %uint_1
+%compute_main = OpFunction %void None %48
+         %54 = OpLabel
          %55 = OpFunctionCall %float %textureLoad_b6ba5d
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %float %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %68 = OpFunctionCall %float %textureLoad_b6ba5d
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.glsl
index fd05491..ab4e4fe8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_b6c458() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_b6c458() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_b6c458() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
index 0bc5baf..fcd0880 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b6c458() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6c458();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
index 0bc5baf..fcd0880 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b6c458() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6c458();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.msl
index ad23f9a..b27896e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_b6c458(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.msl
index 2700792..93c3b75 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b6c458(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.spvasm
index 1624177..7512868 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b6c458.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b6c458 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_b6c458
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_b6c458
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_b6c458
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_b6c458
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_b6c458
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_b6c458
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.glsl
index dd540d5..912f063 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_b73f6b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_b73f6b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_b73f6b() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
index b1e28eb..79ef3c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b73f6b() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b73f6b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
index b1e28eb..79ef3c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b73f6b() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b73f6b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.msl
index 4b600d9..2bb09e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_b73f6b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.msl
index 2e4f1bc..2c21cf1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_b73f6b(texture2d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.spvasm
index 795ef98..b11166f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b73f6b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,71 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b73f6b = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %28 UMin %32 %31
+         %34 = OpImageFetch %v4uint %20 %33 Lod %27
+               OpStore %res %34
+         %37 = OpLoad %v4uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_b73f6b
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_b73f6b
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_b73f6b
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_b73f6b
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_b73f6b
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %61 = OpFunctionCall %v4uint %textureLoad_b73f6b
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.glsl
index a8090e6..199528d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_b75c8f() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_b75c8f() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
index a3cc3bc..8ab7e86 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b75c8f() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
index a3cc3bc..8ab7e86 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b75c8f() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.msl
index 16c20e9..2c31ac1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_b75c8f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.msl
index 791fb71..9c6f000 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_b75c8f(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)));
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.spvasm
index 51ced5a..bceec0e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b75c8f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_b75c8f = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_b75c8f
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_b75c8f
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_b75c8f
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_b75c8f
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.glsl
index 6abc9e3..3b56459 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_b75d4a() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_b75d4a() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  vec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_b75d4a() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = texelFetch(arg_0, v, int(1u));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  vec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
index 0e1049b..d182fa2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b75d4a() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float4 res = float4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b75d4a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
index 0e1049b..d182fa2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b75d4a() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  float4 res = float4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b75d4a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.msl
index 1a50a7e..6176d2c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_b75d4a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1u);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.msl
index d430a18..c10c6a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b75d4a(texture2d_ms<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.spvasm
index 4e37bcb..ac73808 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b75d4a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,64 +55,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b75d4a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %uint_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageFetch %v4float %17 %29 Sample %uint_1
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_b75d4a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_b75d4a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_b75d4a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_b75d4a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_b75d4a
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_b75d4a
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.glsl
index 093b1d6..2f194a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_b7f74f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_b7f74f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_b7f74f() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u))).zyxw;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
index 440a762..87b234c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b7f74f() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b7f74f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
index 440a762..87b234c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b7f74f() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b7f74f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.msl
index c922ac7..6d47972 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_b7f74f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.msl
index 583b7da..c83d1a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_b7f74f(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.spvasm
index 46034e5..06e909d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b7f74f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 55
+; Bound: 59
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,57 +61,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %43 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
+         %47 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b7f74f = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-         %21 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+         %25 = OpVectorShuffle %v4float %24 %24 2 1 0 3
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_b7f74f
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_b7f74f
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_b7f74f
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_b7f74f
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
-         %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %47 = OpFunctionCall %v4float %textureLoad_b7f74f
-               OpStore %46 %47 None
-         %48 = OpLoad %VertexOutput %out None
-               OpReturnValue %48
+%vertex_main_inner = OpFunction %VertexOutput None %43
+         %44 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %47
+         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %48 %49 None
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %51 = OpFunctionCall %v4float %textureLoad_b7f74f
+               OpStore %50 %51 None
+         %52 = OpLoad %VertexOutput %out None
+               OpReturnValue %52
                OpFunctionEnd
-%vertex_main = OpFunction %void None %27
-         %50 = OpLabel
-         %51 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %52 = OpCompositeExtract %v4float %51 0
-               OpStore %vertex_main_position_Output %52 None
-         %53 = OpCompositeExtract %v4float %51 1
-               OpStore %vertex_main_loc0_Output %53 None
+%vertex_main = OpFunction %void None %31
+         %54 = OpLabel
+         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %56 = OpCompositeExtract %v4float %55 0
+               OpStore %vertex_main_position_Output %56 None
+         %57 = OpCompositeExtract %v4float %55 1
+               OpStore %vertex_main_loc0_Output %57 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.glsl
index 3ec5cec..b263465 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_b80e7e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_b80e7e() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_b80e7e() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
index 8a31c39..5baed77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b80e7e() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b80e7e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
index 8a31c39..5baed77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b80e7e() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b80e7e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.msl
index f2bba63..cf5257c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_b80e7e(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.msl
index e48f37e..3598c55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b80e7e(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.spvasm
index 27c428f..0796245 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b80e7e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,74 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b80e7e = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_b80e7e
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_b80e7e
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_b80e7e
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_b80e7e
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_b80e7e
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_b80e7e
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.glsl
index 28571b6..c4db6e7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_b94d15() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_b94d15() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_b94d15() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
index c4a0cd0..fb6a167 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b94d15() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b94d15();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
index c4a0cd0..fb6a167 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b94d15() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b94d15();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.msl
index eb6d1d9..ef14304 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_b94d15(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.msl
index 613faf2..3ab9d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b94d15(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.spvasm
index 24d5718..00aa7a4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/b94d15.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b94d15 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %38 = OpExtInst %v2uint %27 UMin %33 %31
+         %39 = OpCompositeConstruct %v3uint %38 %26
+         %40 = OpImageRead %v4uint %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_b94d15
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_b94d15
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_b94d15
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_b94d15
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_b94d15
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_b94d15
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.glsl
index 2f26619..08a264d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_ba023a() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_ba023a() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
index c494fbc..c7df879 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ba023a() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
index c494fbc..c7df879 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ba023a() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.msl
index 0387482..5b58d91 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 int4 textureLoad_ba023a(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.msl
index ae15892..d10a60e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ba023a(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.spvasm
index 0dc405e..ba8310a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ba023a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %15 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_ba023a = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3int %15 %int_1
-         %18 = OpImageRead %v4int %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4int %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_ba023a
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_ba023a
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_ba023a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_ba023a
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
index 224d033..9eb9672 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ba74b2() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
index 224d033..9eb9672 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ba74b2() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.msl
index b7ce348..60764a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 int4 textureLoad_ba74b2(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.msl
index 159866e..743bc38 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ba74b2(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.spvasm
index 87c7d01..6935129 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ba74b2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %15 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_ba74b2 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3int %15 %int_1
-         %18 = OpImageRead %v4int %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4int %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_ba74b2
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_ba74b2
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_ba74b2
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_ba74b2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
index b7f7cdd..d13923f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_babdf3() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
index b7f7cdd..d13923f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_babdf3() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.msl
index dcb8fd3..c03bac8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_babdf3(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.msl
index 313f226..9e1dd13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_babdf3(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1u));
+  uint4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.spvasm
index 3478591..75abf1b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/babdf3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,29 +39,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_babdf3 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %uint_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4uint %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpExtInst %uint %17 UMin %uint_1 %14
+         %18 = OpImageRead %v4uint %12 %16 None
+               OpStore %res %18
+         %21 = OpLoad %v4uint %res None
+               OpReturnValue %21
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4uint %textureLoad_babdf3
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %23 %22 None
+%fragment_main = OpFunction %void None %24
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4uint %textureLoad_babdf3
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %27 %26 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %20
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_babdf3
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%compute_main = OpFunction %void None %24
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4uint %textureLoad_babdf3
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.glsl
index 27bb566..a8debf3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_bba04a() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_bba04a() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
index 5c724e9..064bbe4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bba04a() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
index 5c724e9..064bbe4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bba04a() {
-  uint4 res = uint4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.msl
index 4b9c080..52a2239 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_bba04a(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.msl
index c43c431..fb09f7b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_bba04a(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1u));
+  uint4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.spvasm
index f16bbe3..eedd822 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bba04a.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 30
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_bba04a = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %uint_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4uint %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpExtInst %uint %17 UMin %uint_1 %14
+         %18 = OpImageRead %v4uint %12 %16 None
+               OpStore %res %18
+         %21 = OpLoad %v4uint %res None
+               OpReturnValue %21
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4uint %textureLoad_bba04a
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %23 %22 None
+%fragment_main = OpFunction %void None %24
+         %25 = OpLabel
+         %26 = OpFunctionCall %v4uint %textureLoad_bba04a
+         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %27 %26 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %20
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_bba04a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%compute_main = OpFunction %void None %24
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4uint %textureLoad_bba04a
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
index 55ce2ae..c719b45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_bbb762() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
index 55ce2ae..c719b45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_bbb762() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.msl
index 8297fde..0375a7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_bbb762(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.msl
index 3e40657..54834cb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_bbb762(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)));
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.spvasm
index 3e36c05..76dff6d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bbb762.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_bbb762 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_bbb762
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_bbb762
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_bbb762
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_bbb762
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.glsl
index 1a62e8b..fe400bbd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_bc3201() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_bc3201() {
-  ivec2 v_1 = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_bc3201() {
-  ivec2 v = ivec2(uvec2(1u, 0u));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_2 = ivec2(uvec2(min(1u, (uvec2(textureSize(arg_0, int(v_1))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
index 585db2f..5b21071 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bc3201() {
-  int v = int(1u);
-  uint4 res = uint4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bc3201();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
index 585db2f..5b21071 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bc3201() {
-  int v = int(1u);
-  uint4 res = uint4(arg_0.Load(int2(v, int(1u))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(1u, (v.y - 1u))), v_1.x, v_1.y);
+  int v_2 = int(min(1u, (v_1.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_2, int(min(1u, (v.y - 1u))))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bc3201();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.msl
index 7c51495..6aba036 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_bc3201(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(1u);
+  min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.msl
index fd28f11..7b678dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 uint4 textureLoad_bc3201(texture1d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint(1u), 0);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.spvasm
index 88d1d1e..43025a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bc3201.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,57 +62,63 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %40 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %47 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bc3201 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %uint_1 Lod %uint_1
-               OpStore %res %21
-         %25 = OpLoad %v4uint %res None
-               OpReturnValue %25
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %uint %20 %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %25 UMin %uint_1 %27
+         %29 = OpImageFetch %v4uint %20 %28 Lod %24
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_bc3201
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_bc3201
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_bc3201
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_bc3201
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %49 = OpFunctionCall %v4uint %textureLoad_bc3201
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_bc3201
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4uint %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.glsl
index 7f3cd03..43e5a2f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_bc882d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_bc882d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
index 9bb5757..35b662a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_bc882d() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
index 9bb5757..35b662a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_bc882d() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.msl
index 9ed865d..2c9ea10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_bc882d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.msl
index 2b0198f..e5046a7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_bc882d(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.spvasm
index ae26c8e..ad6808c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bc882d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,39 +37,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_bc882d = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_bc882d
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_bc882d
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_bc882d
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_bc882d
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.glsl
index 54be270..0c2a103 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_bcbb3c() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_bcbb3c() {
-  ivec3 v_1 = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec3 v_4 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_bcbb3c() {
-  ivec3 v = ivec3(uvec3(1u));
-  vec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec3 v_3 = ivec3(min(uvec3(1u), (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
index 66e8cd4..7391855 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_bcbb3c() {
-  int3 v = int3((1u).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bcbb3c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
index 66e8cd4..7391855 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_bcbb3c() {
-  int3 v = int3((1u).xxx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint v_1 = min(uint(int(1)), (v.w - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z, v_2.w);
+  int3 v_3 = int3(min((1u).xxx, (v_2.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bcbb3c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.msl
index 6264e16..bbbf519 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_bcbb3c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v)) - uint3(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.msl
index 4eec4e1..14fd2b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_bcbb3c(texture3d<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.spvasm
index f50a180..ee48b59 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bcbb3c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,63 +56,70 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
+         %30 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bcbb3c = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Lod %int_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQueryLevels %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageQuerySizeLod %v3uint %17 %25
+         %29 = OpISub %v3uint %27 %30
+         %31 = OpExtInst %v3uint %26 UMin %30 %29
+         %32 = OpImageFetch %v4float %17 %31 Lod %25
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_bcbb3c
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_bcbb3c
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_bcbb3c
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_bcbb3c
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_bcbb3c
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_bcbb3c
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
index f4e00a0..802800f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bd990a() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
index f4e00a0..802800f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bd990a() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.msl
index d09c4f7..8898c48 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_bd990a(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.msl
index 43e5a5e..969dcd3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_bd990a(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.spvasm
index 810d46f..186ce20 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bd990a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,47 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_bd990a = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %13
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4uint %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_bd990a
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_bd990a
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_bd990a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_bd990a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.glsl
index e99e15d..6f22e0b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_bdc67a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_bdc67a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
index c4ace39..f86bd89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_bdc67a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
index c4ace39..f86bd89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_bdc67a() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.msl
index e841945..53ac7a5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_bdc67a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.msl
index ceb0463..9c89634 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_bdc67a(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.spvasm
index ce2ea6b..c8ec433 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bdc67a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,39 +37,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_bdc67a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_bdc67a
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_bdc67a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_bdc67a
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_bdc67a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.glsl
index 7a12416..0dd21ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_bfd154() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_bfd154() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_bfd154() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
index 482670b..4edb1dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bfd154() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bfd154();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
index 482670b..4edb1dc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bfd154() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bfd154();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.msl
index b7e29b5..11bd9f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_bfd154(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.msl
index 0383896..c4b3206 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_bfd154(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.spvasm
index 47dd5e6..64ed43b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/bfd154.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bfd154 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpBitcast %v3uint %27
+         %31 = OpExtInst %v3uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_bfd154
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_bfd154
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_bfd154
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_bfd154
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_bfd154
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_bfd154
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.glsl
index d72b595..c9da1f3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c02b74() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c02b74() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c02b74() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
index 26c123f..096bb69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c02b74() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c02b74();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
index 26c123f..096bb69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c02b74() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c02b74();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.msl
index bc0ad7bd..a383468 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_c02b74(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.msl
index 1922af0..adc3c69 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c02b74(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.spvasm
index 24ed5d2..b39f94b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c02b74.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c02b74 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_c02b74
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_c02b74
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_c02b74
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_c02b74
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_c02b74
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.glsl
index d6d18d7..31ee91b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c07013() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c07013() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c07013() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
index 5fb3fd9..7e12426 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c07013() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c07013();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
index 5fb3fd9..7e12426 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c07013() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c07013();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.msl
index 4a19ed9..358ce72 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_c07013(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.msl
index 630ad77..faf7710 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c07013(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.spvasm
index b66c476..14a800d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c07013.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c07013 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_c07013
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_c07013
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_c07013
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_c07013
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_c07013
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_c07013
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.glsl
index d293f3d..025e592 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_c16e00() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  float res = texelFetch(arg_0, v_7, int(v_4)).x;
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_c16e00() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_2));
+  float res = texelFetch(arg_0, v_7, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_c16e00() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1u));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_1));
+  float res = texelFetch(arg_0, v_6, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
index c274ed1..8469263 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_c16e00() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_5, v_6, int(v_2))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c16e00();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
index c274ed1..8469263 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_c16e00() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_5, v_6, int(v_2))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c16e00();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.msl
index 3f2c70f..e6d9320 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float textureLoad_c16e00(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.msl
index f93db42..2774531 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_c16e00(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.spvasm
index 97168d8..50fdf0b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c16e00.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,69 +55,83 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+        %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %39 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %46 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c16e00 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %19 = OpBitcast %int %uint_1
-         %23 = OpCompositeConstruct %v3int %24 %19
-         %27 = OpImageFetch %v4float %17 %23 Lod %int_1
-         %28 = OpCompositeExtract %float %27 0
-               OpStore %res %28
-         %31 = OpLoad %float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %26 UMin %29 %28
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %39
+         %41 = OpExtInst %v2uint %26 UMin %38 %36
+         %42 = OpCompositeConstruct %v3uint %41 %25
+         %43 = OpImageFetch %v4float %17 %42 Lod %32
+         %44 = OpCompositeExtract %float %43 0
+               OpStore %res %44
+         %47 = OpLoad %float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %float %textureLoad_c16e00
-         %37 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %float %textureLoad_c16e00
+         %53 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %float %textureLoad_c16e00
-         %43 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %50
+         %56 = OpLabel
+         %57 = OpFunctionCall %float %textureLoad_c16e00
+         %58 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %55 = OpFunctionCall %float %textureLoad_c16e00
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %70 = OpFunctionCall %float %textureLoad_c16e00
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %float %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.glsl
index 073b014..05adfd5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c21b33() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c21b33() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_c21b33() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
index eb2e8ec..7a53190 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c21b33() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c21b33();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
index eb2e8ec..7a53190 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c21b33() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c21b33();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.msl
index e303b4e..1843284 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_c21b33(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.msl
index 4b046b0..45336b2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c21b33(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.spvasm
index e8e1204..61a3ffb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c21b33.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,75 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %26 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c21b33 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %v3uint %26 %21
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpExtInst %v2uint %30 UMin %35 %34
+         %37 = OpCompositeConstruct %v3uint %36 %29
+         %38 = OpImageRead %v4uint %20 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_c21b33
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_c21b33
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_c21b33
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_c21b33
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_c21b33
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_c21b33
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.glsl
index d77c0f9..238abcd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.glsl
@@ -2,14 +2,26 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_c2a480() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -17,14 +29,26 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_c2a480() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +58,27 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c2a480() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +88,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
index b6adf68..45e8793 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c2a480() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c2a480();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
index b6adf68..45e8793 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c2a480() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_1))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c2a480();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.msl
index d00f01a..f24b59e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_c2a480(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.msl
index e3d5c76..dc5c06a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c2a480(texture2d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.spvasm
index 66305c9..ec5a764 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c2a480.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,74 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c2a480 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %int_1
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageQuerySizeLod %v2uint %20 %27
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %36 = OpExtInst %v2uint %28 UMin %33 %31
+         %37 = OpImageFetch %v4int %20 %36 Lod %27
+               OpStore %res %37
+         %40 = OpLoad %v4int %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_c2a480
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_c2a480
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%fragment_main = OpFunction %void None %43
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_c2a480
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %v4int %textureLoad_c2a480
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4int %textureLoad_c2a480
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %55
          %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %64 = OpFunctionCall %v4int %textureLoad_c2a480
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4int %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.glsl
index bf389e2..07171f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_c2d09a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, r32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_c2d09a() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
index 12e9770..334bd88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c2d09a() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
index 12e9770..334bd88 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c2d09a() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.msl
index 80c97d6..f94d2df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_c2d09a(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.msl
index 6137a31..6efb34f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c2d09a(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.spvasm
index 59d8b4f..22622bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c2d09a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,47 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_c2d09a = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %13
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4uint %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_c2d09a
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_c2d09a
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_c2d09a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_c2d09a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.glsl
index b7ca804..0f2c29d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_c378ee() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_c378ee() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp usampler2DMS arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_c378ee() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v, int(1));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  uvec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
index f5a8f80..9017566 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c378ee() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  uint4 res = uint4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c378ee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
index f5a8f80..9017566 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c378ee() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  uint4 res = uint4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c378ee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.msl
index af2d5ac..6c0ec21 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_c378ee(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.msl
index 4dfbb73..400c27e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c378ee(texture2d_ms<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.spvasm
index 046a132..52f0cc4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c378ee.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c378ee = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Sample %int_1
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageFetch %v4uint %20 %31 Sample %int_1
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_c378ee
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_c378ee
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_c378ee
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_c378ee
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_c378ee
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_c378ee
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.glsl
index 4d1f1a7..3d8c2f5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c40dcb() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c40dcb() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_c40dcb() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
index ecda24f..c000548 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c40dcb() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c40dcb();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
index ecda24f..c000548 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c40dcb() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c40dcb();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.msl
index 34b61e3..b322bd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_c40dcb(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.msl
index 6aa3198..9b2eba3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c40dcb(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.spvasm
index 589c701..619ad16 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c40dcb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c40dcb = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageRead %v4uint %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4uint %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_c40dcb
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_c40dcb
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_c40dcb
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_c40dcb
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_c40dcb
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.glsl
index 468c082..9726fed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_c456bc() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_c456bc() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c456bc() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
index 035efcc..bc7350c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c456bc() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c456bc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
index 035efcc..bc7350c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c456bc() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c456bc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.msl
index a727a6a..7ed977b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_c456bc(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.msl
index 87f7d24..559e411 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c456bc(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.spvasm
index 0861f8b..41acb2c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c456bc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c456bc = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_c456bc
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_c456bc
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_c456bc
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_c456bc
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_c456bc
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_c456bc
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.glsl
index ef2961f..70310be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c5791b() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c5791b() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c5791b() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
index f0c9cb7..d926690 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c5791b() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c5791b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
index f0c9cb7..d926690 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c5791b() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c5791b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.msl
index 5419de9..c3f68b8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_c5791b(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.msl
index c4d4aa7..a11f5f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_c5791b(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.spvasm
index 4690504..62eb331 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c5791b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c5791b = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_c5791b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_c5791b
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_c5791b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_c5791b
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_c5791b
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_c5791b
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
index 48a509f..a3778b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c5c86d() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
index 48a509f..a3778b0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c5c86d() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.msl
index 01716db..984b176 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 int4 textureLoad_c5c86d(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.msl
index 4d7e3db..566081c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c5c86d(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.spvasm
index 41a84fc..8b8c4e2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c5c86d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %15 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c5c86d = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3int %15 %int_1
-         %18 = OpImageRead %v4int %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4int %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_c5c86d
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_c5c86d
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_c5c86d
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_c5c86d
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.glsl
index 3788838..e5cb6d1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c66b20() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c66b20() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c66b20() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
index 39b6191..9507d10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c66b20() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c66b20();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
index 39b6191..9507d10 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c66b20() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c66b20();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.msl
index ef75701..80aebf9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_c66b20(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.msl
index 5c4f7ce..c8f96f4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_c66b20(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.spvasm
index 105e6f8..75f9a11 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c66b20.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c66b20 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpExtInst %v2uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_c66b20
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_c66b20
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_c66b20
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_c66b20
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_c66b20
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_c66b20
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.glsl
index 41829cb..29a333f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c7cbed() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c7cbed() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c7cbed() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
index 0e29b44..7271e8d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c7cbed() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c7cbed();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
index 0e29b44..7271e8d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c7cbed() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c7cbed();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.msl
index 0ab19e4..1585e4c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_c7cbed(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.msl
index 66fd1f6..5ccbb58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c7cbed(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.spvasm
index c0e0650..f04c851 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c7cbed.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c7cbed = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_c7cbed
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_c7cbed
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_c7cbed
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_c7cbed
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_c7cbed
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
index 98abb50..15c7cc3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c7e313() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
index 98abb50..15c7cc3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c7e313() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.msl
index 32b4107..cf2e292 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 uint4 textureLoad_c7e313(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.msl
index 4970ce8..500bdec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_c7e313(texture2d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.spvasm
index f3e8453..caae7b9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c7e313.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,32 +37,35 @@
          %10 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %26 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_c7e313 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4uint %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %15 = OpISub %v2uint %13 %16
+         %18 = OpExtInst %v2uint %19 UMin %16 %15
+         %20 = OpImageRead %v4uint %12 %18 None
+               OpStore %res %20
+         %23 = OpLoad %v4uint %res None
+               OpReturnValue %23
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4uint %textureLoad_c7e313
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpFunctionCall %v4uint %textureLoad_c7e313
+         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %29 %28 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4uint %textureLoad_c7e313
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %31 %30 None
+%compute_main = OpFunction %void None %26
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4uint %textureLoad_c7e313
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.glsl
index b803c21..b23b5a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c80691() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c80691() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
index 12e743d..e5663f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c80691() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
index 12e743d..e5663f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c80691() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.msl
index d81effd..46a65c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_c80691(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.msl
index e1b8e51..2001d52 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_c80691(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1u));
+  int4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.spvasm
index 0f791b3..d349d35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c80691.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_c80691 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4int %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4int %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4int %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4int %textureLoad_c80691
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4int %textureLoad_c80691
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_c80691
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_c80691
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.glsl
index f356857..9065316 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c8ed19() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_c8ed19() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_c8ed19() {
-  ivec2 v = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
index 4880759..4842cbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c8ed19() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c8ed19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
index 4880759..4842cbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_c8ed19() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c8ed19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.msl
index 106a895..20c8905 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_c8ed19(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.msl
index deae260..9199635 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_c8ed19(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.spvasm
index 3b63ffa..c01c970 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c8ed19.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +61,71 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c8ed19 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3uint %23 %uint_1
-         %26 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpExtInst %v2uint %27 UMin %32 %31
+         %34 = OpCompositeConstruct %v3uint %33 %26
+         %35 = OpImageRead %v4uint %20 %34 None
+               OpStore %res %35
+         %38 = OpLoad %v4uint %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_c8ed19
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_c8ed19
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_c8ed19
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_c8ed19
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_c8ed19
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %62 = OpFunctionCall %v4uint %textureLoad_c8ed19
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4uint %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
index c1c8388..9272ce6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_c98bf4() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
index c1c8388..9272ce6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_c98bf4() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.msl
index f874898..53d9ef4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_c98bf4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.msl
index ea519a0..064f4b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c98bf4(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.spvasm
index ee3aa62..1661d96 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c98bf4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c98bf4 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_c98bf4
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_c98bf4
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_c98bf4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_c98bf4
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
index 5fad3be..7c31c95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9b083() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
index 5fad3be..7c31c95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9b083() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.msl
index 4b1e7be..e7af9c5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_c9b083(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.msl
index a8d053d..adcb667 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9b083(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.spvasm
index 1f2e2e6..cb372e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c9b083.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_c9b083 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %13
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %30 = OpExtInst %v2uint %20 UMin %26 %24
+         %31 = OpCompositeConstruct %v3uint %30 %19
+         %32 = OpImageRead %v4int %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_c9b083
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_c9b083
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_c9b083
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_c9b083
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.glsl
index 43ddd2f..678f3c6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c9cc40() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c9cc40() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c9cc40() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
index 7bd8cc7..099ce35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c9cc40() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c9cc40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
index 7bd8cc7..099ce35 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c9cc40() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c9cc40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.msl
index 3a0992a..e8f0a50 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_c9cc40(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.msl
index 80330df..c75c71b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9cc40(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.spvasm
index 77b8d66..902823d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c9cc40.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c9cc40 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %int_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_c9cc40
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4int %textureLoad_c9cc40
          %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_c9cc40
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4int %textureLoad_c9cc40
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_c9cc40
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.glsl
index 362ad36..20f25d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c9f310() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c9f310() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
index 6872e50..2af9b9e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9f310() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
index 6872e50..2af9b9e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9f310() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.msl
index 6472b9b..db3b0eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_c9f310(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.msl
index b8611e8..4e3b949 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9f310(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1));
+  int4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.spvasm
index 9ec3e09..059181a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/c9f310.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c9f310 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %int_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4int %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %17 %15
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4int %textureLoad_c9f310
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %23 %22 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %20
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4int %textureLoad_c9f310
          %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_c9f310
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
index ec8cad9..bfe3bd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cac876() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
index ec8cad9..bfe3bd7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cac876() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.msl
index 5759aec..aaa34c9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_cac876(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.msl
index efb0ff8..4f9c224 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_cac876(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1u));
+  int4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.spvasm
index 43a697f..0f48e13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cac876.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_cac876 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4int %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4int %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4int %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4int %textureLoad_cac876
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4int %textureLoad_cac876
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_cac876
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_cac876
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.glsl
index b560949..6e8e6b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_cad5f2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_cad5f2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = texelFetch(arg_0, v_2, int(1u));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp usampler2DMS arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_cad5f2() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  uvec4 res = texelFetch(arg_0, v_1, int(1u));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
index 4ff99bb..356f19d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_cad5f2() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  uint4 res = uint4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cad5f2();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
index 4ff99bb..356f19d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_cad5f2() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(v, int(1u)));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  uint4 res = uint4(arg_0.Load(v_2, int(1u)));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cad5f2();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.msl
index f99dd2d..1f78e27 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_cad5f2(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1u);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.msl
index c74fa80..a4139c7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cad5f2(texture2d_ms<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1u);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.spvasm
index 0e83cc4..c991ad4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cad5f2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
-     %uint_1 = OpConstant %uint 1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cad5f2 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Sample %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageFetch %v4uint %20 %31 Sample %uint_1
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_cad5f2
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_cad5f2
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_cad5f2
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_cad5f2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_cad5f2
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_cad5f2
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.glsl
index 32d2563..cb3bd44 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_cb57c2() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_cb57c2() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  float res = texelFetch(arg_0, v_2, int(1)).x;
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_cb57c2() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  float res = texelFetch(arg_0, v_1, int(1)).x;
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
index 184feae..b305f63 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_cb57c2() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_4, v_5, int(v_2))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cb57c2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
index 184feae..b305f63 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_cb57c2() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float res = arg_0.Load(int4(v, v_1, int(int(1)))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float res = arg_0.Load(int4(v_4, v_5, int(v_2))).x;
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cb57c2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.msl
index ed8f0dd..a1da94c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float textureLoad_cb57c2(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.msl
index 672be36..c5e215a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float textureLoad_cb57c2(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.spvasm
index a86d84d..78da408 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cb57c2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,66 +57,78 @@
          %15 = OpTypeFunction %float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %45 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cb57c2 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %int_1
-         %27 = OpCompositeExtract %float %24 0
-               OpStore %res %27
-         %30 = OpLoad %float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %26 UMin %29 %28
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpExtInst %v2uint %26 UMin %37 %36
+         %39 = OpCompositeConstruct %v3uint %38 %25
+         %40 = OpImageFetch %v4float %17 %39 Lod %32
+         %41 = OpCompositeExtract %float %40 0
+               OpStore %res %41
+         %44 = OpLoad %float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %float %textureLoad_cb57c2
-         %36 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %float %textureLoad_cb57c2
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %float %textureLoad_cb57c2
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_float %out %uint_1
+%compute_main = OpFunction %void None %47
+         %53 = OpLabel
          %54 = OpFunctionCall %float %textureLoad_cb57c2
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %55 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %55 %54 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %67 = OpFunctionCall %float %textureLoad_cb57c2
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %float %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
index 347bf1b..5519c2e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cdbcf6() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
index 347bf1b..5519c2e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cdbcf6() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.msl
index fdebb8b..70ce012 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_cdbcf6(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.msl
index 7555ade..b2cc74e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_cdbcf6(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.spvasm
index 7a0a736..75da191 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cdbcf6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_cdbcf6 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_cdbcf6
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_cdbcf6
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_cdbcf6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_cdbcf6
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.glsl
index e0f4b9f..5a4d5e1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_cdccd2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_cdccd2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
index 88d0939..40955bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_cdccd2() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
index 88d0939..40955bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_cdccd2() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.msl
index b08d387..925a2d7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_cdccd2(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.msl
index b98b68b..0af3c79 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cdccd2(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.spvasm
index c73308e..fdbf117 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cdccd2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,49 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %26 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_cdccd2 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %14
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpBitcast %v2uint %26
+         %30 = OpExtInst %v2uint %19 UMin %25 %23
+         %31 = OpCompositeConstruct %v3uint %30 %18
+         %32 = OpImageRead %v4uint %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_cdccd2
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_cdccd2
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_cdccd2
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_cdccd2
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.glsl
index e1b8225..853e5a1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_cdd343() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_cdd343() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_cdd343() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
index 0408695..4569606 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_cdd343() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cdd343();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
index 0408695..4569606 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_cdd343() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cdd343();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.msl
index 8e8e369..2e2835b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_cdd343(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.msl
index 6513a83..826bc47 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cdd343(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.spvasm
index 229642d..59e159c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cdd343.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,67 +59,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cdd343 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %38 = OpExtInst %v2uint %27 UMin %33 %31
+         %39 = OpCompositeConstruct %v3uint %38 %26
+         %40 = OpImageRead %v4uint %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_cdd343
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_cdd343
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_cdd343
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_cdd343
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_cdd343
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_cdd343
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
index 4ef363d..7a1f633 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cddf6b() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
index 4ef363d..7a1f633 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cddf6b() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.msl
index bbb78dd..43b9e67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_cddf6b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.msl
index 4e532eb..4ce4631 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_cddf6b(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.spvasm
index b8edc42..9910864 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cddf6b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_cddf6b = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_cddf6b
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_cddf6b
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_cddf6b
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_cddf6b
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.glsl
index e2024ef..df39349 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_cec477() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_cec477() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
index b4831d7..210e722 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cec477() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
index b4831d7..210e722 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cec477() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.msl
index 27f225b..5ee5f2b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_cec477(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.msl
index 6d3c878..ea96582 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_cec477(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(uint3(1u)));
+  int4 res = tint_symbol.read(uint3(min(uint3(1u), (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.spvasm
index 4a51e98..9516f43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cec477.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_cec477 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpExtInst %v3uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_cec477
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_cec477
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_cec477
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_cec477
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.glsl
index 447fd9b..c3a50d2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_cece6c() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_cece6c() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_cece6c() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
index 59186b6..86cf3e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_cece6c() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cece6c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
index 59186b6..86cf3e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_cece6c() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cece6c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.msl
index 5a9fe62..2ec84e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_cece6c(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.msl
index e290160..f4e759e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_cece6c(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.spvasm
index e68253c..ed2dab7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/cece6c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cece6c = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_cece6c
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_cece6c
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_cece6c
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_cece6c
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_cece6c
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_cece6c
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.glsl
index bfdbda3..e53c6c0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_d02afc() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_d02afc() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_d02afc() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
index bfc0b79..09cf47d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d02afc() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d02afc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
index bfc0b79..09cf47d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d02afc() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d02afc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.msl
index e4ac058..20338cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_d02afc(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.msl
index 2aaa2c6..31f2a76 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_d02afc(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.spvasm
index 3390c2d..f951062 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d02afc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d02afc = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpExtInst %v3uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_d02afc
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_d02afc
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_d02afc
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_d02afc
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_d02afc
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_d02afc
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.glsl
index 754b45b..99af090 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_d0e351() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp uimage2DArray arg_0;
 uvec4 textureLoad_d0e351() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
index c7aa4ba..3ea9e7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d0e351() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
index c7aa4ba..3ea9e7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d0e351() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.msl
index 05484d5..87ce258 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_d0e351(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.msl
index 12c3887..a1f7252 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d0e351(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.spvasm
index 0c94944..2168f68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d0e351.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d0e351 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %13
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4uint %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_d0e351
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_d0e351
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d0e351
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_d0e351
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.glsl
index 5be9873..388541c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d357bb() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0))).zyxw;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d357bb() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0))).zyxw;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d357bb() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0))).zyxw;
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
index d900b4a..2acc502 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d357bb() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d357bb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
index d900b4a..2acc502 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d357bb() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d357bb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.msl
index 01ed05c..434beed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_d357bb(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.msl
index 357393d..7d48616 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d357bb(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.spvasm
index b906a59..8f5c4aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d357bb.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,63 +57,67 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %50 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d357bb = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-         %21 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+         %28 = OpVectorShuffle %v4float %27 %27 2 1 0 3
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_d357bb
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %27
+%fragment_main = OpFunction %void None %34
          %35 = OpLabel
          %36 = OpFunctionCall %v4float %textureLoad_d357bb
          %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
+%compute_main = OpFunction %void None %34
          %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_d357bb
-               OpStore %47 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+         %42 = OpFunctionCall %v4float %textureLoad_d357bb
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %27
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %54 = OpFunctionCall %v4float %textureLoad_d357bb
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %34
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4float %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
index 7daddf3..72f02d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d37a08() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
index 7daddf3..72f02d5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d37a08() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.msl
index c0e28d3..7bf2237 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_d37a08(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.msl
index 258b26c..6ff8084 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d37a08(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.spvasm
index 56fc776..7f3dac1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d37a08.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,49 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %26 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d37a08 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %14
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpBitcast %v2uint %26
+         %30 = OpExtInst %v2uint %19 UMin %25 %23
+         %31 = OpCompositeConstruct %v3uint %30 %18
+         %32 = OpImageRead %v4uint %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_d37a08
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_d37a08
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d37a08
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_d37a08
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
index f4758a9..d1613f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d3d8fc() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
index f4758a9..d1613f6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d3d8fc() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.msl
index 7f8d819..6836f99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_d3d8fc(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.msl
index ec80f3f..42d13db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d3d8fc(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.spvasm
index 7d9b765..3b7ecf9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d3d8fc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,38 +36,46 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_d3d8fc = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %14
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4int %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_d3d8fc
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_d3d8fc
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_d3d8fc
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_d3d8fc
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.glsl
index 33b5b1b..5952aae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_d41c72() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_d41c72() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
index 642c60e..5892641 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d41c72() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
index 642c60e..5892641 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d41c72() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.msl
index c1859a2..4399436 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_d41c72(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.msl
index 06ef8ce..e5943e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d41c72(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(int3(1)));
+  int4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.spvasm
index 6d5483f..b8078e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d41c72.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d41c72 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %23 = OpExtInst %v3uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_d41c72
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_d41c72
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_d41c72
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_d41c72
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.glsl
index 5b3a215..b736e2c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d4df19() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d4df19() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_d4df19() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
index 5bac093..4acfdee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d4df19() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d4df19();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
index 5bac093..4acfdee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d4df19() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d4df19();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.msl
index dff986b..fc36719 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_d4df19(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.msl
index bf17ff4..7e586e7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_d4df19(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.spvasm
index 092bfe8..81ad66f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d4df19.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d4df19 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_d4df19
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_d4df19
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_d4df19
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_d4df19
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_d4df19
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_d4df19
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.glsl
index 7afa6fe..c07e0e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d5c48d() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d5c48d() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d5c48d() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
index 8e07c8d..966caa8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d5c48d() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d5c48d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
index 8e07c8d..966caa8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d5c48d() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d5c48d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.msl
index 3999380..f58ec0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_d5c48d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.msl
index 8beea3d..2bd32b5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d5c48d(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.spvasm
index 737c18b..62ebffb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d5c48d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d5c48d = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_d5c48d
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_d5c48d
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_d5c48d
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_d5c48d
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_d5c48d
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_d5c48d
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
index 767cf07..a9b4999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d72de9() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
index 767cf07..a9b4999 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d72de9() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.msl
index 67f19e3..613eb68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_d72de9(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.msl
index 30e7bd8..cb42cb9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d72de9(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)));
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.spvasm
index 3182ef7..0a1a975 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d72de9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d72de9 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %23 = OpExtInst %v2uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_d72de9
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_d72de9
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_d72de9
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_d72de9
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
index 1e30e65..95ca090 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d7996a() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
index 1e30e65..95ca090 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d7996a() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.msl
index 67115c0..a5273e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_d7996a(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.msl
index 63d8bcc..20c09ab 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d7996a(texture3d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint3(int3(1)));
+  int4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.spvasm
index c040cac..b10187d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d7996a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d7996a = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %23 = OpExtInst %v3uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_d7996a
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_d7996a
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_d7996a
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_d7996a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
index d9ca2ed..72d32aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d79c5c() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
index d9ca2ed..72d32aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d79c5c() {
-  uint4 res = uint4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.msl
index 6ed6583..6e552e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_d79c5c(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.msl
index 9e63b72..d0cbb62 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d79c5c(texture1d<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint(1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.spvasm
index 86aa40a..7228395 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d79c5c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d79c5c = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4uint %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4uint %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpImageRead %v4uint %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4uint %textureLoad_d79c5c
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4uint %textureLoad_d79c5c
          %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_d79c5c
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
index 21ff4d6..c3272bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d80ff3() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
index 21ff4d6..c3272bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d80ff3() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.msl
index 6cb0aaa..cb25ba9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_d80ff3(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.msl
index 8630244..6bb2f68 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d80ff3(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.spvasm
index 8dd5d0f..f328f77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d80ff3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,35 +36,40 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d80ff3 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-         %16 = OpVectorShuffle %v4float %13 %13 2 1 0 3
-               OpStore %res %16
-         %19 = OpLoad %v4float %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+         %23 = OpVectorShuffle %v4float %22 %22 2 1 0 3
+               OpStore %res %23
+         %26 = OpLoad %v4float %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4float %textureLoad_d80ff3
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %25 %24 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %22
+%fragment_main = OpFunction %void None %29
          %30 = OpLabel
          %31 = OpFunctionCall %v4float %textureLoad_d80ff3
          %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_d80ff3
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.glsl
index ddf1262..d12b41a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d81c57() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d81c57() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d81c57() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
index c3f2013..f8c3a41c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d81c57() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d81c57();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
index c3f2013..f8c3a41c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d81c57() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d81c57();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.msl
index 4c99c67..383eade 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_d81c57(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.msl
index a62e9bc..101f445 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d81c57(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.spvasm
index 0bd4b46..1fe075f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d81c57.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d81c57 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_d81c57
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_d81c57
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_d81c57
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_d81c57
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_d81c57
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.glsl
index d66fd89..29ea2a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d85d61() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d85d61() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_d85d61() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
index 9db0ff4..664c64c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d85d61() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d85d61();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
index 9db0ff4..664c64c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d85d61() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d85d61();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.msl
index e6fceea..2e62152 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_d85d61(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.msl
index fa35873..a5d0135 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_d85d61(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.spvasm
index 2127c5d..fb7a8e7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d85d61.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d85d61 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_d85d61
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_d85d61
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_d85d61
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_d85d61
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_d85d61
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_d85d61
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.glsl
index f3b5ce3..b9898b4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_d8617f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_d8617f() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_d8617f() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
index e36fc0a..739ae92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d8617f() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d8617f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
index e36fc0a..739ae92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d8617f() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d8617f();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.msl
index c3c8fc1..9d65440 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_d8617f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.msl
index b9b1fbb..b6c4827 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d8617f(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.spvasm
index 5a2ccb7..8347018 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d8617f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,66 +60,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d8617f = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageRead %v4int %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4int %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4int %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_d8617f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_d8617f
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_d8617f
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_d8617f
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_d8617f
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
index 371eb34..9243af9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d8be5a() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
index 371eb34..9243af9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d8be5a() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.msl
index f898f11..67e3c38 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_d8be5a(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.msl
index 41d0750..a77cff8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d8be5a(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1));
+  int4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.spvasm
index 87d03c5..4177c8b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d8be5a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,33 +36,38 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %20 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d8be5a = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %int_1 None
-               OpStore %res %13
-         %17 = OpLoad %v4int %res None
-               OpReturnValue %17
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %17 %15
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %20
-         %21 = OpLabel
-         %22 = OpFunctionCall %v4int %textureLoad_d8be5a
-         %23 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %23 %22 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %20
+%fragment_main = OpFunction %void None %27
          %28 = OpLabel
          %29 = OpFunctionCall %v4int %textureLoad_d8be5a
          %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_d8be5a
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
index 11924d4..756df2f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d91f37() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
index 11924d4..756df2f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d91f37() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  float4 res = float4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.msl
index e4102d1..6803e65 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_d91f37(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.msl
index 9c58fdc..e35a843 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d91f37(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.spvasm
index 56825c9..2876651 100644
--- a/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/d91f37.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,40 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
-        %int = OpTypeInt 32 1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_d91f37 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %18 = OpCompositeConstruct %v3int %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %20 UMin %26 %24
+         %32 = OpCompositeConstruct %v3uint %31 %19
+         %33 = OpImageRead %v4float %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_d91f37
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_d91f37
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_d91f37
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_d91f37
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
index c9b6f0d..58b15ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_dab04f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
index c9b6f0d..58b15ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_dab04f() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.msl
index db50e08..c9a194a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_dab04f(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.msl
index c97f0b6..d439006 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_dab04f(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.spvasm
index 07a71fc..0930d43 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dab04f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,52 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_dab04f = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-         %20 = OpVectorShuffle %v4float %19 %19 2 1 0 3
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+         %35 = OpVectorShuffle %v4float %34 %34 2 1 0 3
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_dab04f
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_dab04f
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_dab04f
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_dab04f
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.glsl
index 057298d..b2d50a3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dbd554() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dbd554() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_dbd554() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
index 653cc07..ad73a33 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dbd554() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dbd554();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
index 653cc07..ad73a33 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dbd554() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dbd554();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.msl
index f8421ed..e37acd9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_dbd554(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.msl
index 74bc5f1..0495d6b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_dbd554(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.spvasm
index 5edaae3..55eea5e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dbd554.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dbd554 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_dbd554
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_dbd554
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_dbd554
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_dbd554
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_dbd554
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_dbd554
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
index c7c50df..8aee1a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_dd5859() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
index c7c50df..8aee1a8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_dd5859() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.msl
index 1f77074..de7469f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_dd5859(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.msl
index df63929..0bd57e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_dd5859(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.spvasm
index 866ae15..237bcc7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dd5859.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,38 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_dd5859 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_dd5859
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_dd5859
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_dd5859
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_dd5859
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.glsl
index 74440ce..a5ce8f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_dd8776() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_dd8776() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_dd8776() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
index 0e21d1a..b4f9724 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_dd8776() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dd8776();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
index 0e21d1a..b4f9724 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_dd8776() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dd8776();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.msl
index 80e75e1..7843692 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_dd8776(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.msl
index 3db792f..bd521a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_dd8776(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.spvasm
index fe41d32..13984b7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dd8776.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,62 +59,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dd8776 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_dd8776
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_dd8776
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_dd8776
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_dd8776
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_dd8776
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_dd8776
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.glsl
index c80443b4..8aa4a36 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_ddeed3() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_ddeed3() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_ddeed3() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
index fafbc5b..fd1563d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ddeed3() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ddeed3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
index fafbc5b..fd1563d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ddeed3() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ddeed3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.msl
index 432af8c..874f508 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_ddeed3(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.msl
index 77498a6..7c21d31 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ddeed3(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.spvasm
index b4019bb..f8a5e80 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ddeed3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ddeed3 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %int_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_ddeed3
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4int %textureLoad_ddeed3
          %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_ddeed3
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4int %textureLoad_ddeed3
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_ddeed3
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
index 1a0c080..e0fe482 100644
--- a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_de5a0e() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
index 1a0c080..e0fe482 100644
--- a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_de5a0e() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.msl
index b8a6f5f..7a2e5eb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_de5a0e(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.msl
index 48e9535..5885f15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_de5a0e(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.spvasm
index 3f0a041..b4da8a0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/de5a0e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,35 +37,43 @@
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_de5a0e = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4int %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4int %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_de5a0e
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_de5a0e
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_de5a0e
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_de5a0e
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.glsl
index 8f3fce6..eb71d77 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dee8e7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dee8e7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_dee8e7() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
index 5f994a1..40a2729 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dee8e7() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dee8e7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
index 5f994a1..40a2729 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dee8e7() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dee8e7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.msl
index f003f9c..9b7724f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_dee8e7(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.msl
index ecb0319..66a820e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_dee8e7(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.spvasm
index 0869ef7..5a2115c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dee8e7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dee8e7 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_dee8e7
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_dee8e7
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_dee8e7
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_dee8e7
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_dee8e7
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_dee8e7
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.glsl
index 0f1eefe..492f940 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_defd9a() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_defd9a() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
index 3240f14..c7d5fd2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_defd9a() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
index 3240f14..c7d5fd2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_defd9a() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.msl
index f7da608..7ffb088 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_defd9a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.msl
index 2999527..9cb32d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_defd9a(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.spvasm
index 414d93c..dac9d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/defd9a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,36 +36,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_defd9a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_defd9a
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_defd9a
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_defd9a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_defd9a
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.glsl
index 169d2c7..f209307 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_dfdf3b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_dfdf3b() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_dfdf3b() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
index 24b4f70..da10bbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dfdf3b() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dfdf3b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
index 24b4f70..da10bbc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dfdf3b() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dfdf3b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.msl
index d8c97bd..eb67ed4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_dfdf3b(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.msl
index d789ef9..0e83899 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_dfdf3b(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  int4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.spvasm
index ac9004ca..86ec9e9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/dfdf3b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,63 +61,71 @@
          %18 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dfdf3b = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3uint %24 %uint_1
-         %27 = OpImageRead %v4int %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpExtInst %uint %28 UMin %uint_1 %25
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4int %20 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_dfdf3b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_dfdf3b
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_dfdf3b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_dfdf3b
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_dfdf3b
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_dfdf3b
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
index b5b0368..4b676f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e1c3cf() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
index b5b0368..4b676f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e1c3cf() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.msl
index e2680c0..960ec4b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_e1c3cf(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.msl
index b7a4f4b..29d60526 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e1c3cf(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.spvasm
index 77c3380..9a3efb1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e1c3cf.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_e1c3cf = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_e1c3cf
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_e1c3cf
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_e1c3cf
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_e1c3cf
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.glsl
index e015425..f1bbc95 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_e2292f() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_e2292f() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e2292f() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
index 6832677..49ce370 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e2292f() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e2292f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
index 6832677..49ce370 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e2292f() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e2292f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.msl
index d6b03da..144a2af 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_e2292f(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.msl
index d858fb0..6d5d670 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_e2292f(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.spvasm
index fd443a4..2d29f40 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e2292f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e2292f = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %uint_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageRead %v4int %20 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4int %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_e2292f
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_e2292f
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_e2292f
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_e2292f
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_e2292f
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %54 = OpFunctionCall %v4int %textureLoad_e2292f
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4int %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.glsl
index 1c785a4..f174ab9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_e2b3a1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_e2b3a1() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
index 8ead5b0..f0bbb1b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e2b3a1() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
index 8ead5b0..f0bbb1b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e2b3a1() {
-  int2 v = int2((1u).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.msl
index 4845ac1..e693bba 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_e2b3a1(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.msl
index 3b7c73b..81162af 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e2b3a1(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.spvasm
index d556286..2619399 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e2b3a1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,38 +37,46 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
-      %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_e2b3a1 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %14
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4int %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_e2b3a1
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_e2b3a1
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_e2b3a1
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_e2b3a1
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
index 8f10dcc..0a7cac9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e2d7da() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
index 8f10dcc..0a7cac9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e2d7da() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.msl
index 74b70f6..95c28ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_e2d7da(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.msl
index dd19fee..3b036db 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e2d7da(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.spvasm
index d56e121..cbfc63f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e2d7da.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_e2d7da = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_e2d7da
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_e2d7da
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_e2d7da
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_e2d7da
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
index 63894da..9825844 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e33285() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
index 63894da..9825844 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e33285() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.msl
index 06a5b51..0d994de 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_e33285(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.msl
index 4088510..4d75b02 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e33285(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)));
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.spvasm
index 92946f2..4e89661 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e33285.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,35 +35,42 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_e33285 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %19 = OpLoad %v4int %res None
-               OpReturnValue %19
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %23 = OpExtInst %v2uint %24 UMin %19 %16
+         %25 = OpImageRead %v4int %12 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4int %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %22
-         %23 = OpLabel
-         %24 = OpFunctionCall %v4int %textureLoad_e33285
-         %25 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %25 %24 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_e33285
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_e33285
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4int %textureLoad_e33285
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.glsl
index a985f2a..e12822e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_e35f72() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_e35f72() {
-  ivec3 v_1 = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(ivec3(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e35f72() {
-  ivec3 v = ivec3(ivec3(1));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_2 = (uvec3(textureSize(arg_0, int(v_1))) - uvec3(1u));
+  ivec3 v_3 = ivec3(min(uvec3(ivec3(1)), v_2));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
index 0a1e9f1..75629bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e35f72() {
-  int3 v = int3((int(1)).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e35f72();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
index 0a1e9f1..75629bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e35f72() {
-  int3 v = int3((int(1)).xxx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u))));
+  uint4 v = (0u).xxxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 v_2 = (v_1.xyz - (1u).xxx);
+  int3 v_3 = int3(min(uint3((int(1)).xxx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.w - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e35f72();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.msl
index b14afea..f9e07f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_e35f72(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)), 1u);
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_depth(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.msl
index 44b63d2..5368361 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e35f72(texture3d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.spvasm
index 04946dc..21af5bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e35f72.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %30 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+      %v3int = OpTypeVector %int 3
+      %int_1 = OpConstant %int 1
+         %32 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e35f72 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v3uint %20 %25
+         %29 = OpISub %v3uint %27 %30
+         %31 = OpBitcast %v3uint %32
+         %35 = OpExtInst %v3uint %26 UMin %31 %29
+         %36 = OpImageFetch %v4int %20 %35 Lod %25
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_e35f72
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_e35f72
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_e35f72
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_e35f72
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_e35f72
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_e35f72
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.glsl
index a8a48af..e5245cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_e3b08b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_e3b08b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e3b08b() {
-  vec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
index e0ab235..ab46052 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e3b08b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3b08b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
index e0ab235..ab46052 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e3b08b() {
-  float4 res = float4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3b08b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.msl
index b854689..5ffb765 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_e3b08b(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.msl
index 90733e0..789808d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_e3b08b(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  float4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.spvasm
index 127da58..01ff705 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e3b08b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e3b08b = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpExtInst %v3uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_e3b08b
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_e3b08b
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_e3b08b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_e3b08b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_e3b08b
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_e3b08b
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.glsl
index 46f6caa..2e09f3f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_e3d2cc() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 uniform highp isampler2DMS arg_0;
 ivec4 textureLoad_e3d2cc() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1));
+  uvec2 v_1 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  ivec4 res = texelFetch(arg_0, v_2, int(1));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 uniform highp isampler2DMS arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e3d2cc() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v, int(1));
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(1)), v));
+  ivec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
index 1074c3d..a772a67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e3d2cc() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  int4 res = int4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3d2cc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
index 1074c3d..a772a67 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,11 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e3d2cc() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(1)).xx), v_1));
+  int4 res = int4(arg_0.Load(v_2, int(int(1))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3d2cc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.msl
index e649c9b..ae954ca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_e3d2cc(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), 1);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.msl
index 5010ed3..c7d0f30 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e3d2cc(texture2d_ms<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.spvasm
index 510f877..b6b6cd9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e3d2cc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e3d2cc = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Sample %int_1
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageFetch %v4int %20 %31 Sample %int_1
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_e3d2cc
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_e3d2cc
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_e3d2cc
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_e3d2cc
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_e3d2cc
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_e3d2cc
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.glsl
index de94f0e..bb9bb40 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_e4051a() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_e4051a() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
index 03cb335..e32db7b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e4051a() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
index 03cb335..e32db7b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e4051a() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.msl
index bc8ed4e..9fd36cf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_e4051a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.msl
index 6ad10c6..2cec668 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_e4051a(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)));
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.spvasm
index 5e1de50..129489b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e4051a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,32 +39,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_e4051a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4float %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4float %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_e4051a
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4float %textureLoad_e4051a
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_e4051a
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_e4051a
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.glsl
index eaaa0e4..f8d1d72 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_e57e92() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1))).zyxw;
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2))).zyxw;
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_e57e92() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1))).zyxw;
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  ivec2 v_3 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e57e92() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1))).zyxw;
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
index cf43bc4..3e09156 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e57e92() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e57e92();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
index cf43bc4..3e09156 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e57e92() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e57e92();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.msl
index 83465d9..546d830 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_e57e92(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.msl
index b77b6cd..9798160 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e57e92(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.spvasm
index 844b2c6..05c31d2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e57e92.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,67 +57,75 @@
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %59 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e57e92 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %19 = OpBitcast %uint %int_1
-         %23 = OpCompositeConstruct %v3uint %24 %19
-         %27 = OpImageRead %v4float %17 %23 None
-         %28 = OpVectorShuffle %v4float %27 %27 2 1 0 3
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpExtInst %v2uint %28 UMin %33 %32
+         %35 = OpCompositeConstruct %v3uint %34 %27
+         %36 = OpImageRead %v4float %17 %35 None
+         %37 = OpVectorShuffle %v4float %36 %36 2 1 0 3
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_e57e92
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_e57e92
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_e57e92
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_e57e92
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_e57e92
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %63 = OpFunctionCall %v4float %textureLoad_e57e92
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %43
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4float %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.glsl
index 9fefa62..e178d25 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_e59fdf() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_e59fdf() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_e59fdf() {
-  uvec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
index eeaeaf6..16f07cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_e59fdf() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e59fdf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
index eeaeaf6..16f07cd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_e59fdf() {
-  uint4 res = uint4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e59fdf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.msl
index 42c647c..a43fd08 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_e59fdf(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.msl
index 4b3a7f0..c8b57d1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_e59fdf(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  uint4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.spvasm
index 92d6bf3..6a5ba38 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e59fdf.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
          %18 = OpTypeFunction %v4uint
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e59fdf = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpExtInst %v3uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_e59fdf
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_e59fdf
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_e59fdf
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_e59fdf
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_e59fdf
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_e59fdf
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.glsl
index 1fbefab..670816e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_e65916() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_e65916() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e65916() {
-  ivec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
index 8113b52..3231112 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e65916() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e65916();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
index 8113b52..3231112 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e65916() {
-  int4 res = int4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e65916();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.msl
index ba6639a..578dfc5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_e65916(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.msl
index d8c4051..fa5a432 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e65916(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(int3(1)));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.spvasm
index 527363b..76bde5f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e65916.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +60,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %28 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e65916 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpBitcast %v3uint %28
+         %31 = OpExtInst %v3uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_e65916
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_e65916
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_e65916
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_e65916
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_e65916
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_e65916
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.glsl
index ecf3d48..e1e94b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e893d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e893d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e893d7() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
index 5f94dd6..813bf34 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e893d7() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e893d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
index 5f94dd6..813bf34 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e893d7() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e893d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.msl
index 25d6dfd..cc87b4e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_e893d7(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.msl
index 606cba2..f54cf22 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e893d7(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.spvasm
index 2c4c3f8..301065c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e893d7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v2int %int_1 %int_1
+         %25 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e893d7 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpBitcast %v2uint %25
+         %29 = OpExtInst %v2uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_e893d7
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_e893d7
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_e893d7
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_e893d7
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_e893d7
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_e893d7
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.glsl
index 9caaabd..06c4790 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e92dd0() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e92dd0() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e92dd0() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
index 9e931d4..c750611 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e92dd0() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e92dd0();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
index 9e931d4..c750611 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e92dd0() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e92dd0();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.msl
index 74cfdd0..7bfdfcb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_e92dd0(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.msl
index 3a693a9..64cf7bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_e92dd0(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1u));
+  float4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.spvasm
index 407dc24..ce8f6ae 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e92dd0.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 54
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,56 +61,59 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %38 = OpTypeFunction %VertexOutput
+         %42 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %42 = OpConstantNull %VertexOutput
-         %44 = OpConstantNull %v4float
+         %46 = OpConstantNull %VertexOutput
+         %48 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e92dd0 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %uint_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpExtInst %uint %23 UMin %uint_1 %20
+         %24 = OpImageRead %v4float %17 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_e92dd0
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_e92dd0
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_e92dd0
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_e92dd0
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %38
-         %39 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %42
-         %43 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %43 %44 None
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %46 = OpFunctionCall %v4float %textureLoad_e92dd0
-               OpStore %45 %46 None
-         %47 = OpLoad %VertexOutput %out None
-               OpReturnValue %47
+%vertex_main_inner = OpFunction %VertexOutput None %42
+         %43 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %46
+         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %47 %48 None
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %50 = OpFunctionCall %v4float %textureLoad_e92dd0
+               OpStore %49 %50 None
+         %51 = OpLoad %VertexOutput %out None
+               OpReturnValue %51
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %49 = OpLabel
-         %50 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %51 = OpCompositeExtract %v4float %50 0
-               OpStore %vertex_main_position_Output %51 None
-         %52 = OpCompositeExtract %v4float %50 1
-               OpStore %vertex_main_loc0_Output %52 None
+%vertex_main = OpFunction %void None %30
+         %53 = OpLabel
+         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %55 = OpCompositeExtract %v4float %54 0
+               OpStore %vertex_main_position_Output %55 None
+         %56 = OpCompositeExtract %v4float %54 1
+               OpStore %vertex_main_loc0_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
index a19bc58..b15abb2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_e9eb65() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
index a19bc58..b15abb2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_e9eb65() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.msl
index 0dd3a53..fceb77d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_e9eb65(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.msl
index 6d67f59..17975d4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_e9eb65(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.spvasm
index 5300221..ee4de7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/e9eb65.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,47 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %18 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_e9eb65 = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %uint %int_1
-         %17 = OpCompositeConstruct %v3uint %18 %13
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %18 %16
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpExtInst %v2uint %22 UMin %27 %26
+         %29 = OpCompositeConstruct %v3uint %28 %21
+         %30 = OpImageRead %v4uint %12 %29 None
+               OpStore %res %30
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_e9eb65
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_e9eb65
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_e9eb65
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_e9eb65
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.glsl
index 36c1b8e..7a9aae0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_ea2abd() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_ea2abd() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_ea2abd() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
index 7d6f513..1412e54 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ea2abd() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ea2abd();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
index 7d6f513..1412e54 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ea2abd() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ea2abd();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.msl
index 1ede403..41d22e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_ea2abd(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.msl
index d8079cf..c6d61d8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_ea2abd(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.spvasm
index 3258a79..4dbcdf3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ea2abd.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ea2abd = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_ea2abd
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_ea2abd
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_ea2abd
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_ea2abd
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_ea2abd
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_ea2abd
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.glsl
index 9d996f6..84cf8e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_eb573b() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_eb573b() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_eb573b() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
index 252a1e0..31eac9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_eb573b() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eb573b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
index 252a1e0..31eac9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_eb573b() {
-  int4 res = int4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eb573b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.msl
index 2f34421..00b2e18 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_eb573b(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.msl
index 3a1e110..d0ca45c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_eb573b(texture2d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.spvasm
index d888325..6f5d05a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/eb573b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %28 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_eb573b = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageRead %v4int %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_eb573b
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_eb573b
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_eb573b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_eb573b
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_eb573b
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %60 = OpFunctionCall %v4int %textureLoad_eb573b
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4int %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.glsl
index 2443c57..020641e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_ebfb92() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_ebfb92() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ebfb92() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
index 0e728d4..18c60bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ebfb92() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ebfb92();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
index 0e728d4..18c60bd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ebfb92() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ebfb92();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.msl
index 5dded07..b503726 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_ebfb92(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.msl
index 3a3721e..3c7c618 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ebfb92(texture2d<uint, access::sample> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.spvasm
index 0f5e138..824da08 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ebfb92.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
-     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ebfb92 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Lod %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySizeLod %v2uint %20 %24
+         %28 = OpISub %v2uint %26 %29
+         %30 = OpBitcast %v2uint %31
+         %35 = OpExtInst %v2uint %25 UMin %30 %28
+         %36 = OpImageFetch %v4uint %20 %35 Lod %24
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_ebfb92
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_ebfb92
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_ebfb92
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_ebfb92
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_ebfb92
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_ebfb92
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.glsl
index b0a37c2..476a445 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_ecc823() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_ecc823() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ecc823() {
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
index dca0c8a..3ca5295 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ecc823() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ecc823();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
index dca0c8a..3ca5295 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ecc823() {
-  uint4 res = uint4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ecc823();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.msl
index cd4e4a6..236e1cf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_ecc823(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.msl
index b6ddc40..fb75723 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ecc823(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.spvasm
index 30cd868..252a371 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ecc823.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ecc823 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpBitcast %v2uint %27
+         %31 = OpExtInst %v2uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_ecc823
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_ecc823
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_ecc823
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_ecc823
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_ecc823
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_ecc823
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.glsl
index 83b5a53..abb273d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_ed55a8() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2DArray arg_0;
 ivec4 textureLoad_ed55a8() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
index edf8456..55af0f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ed55a8() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
index edf8456..55af0f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ed55a8() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.msl
index 5287001..23f3867 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 int4 textureLoad_ed55a8(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.msl
index 6fc0373..91d3907 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ed55a8(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.spvasm
index 3d06669..b263402 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ed55a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -35,38 +37,48 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %27 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_ed55a8 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %13
-         %21 = OpImageRead %v4int %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4int %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpBitcast %v2uint %27
+         %30 = OpExtInst %v2uint %20 UMin %26 %24
+         %31 = OpCompositeConstruct %v3uint %30 %19
+         %32 = OpImageRead %v4int %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_ed55a8
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_ed55a8
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_ed55a8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_ed55a8
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.glsl
index 2adc3be..1511aad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_ee33c5() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_ee33c5() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_ee33c5() {
-  ivec4 res = imageLoad(arg_0, ivec3(uvec3(1u)));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(1u), (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
index d9a73b2..858e7f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ee33c5() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ee33c5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
index d9a73b2..858e7f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ee33c5() {
-  int4 res = int4(arg_0.Load(int4(int3((1u).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min((1u).xxx, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ee33c5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.msl
index 70ff837..ca6526c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_ee33c5(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(1u), (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.msl
index d2f0a4c..d6a5a14 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_ee33c5(texture3d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint3(uint3(1u)));
+  int4 res = tint_symbol_1.read(uint3(min(uint3(1u), (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.spvasm
index 6e29db7..9c9cff3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ee33c5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,60 +62,63 @@
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+         %25 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ee33c5 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpISub %v3uint %21 %25
+         %27 = OpExtInst %v3uint %28 UMin %25 %24
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_ee33c5
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4int %textureLoad_ee33c5
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_ee33c5
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_ee33c5
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %52 = OpFunctionCall %v4int %textureLoad_ee33c5
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_ee33c5
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4int %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.glsl
index b49623a..560580f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.glsl
@@ -8,8 +8,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_eecf7d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +25,10 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_eecf7d() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +46,10 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_eecf7d() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_1 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_2 = ivec2(min(uvec2(ivec2(1)), v_1));
+  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
index d9518f0..f78863e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_eecf7d() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eecf7d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
index d9518f0..f78863e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_eecf7d() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eecf7d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.msl
index 6f948e6..1faa719 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_eecf7d(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.msl
index 5ccfc82..afebadc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_eecf7d(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.spvasm
index c22ffaa..c5a2c3c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/eecf7d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,67 +60,77 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %26 = OpConstantComposite %v2int %int_1 %int_1
+         %34 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %47 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_eecf7d = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpBitcast %int %uint_1
-         %25 = OpCompositeConstruct %v3int %26 %22
-         %29 = OpImageRead %v4uint %20 %25 None
-               OpStore %res %29
-         %32 = OpLoad %v4uint %res None
-               OpReturnValue %32
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpExtInst %uint %27 UMin %uint_1 %24
+         %28 = OpImageQuerySize %v3uint %20
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %31 = OpISub %v2uint %29 %32
+         %33 = OpBitcast %v2uint %34
+         %38 = OpExtInst %v2uint %27 UMin %33 %31
+         %39 = OpCompositeConstruct %v3uint %38 %26
+         %40 = OpImageRead %v4uint %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4uint %textureLoad_eecf7d
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_eecf7d
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_eecf7d
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_eecf7d
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_eecf7d
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_eecf7d
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.glsl
index e81bd4b..4c3861a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_ef2ec3() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_ef2ec3() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
index aed7f4f..e011d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ef2ec3() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
index aed7f4f..e011d89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ef2ec3() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.msl
index 6c30d74..0a089b6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_ef2ec3(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.msl
index 4ef1736..6358dea 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_ef2ec3(texture1d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint(1u));
+  int4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.spvasm
index f95ed5d..93552e3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ef2ec3.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,29 +41,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_ef2ec3 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4int %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4int %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4int %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4int %textureLoad_ef2ec3
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4int %textureLoad_ef2ec3
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4int %textureLoad_ef2ec3
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4int %textureLoad_ef2ec3
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.glsl
index 120b33f..c44e688 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_ef5405() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_ef5405() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ef5405() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
index 3cf1b59..1706c5d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ef5405() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ef5405();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
index 3cf1b59..1706c5d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ef5405() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ef5405();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.msl
index a266ad8..9475784 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_ef5405(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.msl
index d4de2c1e..db747fa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ef5405(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.spvasm
index 9c7d519..d9ff54d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ef5405.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,64 +60,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ef5405 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpBitcast %v3uint %27
+         %31 = OpExtInst %v3uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_ef5405
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_ef5405
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_ef5405
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_ef5405
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_ef5405
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_ef5405
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.glsl
index a6136df..29f55b3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_efa787() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_efa787() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_efa787() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
index 46e0db3..5dddffb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_efa787() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_efa787();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
index 46e0db3..5dddffb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_efa787() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_efa787();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.msl
index a35e5e9..8dc82bc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_efa787(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.msl
index 145f21f..a8ea85b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_efa787(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.spvasm
index 03480ad..3c0d982 100644
--- a/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/efa787.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_efa787 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_efa787
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_efa787
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_efa787
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_efa787
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_efa787
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_efa787
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
index f8eef06..ee5cb99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f0514a() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
index f8eef06..ee5cb99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f0514a() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.msl
index 7361e98..8962e45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_f0514a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.msl
index dfe6730..8a97f05 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f0514a(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.spvasm
index d35bee1..ad2987e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f0514a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,34 +36,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f0514a = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_f0514a
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_f0514a
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_f0514a
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.glsl
index 037c30c..3d8c258 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f06b69() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f06b69() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f06b69() {
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
index 951e563..31a2695 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f06b69() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f06b69();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
index 951e563..31a2695 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f06b69() {
-  int4 res = int4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f06b69();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.msl
index 239f36b..eec340a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_f06b69(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.msl
index 520c9a8..31adb92 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f06b69(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.spvasm
index 56843e5..19c1515 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f06b69.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f06b69 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %int_1 None
-               OpStore %res %21
-         %25 = OpLoad %v4int %res None
-               OpReturnValue %25
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %25 %23
+         %29 = OpImageRead %v4int %20 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4int %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4int %textureLoad_f06b69
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %31 %30 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %28
+%fragment_main = OpFunction %void None %35
          %36 = OpLabel
          %37 = OpFunctionCall %v4int %textureLoad_f06b69
          %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
+%compute_main = OpFunction %void None %35
          %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %51 = OpFunctionCall %v4int %textureLoad_f06b69
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %43 = OpFunctionCall %v4int %textureLoad_f06b69
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4int %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %56 = OpFunctionCall %v4int %textureLoad_f06b69
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4int %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.glsl
index 2694180..49efbad 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_f0abad() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 vec4 textureLoad_f0abad() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f0abad() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   vec4 res = texelFetch(arg_0, v, int(1));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
index 9f1f77d..0611e85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f0abad() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f0abad();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
index 9f1f77d..0611e85 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f0abad() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f0abad();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.msl
index d1ebb0e..3ac98c2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_f0abad(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.msl
index 505fd1a..63512c1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f0abad(texture2d_ms<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.spvasm
index bb7d61f..f882549 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f0abad.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,61 +58,64 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %50 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f0abad = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %int_1
-               OpStore %res %18
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageFetch %v4float %17 %24 Sample %int_1
+               OpStore %res %26
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f0abad
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_f0abad
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f0abad
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f0abad
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_f0abad
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %54 = OpFunctionCall %v4float %textureLoad_f0abad
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %34
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4float %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.glsl
index 21b7dac..c6f0ecb 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_f1c549() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_f1c549() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
index 9f22400..e569594 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f1c549() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
index 9f22400..e569594 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f1c549() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.msl
index 7aa8718..6a0f756 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_f1c549(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.msl
index b7b0c59..5e932f9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f1c549(texture3d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint3(int3(1)));
+  float4 res = tint_symbol.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.spvasm
index 376dcde..ec8d4ef 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f1c549.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %20 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f1c549 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpISub %v3uint %13 %17
+         %19 = OpBitcast %v3uint %20
+         %24 = OpExtInst %v3uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_f1c549
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_f1c549
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f1c549
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_f1c549
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.glsl
index de2cffa..d395f99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f2a7ff() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f2a7ff() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f2a7ff() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
index 737ce08..255b13e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f2a7ff() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f2a7ff();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
index 737ce08..255b13e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f2a7ff() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f2a7ff();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.msl
index 3f72f18..12364c3 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_f2a7ff(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.msl
index cd5374b..84558cc 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f2a7ff(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.spvasm
index 0c65455..78cc86bf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f2a7ff.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,59 +59,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f2a7ff = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_f2a7ff
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_f2a7ff
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_f2a7ff
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_f2a7ff
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_f2a7ff
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_f2a7ff
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.glsl
index 6897a2a..b1ed0f8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_f2bdd4() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, r8) uniform highp image2DArray arg_0;
 vec4 textureLoad_f2bdd4() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
index acb8a27..139cd06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f2bdd4() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
index acb8a27..139cd06 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f2bdd4() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.msl
index 2bc2560..da5bde8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_f2bdd4(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.msl
index 4608e34..e5fec5c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f2bdd4(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.spvasm
index 1664971..ed80d99 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f2bdd4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,35 +38,43 @@
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %16 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_f2bdd4 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3uint %16 %uint_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpExtInst %uint %20 UMin %uint_1 %17
+         %21 = OpImageQuerySize %v3uint %12
+         %22 = OpVectorShuffle %v2uint %21 %21 0 1
+         %24 = OpISub %v2uint %22 %25
+         %26 = OpExtInst %v2uint %20 UMin %25 %24
+         %27 = OpCompositeConstruct %v3uint %26 %19
+         %28 = OpImageRead %v4float %12 %27 None
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_f2bdd4
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_f2bdd4
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f2bdd4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f2bdd4
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
index 8149367..2311c13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_f2c311() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
index 8149367..2311c13 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<int4> arg_0 : register(u0, space1);
 int4 textureLoad_f2c311() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.msl
index b9a09b1..30c2c50 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 int4 textureLoad_f2c311(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.msl
index e18b704..7943a58 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f2c311(texture2d_array<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.spvasm
index 223980f..b259572 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f2c311.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,37 +35,50 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %15 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %27 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %29 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f2c311 = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpCompositeConstruct %v3int %15 %int_1
-         %18 = OpImageRead %v4int %12 %14 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %21 = OpExtInst %uint %22 UMin %19 %17
+         %23 = OpImageQuerySize %v3uint %12
+         %24 = OpVectorShuffle %v2uint %23 %23 0 1
+         %26 = OpISub %v2uint %24 %27
+         %28 = OpBitcast %v2uint %29
+         %31 = OpExtInst %v2uint %22 UMin %28 %26
+         %32 = OpCompositeConstruct %v3uint %31 %21
+         %33 = OpImageRead %v4int %12 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4int %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_f2c311
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_f2c311
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_f2c311
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_f2c311
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.glsl
index 05d30b3..85af2d0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.glsl
@@ -2,15 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_f348d9() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -18,15 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_f348d9() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  ivec3 v_2 = ivec3(v_1, int(1u));
-  vec4 res = texelFetch(arg_0, v_2, int(1));
+  uint v_2 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(1), v_3);
+  ivec2 v_5 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u))));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f348d9() {
-  ivec2 v = ivec2(uvec2(1u));
-  ivec3 v_1 = ivec3(v, int(1u));
-  vec4 res = texelFetch(arg_0, v_1, int(1));
+  uint v_1 = min(1u, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(1), v_2);
+  ivec2 v_4 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u))));
+  ivec3 v_5 = ivec3(v_4, int(v_1));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
index 09274e4..ab4e3b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f348d9() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f348d9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
index 09274e4..ab4e3b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,16 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f348d9() {
-  int2 v = int2((1u).xx);
-  int v_1 = int(1u);
-  float4 res = float4(arg_0.Load(int4(v, v_1, int(int(1)))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(int(1)), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int2 v_4 = int2(min((1u).xx, (v_3.xy - (1u).xx)));
+  int v_5 = int(min(1u, (v.z - 1u)));
+  float4 res = float4(arg_0.Load(int4(v_4, v_5, int(v_2))));
   return res;
 }
 
@@ -31,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f348d9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.msl
index 5225f97..b34ad45 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_f348d9(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u, 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)), v);
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.msl
index a3ec4f1..00122b1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 float4 textureLoad_f348d9(texture2d_array<float, access::sample> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u, 1);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.spvasm
index 951c4e7..88f12b29 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f348d9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,76 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f348d9 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %int_1
-               OpStore %res %24
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQueryLevels %uint %17
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %26 UMin %29 %28
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpExtInst %v2uint %26 UMin %37 %36
+         %39 = OpCompositeConstruct %v3uint %38 %25
+         %40 = OpImageFetch %v4float %17 %39 Lod %32
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_f348d9
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f348d9
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_f348d9
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_f348d9
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_f348d9
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_f348d9
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %46
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.glsl
index 11ab06c..1d02be1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f35ac7() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f35ac7() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f35ac7() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
index 29401e3..029fd30 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f35ac7() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f35ac7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
index 29401e3..029fd30 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f35ac7() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f35ac7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.msl
index 2b8d297..a5e8ab4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_f35ac7(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.msl
index 0fa3688..e7bf10b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_f35ac7(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.spvasm
index 696a957..461bc2f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f35ac7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f35ac7 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %uint_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageRead %v4int %20 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4int %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_f35ac7
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_f35ac7
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_f35ac7
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_f35ac7
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_f35ac7
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %54 = OpFunctionCall %v4int %textureLoad_f35ac7
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4int %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.glsl
index dcc665a..a73f4ff 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_f379e2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_f379e2() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba8) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f379e2() {
-  ivec2 v = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
index d865a5d..3ad78d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f379e2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f379e2();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
index d865a5d..3ad78d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f379e2() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f379e2();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.msl
index 07c366f..6da861d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float4 textureLoad_f379e2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.msl
index 93a9f5e..d233e56 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f379e2(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.spvasm
index d1af638..8f57a3a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f379e2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,66 +56,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %35 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f379e2 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpBitcast %uint %int_1
+         %27 = OpExtInst %uint %28 UMin %24 %22
+         %29 = OpImageQuerySize %v3uint %17
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %35
+         %37 = OpExtInst %v2uint %28 UMin %34 %32
+         %38 = OpCompositeConstruct %v3uint %37 %27
+         %39 = OpImageRead %v4float %17 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f379e2
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_f379e2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_f379e2
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_f379e2
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_f379e2
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_f379e2
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.glsl
index 42c53ff..458da60 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_f56e6f() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_f56e6f() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_f56e6f() {
-  uvec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
index 1e51ec0..6ff836a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_f56e6f() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f56e6f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
index 1e51ec0..6ff836a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_f56e6f() {
-  uint4 res = uint4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f56e6f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.msl
index b504b5e..d6d7212 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 uint4 textureLoad_f56e6f(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.msl
index 6f7b410..a958fdf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_f56e6f(texture3d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint3(int3(1)));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.spvasm
index ac6ce73..3199835 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f56e6f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,64 +59,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %27 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f56e6f = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpISub %v3uint %21 %24
+         %26 = OpBitcast %v3uint %27
+         %31 = OpExtInst %v3uint %32 UMin %26 %23
+         %33 = OpImageRead %v4uint %20 %31 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_f56e6f
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_f56e6f
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_f56e6f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_f56e6f
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_f56e6f
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %60 = OpFunctionCall %v4uint %textureLoad_f56e6f
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4uint %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.glsl
index 12a2c63..139bae7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f5aee2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f5aee2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f5aee2() {
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
index 451919f..de5de0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f5aee2() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f5aee2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
index 451919f..de5de0c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f5aee2() {
-  float4 res = float4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f5aee2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.msl
index 44724c6..8825696 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_f5aee2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.msl
index df9c0fb..59c0cf1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f5aee2(texture2d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.spvasm
index 89d610d..3802c4d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f5aee2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 60
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,59 +60,62 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %40 = OpTypeFunction %VertexOutput
+         %44 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %44 = OpConstantNull %VertexOutput
-         %46 = OpConstantNull %v4float
+         %48 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f5aee2 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageRead %v4float %17 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_f5aee2
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_f5aee2
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_f5aee2
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_f5aee2
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %40
-         %41 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %44
-         %45 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %45 %46 None
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_f5aee2
-               OpStore %47 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+%vertex_main_inner = OpFunction %VertexOutput None %44
+         %45 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %48
+         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %49 %50 None
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %52 = OpFunctionCall %v4float %textureLoad_f5aee2
+               OpStore %51 %52 None
+         %53 = OpLoad %VertexOutput %out None
+               OpReturnValue %53
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main = OpFunction %void None %32
+         %55 = OpLabel
+         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %57 = OpCompositeExtract %v4float %56 0
+               OpStore %vertex_main_position_Output %57 None
+         %58 = OpCompositeExtract %v4float %56 1
+               OpStore %vertex_main_loc0_Output %58 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
index cc18cef..d63e57a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f5fbc6() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
index cc18cef..d63e57a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f5fbc6() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.msl
index 4a3397c..45228a6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_f5fbc6(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.msl
index 290f9b6..a64d5c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f5fbc6(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.spvasm
index edaa4ca..f01fd82 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f5fbc6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,38 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f5fbc6 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_f5fbc6
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f5fbc6
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_f5fbc6
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f5fbc6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.glsl
index fbf91ef..c496eca 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f74bd8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f74bd8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f74bd8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
index 7475938..474a1c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f74bd8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f74bd8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
index 7475938..474a1c8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f74bd8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f74bd8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.msl
index 3699c53..b5e3e89 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_f74bd8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.msl
index 01b0c26..8c78dcf 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f74bd8(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.spvasm
index fc00973..cffc1ba 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f74bd8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,64 +57,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f74bd8 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_f74bd8
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_f74bd8
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_f74bd8
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_f74bd8
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_f74bd8
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_f74bd8
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
index 39290b9..2403f5a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f7f3bc() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
index 39290b9..2403f5a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f7f3bc() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.msl
index 9d0086d..dfb06a2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_f7f3bc(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.msl
index 84739ca..26188a9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f7f3bc(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1));
+  float4 res = tint_symbol.read(uint(tint_clamp(1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.spvasm
index e86725a..700a84a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f3bc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,34 +36,39 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f7f3bc = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %int_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpBitcast %uint %int_1
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpImageRead %v4float %12 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_f7f3bc
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %21
+%fragment_main = OpFunction %void None %28
          %29 = OpLabel
          %30 = OpFunctionCall %v4float %textureLoad_f7f3bc
          %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_f7f3bc
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.glsl
index 04b4f6b..44da5d9 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.glsl
@@ -8,8 +8,9 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_f7f936() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 void main() {
@@ -23,8 +24,9 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 vec4 textureLoad_f7f936() {
-  ivec2 v_1 = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1u)));
+  uint v_1 = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_2 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +44,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f7f936() {
-  ivec2 v = ivec2(uvec2(1u));
-  vec4 res = imageLoad(arg_0, ivec3(v, int(1u)));
+  uint v = min(1u, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
index c4b25fb..fdb0394 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f7f936() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f7f936();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
index c4b25fb..fdb0394 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,12 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f7f936() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min((1u).xx, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_2, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f7f936();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.msl
index 805bb89..b5f4c07 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float4 textureLoad_f7f936(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.msl
index 394c395..c90b938 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f7f936(texture2d_array<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint2(uint2(1u)), 1u);
+  float4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(1u, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.spvasm
index 334cfcb..807fb0e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f7f936.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,62 +58,70 @@
          %15 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
      %v3uint = OpTypeVector %uint 3
-     %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %21 = OpConstantComposite %v2uint %uint_1 %uint_1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %55 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f7f936 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %20 = OpCompositeConstruct %v3uint %21 %uint_1
-         %24 = OpImageRead %v4float %17 %20 None
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpCompositeExtract %uint %18 2
+         %22 = OpISub %uint %21 %uint_1
+         %24 = OpExtInst %uint %25 UMin %uint_1 %22
+         %26 = OpImageQuerySize %v3uint %17
+         %27 = OpVectorShuffle %v2uint %26 %26 0 1
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpExtInst %v2uint %25 UMin %30 %29
+         %32 = OpCompositeConstruct %v3uint %31 %24
+         %33 = OpImageRead %v4float %17 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f7f936
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_f7f936
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f7f936
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_f7f936
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_f7f936
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %59 = OpFunctionCall %v4float %textureLoad_f7f936
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %39
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4float %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.glsl
index 95887a6..28c8b7f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_f81792() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2DArray arg_0;
 vec4 textureLoad_f81792() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
index cdb9e03..8880c7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f81792() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
index cdb9e03..8880c7a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f81792() {
-  int2 v = int2((int(1)).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.msl
index c5084f0..996a055 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.ir.msl
@@ -7,7 +7,9 @@
 };
 
 float4 textureLoad_f81792(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.msl
index e3c1700..d28a051 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f81792(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)), 1);
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.spvasm
index 64427cd..f9a5155 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f81792.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,38 +35,51 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %30 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f81792 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %15 = OpCompositeConstruct %v3int %16 %int_1
-         %19 = OpImageRead %v4float %12 %15 None
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpBitcast %v2uint %30
+         %32 = OpExtInst %v2uint %23 UMin %29 %27
+         %33 = OpCompositeConstruct %v3uint %32 %22
+         %34 = OpImageRead %v4float %12 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_f81792
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f81792
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_f81792
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f81792
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
index 7810775..2430d48 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f82eb2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
index 7810775..2430d48 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f82eb2() {
-  float4 res = float4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.msl
index 1b4b974..22c71dd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 float4 textureLoad_f82eb2(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(1u);
+  float4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.msl
index da4ca1a..4be7cf8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float4 textureLoad_f82eb2(texture1d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint(1u));
+  float4 res = tint_symbol.read(uint(min(1u, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.spvasm
index 8f634d3..f8549f0 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f82eb2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,29 +40,32 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_f82eb2 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %uint_1 None
-               OpStore %res %13
-         %18 = OpLoad %v4float %res None
-               OpReturnValue %18
+         %13 = OpImageQuerySize %uint %12
+         %15 = OpISub %uint %13 %uint_1
+         %17 = OpExtInst %uint %18 UMin %uint_1 %15
+         %19 = OpImageRead %v4float %12 %17 None
+               OpStore %res %19
+         %22 = OpLoad %v4float %res None
+               OpReturnValue %22
                OpFunctionEnd
-%fragment_main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpFunctionCall %v4float %textureLoad_f82eb2
-         %24 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %24 %23 None
+%fragment_main = OpFunction %void None %25
+         %26 = OpLabel
+         %27 = OpFunctionCall %v4float %textureLoad_f82eb2
+         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %28 %27 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %21
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_f82eb2
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%compute_main = OpFunction %void None %25
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_f82eb2
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.glsl
index 80c4bdb..e99b2e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.glsl
@@ -2,14 +2,25 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_f85291() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -17,14 +28,25 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_f85291() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v_1, int(1u));
+  uint v_2 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +56,26 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f85291() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = texelFetch(arg_0, v, int(1u));
+  uint v_1 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +85,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
index a1ea0c7..7dcd47d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f85291() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f85291();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
index a1ea0c7..7dcd47d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f85291() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int3(v, int(1u))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(1u, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  int4 res = int4(arg_0.Load(int3(v_3, int(min(1u, (v.z - 1u))))));
   return res;
 }
 
@@ -30,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f85291();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.msl
index 988eb8d..326564a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 int4 textureLoad_f85291(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.msl
index c8171c8..f2e1b61 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f85291(texture2d<int, access::sample> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.spvasm
index 8ecfe4f..e97570a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f85291.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,64 +58,73 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v2int = OpTypeVector %int 2
-      %int_1 = OpConstant %int 1
-         %22 = OpConstantComposite %v2int %int_1 %int_1
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %30 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+      %int_1 = OpConstant %int 1
+         %32 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f85291 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4int %20 %22 Lod %uint_1
-               OpStore %res %21
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQueryLevels %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageQuerySizeLod %v2uint %20 %25
+         %29 = OpISub %v2uint %27 %30
+         %31 = OpBitcast %v2uint %32
+         %35 = OpExtInst %v2uint %26 UMin %31 %29
+         %36 = OpImageFetch %v4int %20 %35 Lod %25
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_f85291
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_f85291
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_f85291
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_f85291
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_f85291
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_f85291
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.glsl
index 8ab3c42..d8839c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f8a2e8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1))).zyxw;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1))).zyxw;
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f8a2e8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1))).zyxw;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f8a2e8() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1))).zyxw;
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
index 14eb36f..d72cafe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f8a2e8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f8a2e8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
index 14eb36f..d72cafe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f8a2e8() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f8a2e8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.msl
index 98fdf21..30a8dce 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_f8a2e8(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.msl
index dd41de9..3e2f1e4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f8a2e8(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.spvasm
index e318c5b..a0311ee 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f8a2e8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,65 +56,71 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f8a2e8 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-         %23 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+         %32 = OpVectorShuffle %v4float %31 %31 2 1 0 3
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_f8a2e8
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_f8a2e8
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f8a2e8
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_f8a2e8
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_f8a2e8
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_f8a2e8
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.glsl
index 1550acc..8c4864b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_f92c2d() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_f92c2d() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1)));
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(ivec2(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
index b2817f6..3866598 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f92c2d() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
index b2817f6..3866598 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f92c2d() {
-  float4 res = float4(arg_0.Load(int3(int2((int(1)).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2((int(1)).xx), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.msl
index 786f855..3eaf432 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_f92c2d(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(int2(1)));
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.msl
index e2f1757..765d84a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f92c2d(texture2d<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(int2(1)));
+  float4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.spvasm
index f606be8..6e71505 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f92c2d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,36 +35,43 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %14 = OpConstantComposite %v2int %int_1 %int_1
+         %20 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f92c2d = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4float %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4float %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpBitcast %v2uint %20
+         %24 = OpExtInst %v2uint %25 UMin %19 %16
+         %26 = OpImageRead %v4float %12 %24 None
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4float %textureLoad_f92c2d
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %32
+         %33 = OpLabel
+         %34 = OpFunctionCall %v4float %textureLoad_f92c2d
+         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f92c2d
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_f92c2d
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.glsl
index 69e2d00..95efb9f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f9eaaf() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f9eaaf() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f9eaaf() {
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(1u, 0u)));
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(1u, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
index dd0305d..e189a15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f9eaaf() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f9eaaf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
index dd0305d..e189a15 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f9eaaf() {
-  int4 res = int4(arg_0.Load(int2(int(1u), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(1u, (v - 1u))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f9eaaf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.msl
index 79f76f4..c710711 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 int4 textureLoad_f9eaaf(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(1u);
+  int4 res = tint_module_vars.arg_0.read(min(1u, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.msl
index 4240185..05df0aa 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_f9eaaf(texture1d<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint(1u));
+  int4 res = tint_symbol_1.read(uint(min(1u, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.spvasm
index 06d9a85..5e8f454 100644
--- a/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/f9eaaf.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,57 +64,60 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f9eaaf = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4int %20 %uint_1 None
-               OpStore %res %21
-         %26 = OpLoad %v4int %res None
-               OpReturnValue %26
+         %21 = OpImageQuerySize %uint %20
+         %23 = OpISub %uint %21 %uint_1
+         %25 = OpExtInst %uint %26 UMin %uint_1 %23
+         %27 = OpImageRead %v4int %20 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4int %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_f9eaaf
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_f9eaaf
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4int %textureLoad_f9eaaf
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4int %textureLoad_f9eaaf
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %50 = OpFunctionCall %v4int %textureLoad_f9eaaf
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %54 = OpFunctionCall %v4int %textureLoad_f9eaaf
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4int %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4int %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
index 0914058..40093f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_fc47ff() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
index 0914058..40093f1 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_fc47ff() {
-  int4 res = int4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.msl
index 853c8e5..38d84de 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.ir.msl
@@ -7,7 +7,7 @@
 };
 
 int4 textureLoad_fc47ff(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.msl
index 232f539..736bc55 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 int4 textureLoad_fc47ff(texture2d<int, access::read_write> tint_symbol) {
-  int4 res = tint_symbol.read(uint2(uint2(1u)));
+  int4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.spvasm
index ec44581..a1b9afd 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fc47ff.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -36,32 +38,35 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %14 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %17 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_fc47ff = OpFunction %v4int None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %12 = OpLoad %8 %arg_0 None
-         %13 = OpImageRead %v4int %12 %14 None
-               OpStore %res %13
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %13 = OpImageQuerySize %v2uint %12
+         %16 = OpISub %v2uint %13 %17
+         %19 = OpExtInst %v2uint %20 UMin %17 %16
+         %21 = OpImageRead %v4int %12 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4int %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_fc47ff
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4int %textureLoad_fc47ff
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4int %textureLoad_fc47ff
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4int %textureLoad_fc47ff
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.glsl
index ee13a6d..5bf1206 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_fc6d36() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 ivec4 textureLoad_fc6d36() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_fc6d36() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
index d16d735..87108d7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_fc6d36() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fc6d36();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
index d16d735..87108d7 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<int4> arg_0 : register(t0, space1);
 int4 textureLoad_fc6d36() {
-  int2 v = int2((int(1)).xx);
-  int4 res = int4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fc6d36();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.msl
index 900895a..ca670fe 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 int4 textureLoad_fc6d36(tint_module_vars_struct tint_module_vars) {
-  int4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.msl
index e71f657..5db775c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_fc6d36(texture2d_array<int, access::read> tint_symbol_1) {
-  int4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.spvasm
index dcc8eba..8e038a4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fc6d36.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4int
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
-         %23 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fc6d36 = OpFunction %v4int None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4int Function
          %20 = OpLoad %8 %arg_0 None
-         %22 = OpCompositeConstruct %v3int %23 %int_1
-         %26 = OpImageRead %v4int %20 %22 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v3uint %20
+         %24 = OpCompositeExtract %uint %21 2
+         %25 = OpISub %uint %24 %uint_1
+         %27 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %27 %25
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4int %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4int %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_fc6d36
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_fc6d36
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_fc6d36
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4int %textureLoad_fc6d36
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %68 = OpFunctionCall %v4int %textureLoad_fc6d36
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4int %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.glsl
index ccc2601..9f0f786 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_fcd23d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v_1, int(1)).x;
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp sampler2DMS arg_0;
 float textureLoad_fcd23d() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v_1, int(1)).x;
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp sampler2DMS arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_fcd23d() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   float res = texelFetch(arg_0, v, int(1)).x;
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
index 262d86a..32ad8e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_fcd23d() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(v, int(int(1))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float res = arg_0.Load(v_1, int(int(1))).x;
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fcd23d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
index 262d86a..32ad8e6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<float4> arg_0 : register(t0, space1);
 float textureLoad_fcd23d() {
-  int2 v = int2((1u).xx);
-  float res = arg_0.Load(v, int(int(1))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  float res = arg_0.Load(v_1, int(int(1))).x;
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fcd23d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.msl
index 91eb83b..94c285e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 float textureLoad_fcd23d(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  float res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.msl
index bd79895..aa35321 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 float textureLoad_fcd23d(depth2d_ms<float, access::read> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  float res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.spvasm
index 49edfde..7652d94 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fcd23d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -56,63 +58,66 @@
        %uint = OpTypeInt 32 0
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fcd23d = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %18 = OpImageFetch %v4float %17 %19 Sample %int_1
-         %25 = OpCompositeExtract %float %18 0
-               OpStore %res %25
-         %28 = OpLoad %float %res None
-               OpReturnValue %28
+         %18 = OpImageQuerySize %v2uint %17
+         %21 = OpISub %v2uint %18 %22
+         %24 = OpExtInst %v2uint %25 UMin %22 %21
+         %26 = OpImageFetch %v4float %17 %24 Sample %int_1
+         %29 = OpCompositeExtract %float %26 0
+               OpStore %res %29
+         %32 = OpLoad %float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %float %textureLoad_fcd23d
-         %34 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %float %textureLoad_fcd23d
+         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_fcd23d
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %float %textureLoad_fcd23d
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %52 = OpFunctionCall %float %textureLoad_fcd23d
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %56 = OpFunctionCall %float %textureLoad_fcd23d
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.glsl
index 08a773f..7b25798 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_fd6442() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -22,7 +22,7 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_fd6442() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +40,7 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_fd6442() {
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(1u)));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(1u), (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
index f9d9369..9e87675 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fd6442() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fd6442();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
index f9d9369..9e87675 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,9 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fd6442() {
-  uint4 res = uint4(arg_0.Load(int3(int2((1u).xx), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min((1u).xx, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -29,13 +31,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fd6442();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.msl
index c1dd1e8..567b5e5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_fd6442(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.msl
index 5558b5d..886ac46 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_fd6442(texture2d<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)));
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.spvasm
index 2675f05..d962e7b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fd6442.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,60 +61,63 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fd6442 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageRead %v4uint %20 %22 None
-               OpStore %res %21
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageRead %v4uint %20 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_fd6442
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_fd6442
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_fd6442
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_fd6442
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %51 = OpFunctionCall %v4uint %textureLoad_fd6442
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %55 = OpFunctionCall %v4uint %textureLoad_fd6442
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
index e3429b1..72489d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_fd9606() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
index e3429b1..72489d6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<float4> arg_0 : register(u0, space1);
 float4 textureLoad_fd9606() {
-  int2 v = int2((1u).xx);
-  float4 res = float4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min((1u).xx, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.msl
index 16fbd74..461a66f 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 float4 textureLoad_fd9606(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.msl
index 84ad6cf..586ea02 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_fd9606(texture2d_array<float, access::read_write> tint_symbol) {
-  float4 res = tint_symbol.read(uint2(uint2(1u)), 1);
+  float4 res = tint_symbol.read(uint2(min(uint2(1u), (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(1, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.spvasm
index c6b5131..59c9ea5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fd9606.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -34,39 +36,47 @@
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4float
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
-     %uint_1 = OpConstant %uint 1
-         %19 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %28 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_fd9606 = OpFunction %v4float None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %uint %int_1
-         %18 = OpCompositeConstruct %v3uint %19 %14
-         %22 = OpImageRead %v4float %12 %18 None
-               OpStore %res %22
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %13 = OpImageQuerySize %v3uint %12
+         %16 = OpCompositeExtract %uint %13 2
+         %17 = OpISub %uint %16 %uint_1
+         %19 = OpBitcast %uint %int_1
+         %22 = OpExtInst %uint %23 UMin %19 %17
+         %24 = OpImageQuerySize %v3uint %12
+         %25 = OpVectorShuffle %v2uint %24 %24 0 1
+         %27 = OpISub %v2uint %25 %28
+         %29 = OpExtInst %v2uint %23 UMin %28 %27
+         %30 = OpCompositeConstruct %v3uint %29 %22
+         %31 = OpImageRead %v4float %12 %30 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_fd9606
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_fd9606
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_fd9606
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_fd9606
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.glsl
index b29ec32..937693d 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.glsl
@@ -8,8 +8,11 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_fdebd0() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 void main() {
@@ -23,8 +26,11 @@
 } v;
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 uvec4 textureLoad_fdebd0() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(1)));
+  uint v_1 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(ivec2(1)), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -42,8 +48,11 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_fdebd0() {
-  ivec2 v = ivec2(ivec2(1));
-  uvec4 res = imageLoad(arg_0, ivec3(v, int(1)));
+  uint v = (uint(imageSize(arg_0).z) - 1u);
+  uint v_1 = min(uint(1), v);
+  uvec2 v_2 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(ivec2(1)), v_2));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +62,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_1 = vertex_main_inner();
-  gl_Position = v_1.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_1.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
index ccf7fc0..acabe51 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fdebd0() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fdebd0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
index ccf7fc0..acabe51 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,14 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fdebd0() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(int(1)), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2((int(1)).xx), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -30,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fdebd0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.msl
index 8bfc868..46dba7c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 uint4 textureLoad_fdebd0(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v);
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.msl
index fa59b83..a72769b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.msl
@@ -1,8 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_fdebd0(texture2d_array<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(int2(1)), 1);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.spvasm
index e439bbc..d54a351 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fdebd0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -57,66 +59,78 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %18 = OpTypeFunction %v4uint
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %37 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fdebd0 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %23 = OpCompositeConstruct %v3int %24 %int_1
-         %27 = OpImageRead %v4uint %20 %23 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %21 = OpImageQuerySize %v3uint %20
+         %23 = OpCompositeExtract %uint %21 2
+         %24 = OpISub %uint %23 %uint_1
+         %26 = OpBitcast %uint %int_1
+         %29 = OpExtInst %uint %30 UMin %26 %24
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %37
+         %39 = OpExtInst %v2uint %30 UMin %36 %34
+         %40 = OpCompositeConstruct %v3uint %39 %29
+         %41 = OpImageRead %v4uint %20 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_fdebd0
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_fdebd0
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_fdebd0
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
          %55 = OpFunctionCall %v4uint %textureLoad_fdebd0
-               OpStore %53 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_fdebd0
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.glsl
index abf1d90..9ef3e41 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_fe0565() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -23,7 +23,7 @@
 } v;
 uniform highp usampler2DMS arg_0;
 uvec4 textureLoad_fe0565() {
-  ivec2 v_1 = ivec2(uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v_1, int(1));
   return res;
 }
@@ -42,7 +42,7 @@
 uniform highp usampler2DMS arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_fe0565() {
-  ivec2 v = ivec2(uvec2(1u));
+  ivec2 v = ivec2(min(uvec2(1u), (uvec2(textureSize(arg_0)) - uvec2(1u))));
   uvec4 res = texelFetch(arg_0, v, int(1));
   return res;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
index 15f3337..8da573b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fe0565() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe0565();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
index 15f3337..8da573b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
@@ -12,8 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DMS<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fe0565() {
-  int2 v = int2((1u).xx);
-  uint4 res = uint4(arg_0.Load(v, int(int(1))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int2 v_1 = int2(min((1u).xx, (v.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_1, int(int(1))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe0565();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.msl
index ab6b1c8..34f5cb6 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 };
 
 uint4 textureLoad_fe0565(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(1u), 1);
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(1u), (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.msl
index e0b721d..ccccbc5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 uint4 textureLoad_fe0565(texture2d_ms<uint, access::read> tint_symbol_1) {
-  uint4 res = tint_symbol_1.read(uint2(uint2(1u)), 1);
+  uint4 res = tint_symbol_1.read(uint2(min(uint2(1u), (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), 1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.spvasm
index 936dfe1..af6f30c 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fe0565.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -58,62 +60,65 @@
          %18 = OpTypeFunction %v4uint
      %v2uint = OpTypeVector %uint 2
      %uint_1 = OpConstant %uint 1
-         %22 = OpConstantComposite %v2uint %uint_1 %uint_1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fe0565 = OpFunction %v4uint None %18
          %19 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %20 = OpLoad %8 %arg_0 None
-         %21 = OpImageFetch %v4uint %20 %22 Sample %int_1
-               OpStore %res %21
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %21 = OpImageQuerySize %v2uint %20
+         %23 = OpISub %v2uint %21 %24
+         %26 = OpExtInst %v2uint %27 UMin %24 %23
+         %28 = OpImageFetch %v4uint %20 %26 Sample %int_1
+               OpStore %res %28
+         %33 = OpLoad %v4uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_fe0565
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_fe0565
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_fe0565
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_fe0565
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %53 = OpFunctionCall %v4uint %textureLoad_fe0565
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %57 = OpFunctionCall %v4uint %textureLoad_fe0565
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4uint %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.glsl
index 891f8a5..9e56ef2 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_fe222a() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_fe222a() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v_1), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_fe222a() {
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(1, 0)));
+  uint v = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(1), v), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
index 25d60bf..de38f9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_fe222a() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe222a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
index 25d60bf..de38f9a 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_fe222a() {
-  float4 res = float4(arg_0.Load(int2(int(int(1)), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(int(1)), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe222a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.msl
index efac045..6ef081e 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_fe222a(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint(1));
+  uint const v = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(1), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.msl
index 57e75b2..2cad0be 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_fe222a(texture1d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint(1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.spvasm
index 7107e23..936e004 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fe222a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 56
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -55,62 +57,66 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %39 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %43 = OpConstantNull %VertexOutput
-         %45 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fe222a = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %int_1 None
-               OpStore %res %18
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %18 = OpImageQuerySize %uint %17
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %int_1
+         %25 = OpExtInst %uint %26 UMin %22 %20
+         %27 = OpImageRead %v4float %17 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_fe222a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %26
+%fragment_main = OpFunction %void None %33
          %34 = OpLabel
          %35 = OpFunctionCall %v4float %textureLoad_fe222a
          %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %39
+%compute_main = OpFunction %void None %33
          %40 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %43
-         %44 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %44 %45 None
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %48 = OpFunctionCall %v4float %textureLoad_fe222a
-               OpStore %46 %48 None
-         %49 = OpLoad %VertexOutput %out None
-               OpReturnValue %49
+         %41 = OpFunctionCall %v4float %textureLoad_fe222a
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %26
-         %51 = OpLabel
-         %52 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %53 = OpCompositeExtract %v4float %52 0
-               OpStore %vertex_main_position_Output %53 None
-         %54 = OpCompositeExtract %v4float %52 1
-               OpStore %vertex_main_loc0_Output %54 None
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_fe222a
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
index c35bced..24675ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_fe2c1b() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
index c35bced..24675ec 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
@@ -2,8 +2,13 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 RWTexture2DArray<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_fe2c1b() {
-  int2 v = int2((int(1)).xx);
-  uint4 res = uint4(arg_0.Load(int4(v, int(1u), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2((int(1)).xx), v_2));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(min(1u, (v.z - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.msl
index f886aba..1b97b75 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.ir.msl
@@ -7,7 +7,8 @@
 };
 
 uint4 textureLoad_fe2c1b(tint_module_vars_struct tint_module_vars) {
-  uint4 res = tint_module_vars.arg_0.read(uint2(int2(1)), 1u);
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v), min(1u, (tint_module_vars.arg_0.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.msl
index cff2aef..092d1c4 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_fe2c1b(texture2d_array<uint, access::read_write> tint_symbol) {
-  uint4 res = tint_symbol.read(uint2(int2(1)), 1u);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(1u, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.spvasm
index 38dec4c..21c44df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/fe2c1b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %19 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -33,39 +35,49 @@
 %_ptr_UniformConstant_8 = OpTypePointer UniformConstant %8
       %arg_0 = OpVariable %_ptr_UniformConstant_8 UniformConstant
          %10 = OpTypeFunction %v4uint
-        %int = OpTypeInt 32 1
+     %v3uint = OpTypeVector %uint 3
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v2uint = OpTypeVector %uint 2
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
+        %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
       %int_1 = OpConstant %int 1
-         %18 = OpConstantComposite %v2int %int_1 %int_1
+         %26 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_fe2c1b = OpFunction %v4uint None %10
          %11 = OpLabel
         %res = OpVariable %_ptr_Function_v4uint Function
          %12 = OpLoad %8 %arg_0 None
-         %14 = OpBitcast %int %uint_1
-         %17 = OpCompositeConstruct %v3int %18 %14
-         %21 = OpImageRead %v4uint %12 %17 None
-               OpStore %res %21
-         %24 = OpLoad %v4uint %res None
-               OpReturnValue %24
+         %13 = OpImageQuerySize %v3uint %12
+         %15 = OpCompositeExtract %uint %13 2
+         %16 = OpISub %uint %15 %uint_1
+         %18 = OpExtInst %uint %19 UMin %uint_1 %16
+         %20 = OpImageQuerySize %v3uint %12
+         %21 = OpVectorShuffle %v2uint %20 %20 0 1
+         %23 = OpISub %v2uint %21 %24
+         %25 = OpBitcast %v2uint %26
+         %30 = OpExtInst %v2uint %19 UMin %25 %23
+         %31 = OpCompositeConstruct %v3uint %30 %18
+         %32 = OpImageRead %v4uint %12 %31 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4uint %textureLoad_fe2c1b
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4uint %textureLoad_fe2c1b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_fe2c1b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_fe2c1b
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.glsl
index 7f99134..2bb4ea5 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.glsl
@@ -8,7 +8,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_feab99() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 void main() {
@@ -22,7 +23,8 @@
 } v;
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_feab99() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v_1)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,7 +42,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_feab99() {
-  vec4 res = imageLoad(arg_0, ivec3(ivec3(1)));
+  uvec3 v = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(ivec3(1)), v)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -50,10 +53,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
index 2d0746b..46364df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_feab99() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_feab99();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
index 2d0746b..46364df 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,10 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_feab99() {
-  float4 res = float4(arg_0.Load(int4(int3((int(1)).xxx), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3((int(1)).xxx), v_1)), int(0))));
   return res;
 }
 
@@ -29,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_feab99();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.msl
index 55833e5..d630168 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.ir.msl
@@ -17,7 +17,8 @@
 };
 
 float4 textureLoad_feab99(tint_module_vars_struct tint_module_vars) {
-  float4 res = tint_module_vars.arg_0.read(uint3(int3(1)));
+  uint3 const v = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(int3(1)), v));
   return res;
 }
 
@@ -40,9 +41,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.msl
index e43c65d..5ac136b 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.msl
@@ -1,8 +1,12 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_feab99(texture3d<float, access::read> tint_symbol_1) {
-  float4 res = tint_symbol_1.read(uint3(int3(1)));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(int3(1), int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.spvasm
index ebbd61f..0390932 100644
--- a/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/feab99.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -54,64 +56,70 @@
 %_ptr_Output_float = OpTypePointer Output %float
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %v4float
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %22 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v3int = OpTypeVector %int 3
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+         %25 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %28 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_feab99 = OpFunction %v4float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
          %17 = OpLoad %8 %arg_0 None
-         %18 = OpImageRead %v4float %17 %19 None
-               OpStore %res %18
-         %25 = OpLoad %v4float %res None
-               OpReturnValue %25
+         %18 = OpImageQuerySize %v3uint %17
+         %21 = OpISub %v3uint %18 %22
+         %24 = OpBitcast %v3uint %25
+         %29 = OpExtInst %v3uint %30 UMin %24 %21
+         %31 = OpImageRead %v4float %17 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %28
-         %29 = OpLabel
-         %30 = OpFunctionCall %v4float %textureLoad_feab99
-         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %31 %30 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_feab99
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %28
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_feab99
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_feab99
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_feab99
-               OpStore %48 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_feab99
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %28
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.glsl
index 4fc9986..afbe7e8 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.glsl
@@ -2,15 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_ff1119() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  float res = texelFetch(arg_0, v_7, int(v_4)).x;
   return res;
 }
 void main() {
@@ -18,15 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_ff1119() {
-  ivec2 v_1 = ivec2(ivec2(1));
-  ivec3 v_2 = ivec3(v_1, int(1));
-  float res = texelFetch(arg_0, v_2, int(1u)).x;
+  uint v_2 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_3 = min(uint(1), v_2);
+  uint v_4 = min(1u, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4)).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(ivec2(1)), v_5));
+  ivec3 v_7 = ivec3(v_6, int(v_3));
+  float res = texelFetch(arg_0, v_7, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -36,17 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_ff1119() {
-  ivec2 v = ivec2(ivec2(1));
-  ivec3 v_1 = ivec3(v, int(1));
-  float res = texelFetch(arg_0, v_1, int(1u)).x;
+  uint v_1 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  uint v_3 = min(1u, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3)).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(ivec2(1)), v_4));
+  ivec3 v_6 = ivec3(v_5, int(v_2));
+  float res = texelFetch(arg_0, v_6, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -56,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_7 = vertex_main_inner();
+  gl_Position = v_7.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_7.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
index db3da7e..b456aed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_ff1119() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  float res = arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ff1119();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
index db3da7e..b456aed 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
@@ -12,9 +12,17 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 Texture2DArray arg_0 : register(t0, space1);
 float textureLoad_ff1119() {
-  int2 v = int2((int(1)).xx);
-  int v_1 = int(int(1));
-  float res = arg_0.Load(int4(v, v_1, int(1u))).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(uint(int(1)), (v.z - 1u));
+  uint4 v_2 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(1u, (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2((int(1)).xx), v_4));
+  int v_6 = int(v_1);
+  float res = arg_0.Load(int4(v_5, v_6, int(min(1u, (v_2.w - 1u))))).x;
   return res;
 }
 
@@ -31,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ff1119();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_7 = tint_symbol;
+  return v_7;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_8 = vertex_main_inner();
+  vertex_main_outputs v_9 = {v_8.prevent_dce, v_8.pos};
+  return v_9;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.msl
index 5e685d8..ffa6360 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.ir.msl
@@ -17,7 +17,9 @@
 };
 
 float textureLoad_ff1119(tint_module_vars_struct tint_module_vars) {
-  float res = tint_module_vars.arg_0.read(uint2(int2(1)), 1, 1u);
+  uint const v = min(uint(1), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(int2(1)), v_1), v, min(1u, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -40,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.msl b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.msl
index f62932b..2f23d84 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.msl
@@ -1,8 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_ff1119(depth2d_array<float, access::sample> tint_symbol_1) {
-  float res = tint_symbol_1.read(uint2(int2(1)), 1, 1u);
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(int2(1), int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(1, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.spvasm
index 6eddd87..de48996 100644
--- a/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/textureLoad/ff1119.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -53,68 +55,83 @@
 %vertex_main_loc0_Output = OpVariable %_ptr_Output_float Output
 %vertex_main___point_size_Output = OpVariable %_ptr_Output_float Output
          %15 = OpTypeFunction %float
-        %int = OpTypeInt 32 1
-      %v3int = OpTypeVector %int 3
-      %v2int = OpTypeVector %int 2
-      %int_1 = OpConstant %int 1
-         %21 = OpConstantComposite %v2int %int_1 %int_1
        %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
+      %v2int = OpTypeVector %int 2
+         %39 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %45 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ff1119 = OpFunction %float None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
          %17 = OpLoad %7 %arg_0 None
-         %20 = OpCompositeConstruct %v3int %21 %int_1
-         %24 = OpImageFetch %v4float %17 %20 Lod %uint_1
-         %27 = OpCompositeExtract %float %24 0
-               OpStore %res %27
-         %30 = OpLoad %float %res None
-               OpReturnValue %30
+         %18 = OpImageQuerySizeLod %v3uint %17 %uint_0
+         %22 = OpCompositeExtract %uint %18 2
+         %23 = OpISub %uint %22 %uint_1
+         %25 = OpBitcast %uint %int_1
+         %28 = OpExtInst %uint %29 UMin %25 %23
+         %30 = OpImageQueryLevels %uint %17
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %29 UMin %uint_1 %31
+         %33 = OpImageQuerySizeLod %v3uint %17 %32
+         %34 = OpVectorShuffle %v2uint %33 %33 0 1
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %39
+         %41 = OpExtInst %v2uint %29 UMin %38 %36
+         %42 = OpCompositeConstruct %v3uint %41 %28
+         %43 = OpImageFetch %v4float %17 %42 Lod %32
+         %44 = OpCompositeExtract %float %43 0
+               OpStore %res %44
+         %47 = OpLoad %float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %float %textureLoad_ff1119
-         %36 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %float %textureLoad_ff1119
+         %53 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %float %textureLoad_ff1119
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %50
+         %56 = OpLabel
+         %57 = OpFunctionCall %float %textureLoad_ff1119
+         %58 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %54 = OpFunctionCall %float %textureLoad_ff1119
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %70 = OpFunctionCall %float %textureLoad_ff1119
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.glsl
index 3076c03..df220a1 100644
--- a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_06794e() {
   f16mat3 res = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_06794e();
@@ -23,7 +23,7 @@
 } v;
 int transpose_06794e() {
   f16mat3 res = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_06794e() {
   f16mat3 res = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.dxc.hlsl
index cec93b7..47e1511 100644
--- a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_06794e() {
   matrix<float16_t, 3, 3> res = matrix<float16_t, 3, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.msl
index f7d722e..d007b74 100644
--- a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_06794e() {
   half3x3 res = half3x3(half3(1.0h), half3(1.0h), half3(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.spvasm
index fae13dd..d946178 100644
--- a/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/06794e.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat3v3half %22 %22 %22
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v3half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_06794e
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_06794e
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_06794e
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.glsl
index d8a80ab..39ab2b2 100644
--- a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_2585cd() {
   mat3x4 res = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_2585cd();
@@ -21,7 +21,7 @@
 } v;
 int transpose_2585cd() {
   mat3x4 res = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_2585cd() {
   mat3x4 res = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
index 5da0034..3210507 100644
--- a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_2585cd() {
   float3x4 res = float3x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
index 5da0034..3210507 100644
--- a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_2585cd() {
   float3x4 res = float3x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.msl
index 16aa49d..bc1e64e 100644
--- a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_2585cd() {
   float3x4 res = float3x4(float4(1.0f), float4(1.0f), float4(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.spvasm
index 1512172..90612b9 100644
--- a/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/2585cd.wgsl.expected.spvasm
@@ -55,16 +55,16 @@
          %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
          %19 = OpConstantComposite %mat3v4float %20 %20 %20
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -76,21 +76,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v4float Function
                OpStore %res %19
-         %22 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %25 = OpAccessChain %_ptr_Function_float %22 %int_0
-         %27 = OpLoad %float %25 None
-         %28 = OpFOrdEqual %bool %27 %float_0
-         %31 = OpSelect %int %28 %int_1 %int_0
-               OpReturnValue %31
+         %22 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %26 = OpAccessChain %_ptr_Function_float %22 %uint_0
+         %28 = OpLoad %float %26 None
+         %29 = OpFOrdEqual %bool %28 %float_0
+         %32 = OpSelect %int %29 %int_1 %int_0
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %int %transpose_2585cd
-         %38 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %int %transpose_2585cd
+         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
+%compute_main = OpFunction %void None %37
          %43 = OpLabel
          %44 = OpFunctionCall %int %transpose_2585cd
          %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -108,7 +108,7 @@
          %59 = OpLoad %VertexOutput %out None
                OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main = OpFunction %void None %37
          %61 = OpLabel
          %62 = OpFunctionCall %VertexOutput %vertex_main_inner
          %63 = OpCompositeExtract %v4float %62 0
diff --git a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.glsl
index a520f97..df60f31 100644
--- a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_31d679() {
   mat2 res = mat2(vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_31d679();
@@ -21,7 +21,7 @@
 } v;
 int transpose_31d679() {
   mat2 res = mat2(vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_31d679() {
   mat2 res = mat2(vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.dxc.hlsl
index 3a5bec9..b631ba7 100644
--- a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_31d679() {
   float2x2 res = float2x2((1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.fxc.hlsl
index 3a5bec9..b631ba7 100644
--- a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_31d679() {
   float2x2 res = float2x2((1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.msl
index 09bc5d0..d74aabc 100644
--- a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_31d679() {
   float2x2 res = float2x2(float2(1.0f), float2(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.spvasm
index 3e29525..e53eb6a 100644
--- a/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/31d679.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v2float %float_1 %float_1
          %20 = OpConstantComposite %mat2v2float %21 %21
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v2float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_31d679
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_31d679
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_31d679
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.glsl
index dde45f2..d980ab1 100644
--- a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_31e37e() {
   mat2x4 res = mat2x4(vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_31e37e();
@@ -21,7 +21,7 @@
 } v;
 int transpose_31e37e() {
   mat2x4 res = mat2x4(vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_31e37e() {
   mat2x4 res = mat2x4(vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
index ce01782..ec9b030 100644
--- a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_31e37e() {
   float2x4 res = float2x4((1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
index ce01782..ec9b030 100644
--- a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_31e37e() {
   float2x4 res = float2x4((1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.msl
index 863c2db..335a0cb 100644
--- a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_31e37e() {
   float2x4 res = float2x4(float4(1.0f), float4(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.spvasm
index 48c4a33..867d610 100644
--- a/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/31e37e.wgsl.expected.spvasm
@@ -55,16 +55,16 @@
          %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
          %19 = OpConstantComposite %mat2v4float %20 %20
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -76,21 +76,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v4float Function
                OpStore %res %19
-         %22 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %25 = OpAccessChain %_ptr_Function_float %22 %int_0
-         %27 = OpLoad %float %25 None
-         %28 = OpFOrdEqual %bool %27 %float_0
-         %31 = OpSelect %int %28 %int_1 %int_0
-               OpReturnValue %31
+         %22 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %26 = OpAccessChain %_ptr_Function_float %22 %uint_0
+         %28 = OpLoad %float %26 None
+         %29 = OpFOrdEqual %bool %28 %float_0
+         %32 = OpSelect %int %29 %int_1 %int_0
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %int %transpose_31e37e
-         %38 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %int %transpose_31e37e
+         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
+%compute_main = OpFunction %void None %37
          %43 = OpLabel
          %44 = OpFunctionCall %int %transpose_31e37e
          %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -108,7 +108,7 @@
          %59 = OpLoad %VertexOutput %out None
                OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main = OpFunction %void None %37
          %61 = OpLabel
          %62 = OpFunctionCall %VertexOutput %vertex_main_inner
          %63 = OpCompositeExtract %v4float %62 0
diff --git a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.glsl
index 72ecc88..f09eb6c 100644
--- a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_4ce359() {
   mat4x2 res = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_4ce359();
@@ -21,7 +21,7 @@
 } v;
 int transpose_4ce359() {
   mat4x2 res = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_4ce359() {
   mat4x2 res = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
index 5a2e592..1f87e44 100644
--- a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_4ce359() {
   float4x2 res = float4x2((1.0f).xx, (1.0f).xx, (1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
index 5a2e592..1f87e44 100644
--- a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_4ce359() {
   float4x2 res = float4x2((1.0f).xx, (1.0f).xx, (1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.msl
index 314bff8..10df460 100644
--- a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_4ce359() {
   float4x2 res = float4x2(float2(1.0f), float2(1.0f), float2(1.0f), float2(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.spvasm
index 211ca0e..14bf79d 100644
--- a/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/4ce359.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v2float %float_1 %float_1
          %20 = OpConstantComposite %mat4v2float %21 %21 %21 %21
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v2float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_4ce359
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_4ce359
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_4ce359
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.glsl
index 8160dd5..af2bdd3 100644
--- a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_4dc9a1() {
   mat3x2 res = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_4dc9a1();
@@ -21,7 +21,7 @@
 } v;
 int transpose_4dc9a1() {
   mat3x2 res = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_4dc9a1() {
   mat3x2 res = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
index d90cb7f..686a8e5 100644
--- a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_4dc9a1() {
   float3x2 res = float3x2((1.0f).xx, (1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
index d90cb7f..686a8e5 100644
--- a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_4dc9a1() {
   float3x2 res = float3x2((1.0f).xx, (1.0f).xx, (1.0f).xx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.msl
index d003bb3..ac4b4a9 100644
--- a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_4dc9a1() {
   float3x2 res = float3x2(float2(1.0f), float2(1.0f), float2(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.spvasm
index c48df8d..9a69df4 100644
--- a/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/4dc9a1.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v2float %float_1 %float_1
          %20 = OpConstantComposite %mat3v2float %21 %21 %21
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v2float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_4dc9a1
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_4dc9a1
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_4dc9a1
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.glsl
index 67c2381..66c1274 100644
--- a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_5edd96() {
   f16mat2x4 res = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_5edd96();
@@ -23,7 +23,7 @@
 } v;
 int transpose_5edd96() {
   f16mat2x4 res = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_5edd96() {
   f16mat2x4 res = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
index 9dfb9ba..a2852d8 100644
--- a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_5edd96() {
   matrix<float16_t, 2, 4> res = matrix<float16_t, 2, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.msl
index ed3632e..8b33a3d 100644
--- a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_5edd96() {
   half2x4 res = half2x4(half4(1.0h), half4(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.spvasm
index 6373874..bf0b917 100644
--- a/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/5edd96.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat2v4half %22 %22
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v4half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_5edd96
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_5edd96
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_5edd96
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.glsl
index 0b99e8c..0f29158 100644
--- a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_5f36bf() {
   f16mat3x4 res = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_5f36bf();
@@ -23,7 +23,7 @@
 } v;
 int transpose_5f36bf() {
   f16mat3x4 res = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_5f36bf() {
   f16mat3x4 res = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
index 494e50e..8a4a7d3 100644
--- a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_5f36bf() {
   matrix<float16_t, 3, 4> res = matrix<float16_t, 3, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.msl
index b196e01..1f0b9f7 100644
--- a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_5f36bf() {
   half3x4 res = half3x4(half4(1.0h), half4(1.0h), half4(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.spvasm
index 55ff25e..b8ff80b 100644
--- a/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/5f36bf.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat3v4half %22 %22 %22
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v4half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_5f36bf
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_5f36bf
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_5f36bf
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.glsl
index 5c3da03..beafe1f 100644
--- a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_7be8b2() {
   f16mat2 res = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_7be8b2();
@@ -23,7 +23,7 @@
 } v;
 int transpose_7be8b2() {
   f16mat2 res = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_7be8b2() {
   f16mat2 res = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
index e5bb6df..f9d598a 100644
--- a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_7be8b2() {
   matrix<float16_t, 2, 2> res = matrix<float16_t, 2, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.msl
index 7daab97..0d3e629 100644
--- a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_7be8b2() {
   half2x2 res = half2x2(half2(1.0h), half2(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.spvasm
index 1858085..a84eabe 100644
--- a/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/7be8b2.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat2v2half %22 %22
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v2half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_7be8b2
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_7be8b2
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_7be8b2
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.glsl
index 2291bd7..0c4a982 100644
--- a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_844869() {
   f16mat4 res = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_844869();
@@ -23,7 +23,7 @@
 } v;
 int transpose_844869() {
   f16mat4 res = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_844869() {
   f16mat4 res = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.dxc.hlsl
index e182457..3158ba6 100644
--- a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_844869() {
   matrix<float16_t, 4, 4> res = matrix<float16_t, 4, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.msl
index 6a8f767..d635cb82 100644
--- a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_844869() {
   half4x4 res = half4x4(half4(1.0h), half4(1.0h), half4(1.0h), half4(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.spvasm
index d9eae7b..3b7d0ec 100644
--- a/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/844869.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat4v4half %22 %22 %22 %22
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v4half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_844869
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_844869
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_844869
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.glsl
index 8ca6864..4e4d548 100644
--- a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_854336() {
   mat3 res = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_854336();
@@ -21,7 +21,7 @@
 } v;
 int transpose_854336() {
   mat3 res = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_854336() {
   mat3 res = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.dxc.hlsl
index 5204d7a..a73ec33 100644
--- a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_854336() {
   float3x3 res = float3x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.fxc.hlsl
index 5204d7a..a73ec33 100644
--- a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_854336() {
   float3x3 res = float3x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.msl
index a19b68b..ca8e06f 100644
--- a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_854336() {
   float3x3 res = float3x3(float3(1.0f), float3(1.0f), float3(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.spvasm
index c0880fb..e00d793 100644
--- a/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/854336.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v3float %float_1 %float_1 %float_1
          %20 = OpConstantComposite %mat3v3float %21 %21 %21
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_854336
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_854336
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_854336
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.glsl
index 7b15037..1153f4d 100644
--- a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_8c06ce() {
   f16mat4x3 res = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_8c06ce();
@@ -23,7 +23,7 @@
 } v;
 int transpose_8c06ce() {
   f16mat4x3 res = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_8c06ce() {
   f16mat4x3 res = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
index 96574133..0dcc031 100644
--- a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_8c06ce() {
   matrix<float16_t, 4, 3> res = matrix<float16_t, 4, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.msl
index 27fa482..ff7c718 100644
--- a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_8c06ce() {
   half4x3 res = half4x3(half3(1.0h), half3(1.0h), half3(1.0h), half3(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.spvasm
index bf33a2b..560b61a 100644
--- a/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/8c06ce.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat4v3half %22 %22 %22 %22
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v3half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_8c06ce
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_8c06ce
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_8c06ce
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.glsl
index c941f73..cabe4d5 100644
--- a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_b9ad1f() {
   f16mat2x3 res = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_b9ad1f();
@@ -23,7 +23,7 @@
 } v;
 int transpose_b9ad1f() {
   f16mat2x3 res = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_b9ad1f() {
   f16mat2x3 res = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
index 0ea405e..6bf91c4 100644
--- a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_b9ad1f() {
   matrix<float16_t, 2, 3> res = matrix<float16_t, 2, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.msl
index 239d0b3..6ff0048 100644
--- a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_b9ad1f() {
   half2x3 res = half2x3(half3(1.0h), half3(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.spvasm
index 9c25469..5062bf4 100644
--- a/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/b9ad1f.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat2v3half %22 %22
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v3half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_b9ad1f
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_b9ad1f
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_b9ad1f
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.glsl
index 385b702..0bdf7bd 100644
--- a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_c1b600() {
   mat4 res = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_c1b600();
@@ -21,7 +21,7 @@
 } v;
 int transpose_c1b600() {
   mat4 res = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_c1b600() {
   mat4 res = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
index 017d644..5bf7033 100644
--- a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_c1b600() {
   float4x4 res = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
index 017d644..5bf7033 100644
--- a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_c1b600() {
   float4x4 res = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.msl
index 3789d87..9eb6173 100644
--- a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_c1b600() {
   float4x4 res = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.spvasm
index 20d73f9..bec5900 100644
--- a/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/c1b600.wgsl.expected.spvasm
@@ -55,16 +55,16 @@
          %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
          %19 = OpConstantComposite %mat4v4float %20 %20 %20 %20
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -76,21 +76,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v4float Function
                OpStore %res %19
-         %22 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %25 = OpAccessChain %_ptr_Function_float %22 %int_0
-         %27 = OpLoad %float %25 None
-         %28 = OpFOrdEqual %bool %27 %float_0
-         %31 = OpSelect %int %28 %int_1 %int_0
-               OpReturnValue %31
+         %22 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %26 = OpAccessChain %_ptr_Function_float %22 %uint_0
+         %28 = OpLoad %float %26 None
+         %29 = OpFOrdEqual %bool %28 %float_0
+         %32 = OpSelect %int %29 %int_1 %int_0
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %int %transpose_c1b600
-         %38 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %int %transpose_c1b600
+         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
+%compute_main = OpFunction %void None %37
          %43 = OpLabel
          %44 = OpFunctionCall %int %transpose_c1b600
          %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -108,7 +108,7 @@
          %59 = OpLoad %VertexOutput %out None
                OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%vertex_main = OpFunction %void None %37
          %61 = OpLabel
          %62 = OpFunctionCall %VertexOutput %vertex_main_inner
          %63 = OpCompositeExtract %v4float %62 0
diff --git a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.glsl
index 83f15ab..f12d2d4 100644
--- a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_d6faec() {
   f16mat3x2 res = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_d6faec();
@@ -23,7 +23,7 @@
 } v;
 int transpose_d6faec() {
   f16mat3x2 res = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_d6faec() {
   f16mat3x2 res = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
index 01c5d76..e80929c 100644
--- a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_d6faec() {
   matrix<float16_t, 3, 2> res = matrix<float16_t, 3, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.msl
index d4a4303..a7c3dde 100644
--- a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_d6faec() {
   half3x2 res = half3x2(half2(1.0h), half2(1.0h), half2(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.spvasm
index c6f1a52..5a75960 100644
--- a/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/d6faec.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat3v2half %22 %22 %22
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat3v2half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_d6faec
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_d6faec
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_d6faec
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.glsl
index d4cf355..5f6a7fb 100644
--- a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_d8f8ba() {
   mat4x3 res = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_d8f8ba();
@@ -21,7 +21,7 @@
 } v;
 int transpose_d8f8ba() {
   mat4x3 res = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_d8f8ba() {
   mat4x3 res = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
index 6001874..03d5c74 100644
--- a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_d8f8ba() {
   float4x3 res = float4x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
index 6001874..03d5c74 100644
--- a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_d8f8ba() {
   float4x3 res = float4x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.msl
index c1d7f82..72ae9e9 100644
--- a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_d8f8ba() {
   float4x3 res = float4x3(float3(1.0f), float3(1.0f), float3(1.0f), float3(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.spvasm
index f872bcc..7214f84 100644
--- a/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/d8f8ba.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v3float %float_1 %float_1 %float_1
          %20 = OpConstantComposite %mat4v3float %21 %21 %21 %21
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v3float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_d8f8ba
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_d8f8ba
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_d8f8ba
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.glsl
index 2ff26bf..8c6e081 100644
--- a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 } v;
 int transpose_ed4bdc() {
   mat2x3 res = mat2x3(vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_ed4bdc();
@@ -21,7 +21,7 @@
 } v;
 int transpose_ed4bdc() {
   mat2x3 res = mat2x3(vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -38,7 +38,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_ed4bdc() {
   mat2x3 res = mat2x3(vec3(1.0f), vec3(1.0f));
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
index aee0375..b820805 100644
--- a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_ed4bdc() {
   float2x3 res = float2x3((1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
index aee0375..b820805 100644
--- a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_ed4bdc() {
   float2x3 res = float2x3((1.0f).xxx, (1.0f).xxx);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.msl
index 545162f..56d05c3 100644
--- a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_ed4bdc() {
   float2x3 res = float2x3(float3(1.0f), float3(1.0f));
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.spvasm
index 7169c17..23d79b2 100644
--- a/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/ed4bdc.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %21 = OpConstantComposite %v3float %float_1 %float_1 %float_1
          %20 = OpConstantComposite %mat2v3float %21 %21
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -78,21 +78,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat2v3float Function
                OpStore %res %20
-         %23 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %26 = OpAccessChain %_ptr_Function_float %23 %int_0
-         %28 = OpLoad %float %26 None
-         %29 = OpFOrdEqual %bool %28 %float_0
-         %32 = OpSelect %int %29 %int_1 %int_0
-               OpReturnValue %32
+         %23 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %27 = OpAccessChain %_ptr_Function_float %23 %uint_0
+         %29 = OpLoad %float %27 None
+         %30 = OpFOrdEqual %bool %29 %float_0
+         %33 = OpSelect %int %30 %int_1 %int_0
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %int %transpose_ed4bdc
-         %39 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %int %transpose_ed4bdc
+         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %38
          %44 = OpLabel
          %45 = OpFunctionCall %int %transpose_ed4bdc
          %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -110,7 +110,7 @@
          %61 = OpLoad %VertexOutput %out None
                OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main = OpFunction %void None %38
          %63 = OpLabel
          %64 = OpFunctionCall %VertexOutput %vertex_main_inner
          %65 = OpCompositeExtract %v4float %64 0
diff --git a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.glsl b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.glsl
index 2a9aca4..3e9b950 100644
--- a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 } v;
 int transpose_faeb05() {
   f16mat4x2 res = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_faeb05();
@@ -23,7 +23,7 @@
 } v;
 int transpose_faeb05() {
   f16mat4x2 res = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 layout(location = 0) flat out int vertex_main_loc0_Output;
 int transpose_faeb05() {
   f16mat4x2 res = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
index f5f2c02..c336fc9 100644
--- a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 RWByteAddressBuffer prevent_dce : register(u0);
 int transpose_faeb05() {
   matrix<float16_t, 4, 2> res = matrix<float16_t, 4, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.msl b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.msl
index b139c0a..1de57cb 100644
--- a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.ir.msl
@@ -17,7 +17,7 @@
 
 int transpose_faeb05() {
   half4x2 res = half4x2(half2(1.0h), half2(1.0h), half2(1.0h), half2(1.0h));
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.spvasm
index 8e9139a..de0e50c 100644
--- a/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/transpose/faeb05.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
          %22 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat4v2half %22 %22 %22 %22
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %15 = OpLabel
         %res = OpVariable %_ptr_Function_mat4v2half Function
                OpStore %res %21
-         %24 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %27 = OpAccessChain %_ptr_Function_half %24 %int_0
-         %29 = OpLoad %half %27 None
-         %30 = OpFOrdEqual %bool %29 %half_0x0p_0
-         %33 = OpSelect %int %30 %int_1 %int_0
-               OpReturnValue %33
+         %24 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %28 = OpAccessChain %_ptr_Function_half %24 %uint_0
+         %30 = OpLoad %half %28 None
+         %31 = OpFOrdEqual %bool %30 %half_0x0p_0
+         %34 = OpSelect %int %31 %int_1 %int_0
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %int %transpose_faeb05
-         %40 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %int %transpose_faeb05
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %39
          %45 = OpLabel
          %46 = OpFunctionCall %int %transpose_faeb05
          %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%vertex_main = OpFunction %void None %39
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.glsl
index 68cef05..04823d5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_022903() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_022903() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_022903() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
index 8f9fdfd..57f3509 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_022903() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_022903();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
index 8f9fdfd..57f3509 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_022903() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_022903();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.msl
index 70acc77..cdeba68 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_022903(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
+  min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.msl
index 435949f..40d3c26 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_022903(texture1d<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.spvasm
index 224a8e1..6f575b1 100644
--- a/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/022903.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
+         %50 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %49 = OpConstantNull %v4float
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_022903 = OpFunction %uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %7 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %uint %23 %24
-               OpStore %res %25
-         %27 = OpLoad %uint %res None
-               OpReturnValue %27
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %uint %23 %27
+               OpStore %res %29
+         %31 = OpLoad %uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %uint %textureDimensions_022903
-         %33 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %uint %textureDimensions_022903
+         %37 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %uint %textureDimensions_022903
-         %39 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %uint %textureDimensions_022903
+         %43 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %49 None
-         %50 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %51 = OpFunctionCall %uint %textureDimensions_022903
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %53 None
+         %54 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %55 = OpFunctionCall %uint %textureDimensions_022903
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %uint %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %34
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %uint %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.glsl
index b53341c..737c731 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_0890c6() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_0890c6() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_0890c6() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
index fc9e297..63f5352 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_0890c6() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0890c6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
index fc9e297..63f5352 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_0890c6() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0890c6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.msl
index 14926eb..49def3e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_0890c6(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.msl
index 8d1db9a..40dac0e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_0890c6(texture3d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.spvasm
index 217719d..e68cd95 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/0890c6.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_0890c6 = OpFunction %v3uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v3uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v3uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v3uint %textureDimensions_0890c6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v3uint %textureDimensions_0890c6
+         %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v3uint %textureDimensions_0890c6
-         %40 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v3uint %textureDimensions_0890c6
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %52 = OpFunctionCall %v3uint %textureDimensions_0890c6
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %56 = OpFunctionCall %v3uint %textureDimensions_0890c6
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v3uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v3uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.glsl
index e500a54..2145111 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_0ff9a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_0ff9a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_0ff9a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
index 7e00967..9848f25 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_0ff9a4() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0ff9a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
index 7e00967..9848f25 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_0ff9a4() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_0ff9a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.msl
index 665b203..e68b077 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_0ff9a4(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.msl
index bf8f831..dc4ec96 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_0ff9a4(depthcube_array<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.spvasm
index 0208790..769fd7d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/0ff9a4.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +63,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_0ff9a4 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -83,44 +84,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_0ff9a4
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.glsl
index 2e57bb4..f9487f4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_13f8db() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_13f8db() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_13f8db() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
index 81b5582..7b7c2b4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_13f8db() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_13f8db();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
index 81b5582..7b7c2b4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_13f8db() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_13f8db();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.msl
index a0fad81..c4feacc 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_13f8db(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.msl
index 75cd057..b53fe7c 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_13f8db(texture2d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.spvasm
index 440554b..ad8daab 100644
--- a/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/13f8db.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_13f8db = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_13f8db
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_13f8db
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_13f8db
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_13f8db
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_13f8db
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_13f8db
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.glsl
index f82ea08..3ba13b3 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_15b577() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_15b577() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_15b577() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
index 8471781..f9a9de2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_15b577() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_15b577();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
index 8471781..f9a9de2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_15b577() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_15b577();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.msl
index bae9238..0621730 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_15b577(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.msl
index f4952ca..864f25d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_15b577(texture2d<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.spvasm
index 4aff4c8..2604341 100644
--- a/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/15b577.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_15b577 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_15b577
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_15b577
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_15b577
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_15b577
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_15b577
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.glsl
index f2e445a..71bb503 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_1bc428() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 uvec3 textureDimensions_1bc428() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_1bc428() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
index e45e640..119f5fd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_1bc428() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bc428();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
index e45e640..119f5fd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_1bc428() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bc428();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.msl
index 9cb8543..f9cb985 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_1bc428(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.msl
index 01a275e..810f325 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_1bc428(texture3d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.spvasm
index 42bd2e9..0d2e5f9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/1bc428.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_1bc428 = OpFunction %v3uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v3uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v3uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v3uint %textureDimensions_1bc428
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v3uint %textureDimensions_1bc428
          %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %54 = OpFunctionCall %v3uint %textureDimensions_1bc428
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v3uint %textureDimensions_1bc428
+         %47 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v3uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %59 = OpFunctionCall %v3uint %textureDimensions_1bc428
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v3uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.glsl
index a9e2058..b204b5f 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_1bd78c() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_1bd78c() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_1bd78c() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
index 1baa7b3..78e88cf 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_1bd78c() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bd78c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
index 1baa7b3..78e88cf 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_1bd78c() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_1bd78c();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.msl
index cbbf33a..d13afe4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_1bd78c(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.msl
index 523d6e0..c554170 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_1bd78c(texture2d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.spvasm
index 33e55f8..1e06f7f 100644
--- a/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/1bd78c.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_1bd78c = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_1bd78c
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_1bd78c
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_1bd78c
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_1bd78c
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_1bd78c
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.glsl
index de84566..d098b56 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_22b5b6() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_22b5b6() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_22b5b6() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
index 498e6fa..b83e1dd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_22b5b6() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_22b5b6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
index 498e6fa..b83e1dd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_22b5b6() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_22b5b6();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.msl
index e8eed85..a4911e2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_22b5b6(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.msl
index 9850018..da59b9d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_22b5b6(texturecube_array<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.spvasm
index f6ab12d..f5261f9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/22b5b6.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +63,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_22b5b6 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -83,44 +84,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_22b5b6
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_22b5b6
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_22b5b6
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_22b5b6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_22b5b6
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.glsl
index 00f4b34..31cf17e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_2e443d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_2e443d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_2e443d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
index 590ee10..8151a7d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_2e443d() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2e443d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
index 590ee10..8151a7d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_2e443d() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2e443d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.msl
index 7fd1195..073380e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_2e443d(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.msl
index 1403e69..b907773 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_2e443d(texture2d<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.spvasm
index e60640e..6670769 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/2e443d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
          %19 = OpTypeFunction %v2uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_2e443d = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_2e443d
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_2e443d
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_2e443d
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_2e443d
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_2e443d
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.glsl
index e113812..7891bd7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_2fd2a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_2fd2a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_2fd2a4() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
index 53eba9c..9e8d989 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_2fd2a4() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2fd2a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
index 53eba9c..9e8d989 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_2fd2a4() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_2fd2a4();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.msl
index 11ad43f..59387a6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_2fd2a4(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.msl
index 82ada0d..34f9dee 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_2fd2a4(texture2d_array<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.spvasm
index fe8fe2b..fc26b52 100644
--- a/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/2fd2a4.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +62,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_2fd2a4 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -82,44 +83,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_2fd2a4
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.glsl
index c27c5d5..88219fd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_346fee() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCubeArray arg_0;
 uvec2 textureDimensions_346fee() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_346fee() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
index 23544d0..d2ea25e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_346fee() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_346fee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
index 23544d0..d2ea25e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_346fee() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_346fee();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.msl
index 96c73d0..d3f0b67 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_346fee(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.msl
index 57fc86d..e735572 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_346fee(texturecube_array<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.spvasm
index 3561b7f..5ef23ef 100644
--- a/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/346fee.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +65,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_346fee = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,44 +82,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_346fee
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_346fee
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_346fee
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_346fee
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_346fee
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_346fee
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.glsl
index 89432fb..6cbcad4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_382b16() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_382b16() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_382b16() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
index d3d3634..3f8e853 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_382b16() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_382b16();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
index d3d3634..3f8e853 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_382b16() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_382b16();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.msl
index bb429e8..0005973 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_382b16(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.msl
index 95ee932..f02ef1d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_382b16(texturecube<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.spvasm
index 88bff56..87a1b24 100644
--- a/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/382b16.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_382b16 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_382b16
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_382b16
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_382b16
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_382b16
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_382b16
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_382b16
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.glsl
index fcb94f7..3092bb0 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3963d0() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3963d0() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3963d0() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
index 439acda..944cffe 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3963d0() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3963d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
index 439acda..944cffe 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3963d0() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3963d0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.msl
index 22176a2..c0a6e07 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_3963d0(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.msl
index 3303964..3ab53d7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_3963d0(texturecube_array<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.spvasm
index 34b69b5..2607533 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/3963d0.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +66,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3963d0 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -82,44 +83,47 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageQuerySizeLod %v3uint %24 %28
+         %32 = OpVectorShuffle %v2uint %30 %30 0 1
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_3963d0
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_3963d0
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v2uint %textureDimensions_3963d0
-         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v2uint %textureDimensions_3963d0
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %55 = OpFunctionCall %v2uint %textureDimensions_3963d0
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_3963d0
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v2uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.glsl
index a26b69a..73d5ae3 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3c66f0() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCubeArray arg_0;
 uvec2 textureDimensions_3c66f0() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3c66f0() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
index 3187109..d226f65 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3c66f0() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3c66f0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
index 3187109..d226f65 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3c66f0() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3c66f0();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.msl
index 303c521..26c7dcc 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_3c66f0(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.msl
index acc53a5..cfbe183 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_3c66f0(texturecube_array<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.spvasm
index fc9c3c2..4fba508 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/3c66f0.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +63,19 @@
          %19 = OpTypeFunction %v2uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3c66f0 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -83,44 +84,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_3c66f0
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_3c66f0
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_3c66f0
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_3c66f0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_3c66f0
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.glsl
index c166557..8ffeebd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_3fc3dc() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_3fc3dc() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_3fc3dc() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
index 5426028..9785fe9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3fc3dc() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3fc3dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
index 5426028..9785fe9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_3fc3dc() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_3fc3dc();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.msl
index b6d0a37..8e26a83 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_3fc3dc(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.msl
index f9b65d2..2fa882d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_3fc3dc(texture2d_array<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.spvasm
index ffe2d11..a30897c 100644
--- a/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/3fc3dc.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_3fc3dc = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -80,44 +81,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_3fc3dc
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.glsl
index 0b4c1fb..d61221e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_49a067() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_49a067() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_49a067() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
index 636b440..5488364 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_49a067() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_49a067();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
index 636b440..5488364 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_49a067() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_49a067();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.msl
index 99e8b03..8054c80 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_49a067(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.msl
index 7111eae..ad6333d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_49a067(texturecube<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.spvasm
index 6317572..4e55cdf 100644
--- a/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/49a067.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_49a067 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_49a067
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_49a067
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_49a067
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_49a067
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_49a067
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.glsl
index 92aa8fc..d68d476 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_528c0e() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_528c0e() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_528c0e() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
index 0bde84e..7f86ef5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_528c0e() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_528c0e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
index 0bde84e..7f86ef5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_528c0e() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_528c0e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.msl
index b686843..e342479 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_528c0e(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.msl
index 21a730a..85833fa 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_528c0e(texture2d_array<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.spvasm
index 5b382a8..84200c7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/528c0e.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_528c0e = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -80,44 +81,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_528c0e
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_528c0e
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_528c0e
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_528c0e
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_528c0e
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_528c0e
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.glsl
index 249c192..a2c41df 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_64dc74() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_64dc74() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_64dc74() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
index d56fe3f..1536f2a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_64dc74() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_64dc74();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
index d56fe3f..1536f2a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_64dc74() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_64dc74();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.msl
index 6c983cc..d4bde2c 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_64dc74(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.msl
index 90ad7a4..0348d3e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_64dc74(texturecube<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.spvasm
index 743c70b..e6e8ea3 100644
--- a/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/64dc74.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_64dc74 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -80,43 +81,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageQuerySizeLod %v2uint %24 %28
+               OpStore %res %30
+         %33 = OpLoad %v2uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_64dc74
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v2uint %textureDimensions_64dc74
+         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v2uint %textureDimensions_64dc74
-         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v2uint %textureDimensions_64dc74
+         %45 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_64dc74
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %57 = OpFunctionCall %v2uint %textureDimensions_64dc74
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v2uint %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.glsl
index bfdd0a5..6ec1d4a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_6e6c7a() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_6e6c7a() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_6e6c7a() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
index 08b4575..512545b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_6e6c7a() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6e6c7a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
index 08b4575..512545b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_6e6c7a() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6e6c7a();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.msl
index d151419..908963a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_6e6c7a(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.msl
index 638e69b..daffc8b9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_6e6c7a(texture3d<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.spvasm
index 47e0c19..6dae996 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/6e6c7a.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_6e6c7a = OpFunction %v3uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v3uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v3uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+         %38 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+         %44 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %52 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %56 = OpFunctionCall %v3uint %textureDimensions_6e6c7a
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v3uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v3uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.glsl
index 0161011..d26e31e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_6f1b5d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_6f1b5d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_6f1b5d() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
index f12538f..410db3b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_6f1b5d() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6f1b5d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
index f12538f..410db3b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_6f1b5d() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_6f1b5d();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.msl
index a9fc796..0ebe7de 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_6f1b5d(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.msl
index ea634aa..7c37dab 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_6f1b5d(depth2d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.spvasm
index f2ec602..a0d52c3 100644
--- a/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/6f1b5d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_6f1b5d = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_6f1b5d
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.glsl
index c2b825a..a922ebe 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_756031() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_756031() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_756031() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
index 84a254b..b82b951 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_756031() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_756031();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
index 84a254b..b82b951 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_756031() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_756031();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.msl
index 0689945..44567b1 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_756031(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.msl
index d4259bf..f0bc72e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_756031(texture3d<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.spvasm
index ef67b9e..0318164 100644
--- a/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/756031.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
          %19 = OpTypeFunction %v3uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_756031 = OpFunction %v3uint None %19
          %20 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v3uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v3uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v3uint %textureDimensions_756031
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v3uint %textureDimensions_756031
          %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %54 = OpFunctionCall %v3uint %textureDimensions_756031
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v3uint %textureDimensions_756031
+         %47 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v3uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %59 = OpFunctionCall %v3uint %textureDimensions_756031
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v3uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.glsl
index c15996c..1d4c66c 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_79d168() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_79d168() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_79d168() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
index 7a0e261..8c65094 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_79d168() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_79d168();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
index 7a0e261..8c65094 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_79d168() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_79d168();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.msl
index b8c8f84..c89753d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_79d168(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.msl
index 94841d6..a52f867 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_79d168(depthcube<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.spvasm
index a12b0cf..786a785 100644
--- a/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/79d168.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_79d168 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_79d168
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_79d168
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_79d168
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_79d168
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_79d168
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.glsl
index 16c64c8..48e0249 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_920006() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_920006() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_920006() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
index 0846332..dca8298 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_920006() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_920006();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
index 0846332..dca8298 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_920006() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_920006();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.msl
index d9f2deb..30a792a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_920006(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
+  min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.msl
index 16935ff..a7d28f9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_920006(texture1d<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.spvasm
index 212ea97..91173fd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/920006.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_920006 = OpFunction %uint None %17
          %18 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %7 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageQuerySizeLod %uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %24
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySizeLod %uint %23 %29
+               OpStore %res %31
+         %34 = OpLoad %uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %uint %textureDimensions_920006
-         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %uint %textureDimensions_920006
          %40 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %53 = OpFunctionCall %uint %textureDimensions_920006
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %uint %textureDimensions_920006
+         %46 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %58 = OpFunctionCall %uint %textureDimensions_920006
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.glsl
index c8163ef..18c23ee 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_991ea9() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uvec2 textureDimensions_991ea9() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_991ea9() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
index 2c9cbd2..4425ff6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_991ea9() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_991ea9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
index 2c9cbd2..4425ff6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_991ea9() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_991ea9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.msl
index efe24b8..ac90314 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_991ea9(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.msl
index ca5b4fb..fb8b60e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_991ea9(depth2d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.spvasm
index 3687410..0f08414 100644
--- a/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/991ea9.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_991ea9 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_991ea9
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_991ea9
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_991ea9
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_991ea9
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_991ea9
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_991ea9
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.glsl
index 1851f15..a24c015 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9baf27() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9baf27() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9baf27() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
index a80f438..2ee630d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9baf27() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9baf27();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
index a80f438..2ee630d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9baf27() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9baf27();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.msl
index 4e0de58..fedd94e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_9baf27(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.msl
index 22978fd..3da816b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_9baf27(texturecube<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.spvasm
index 4d2fd96..e0a0619 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/9baf27.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9baf27 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_9baf27
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_9baf27
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_9baf27
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_9baf27
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_9baf27
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_9baf27
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.glsl
index 2a460f7..2bbc5c9 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_9c7a00() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uint textureDimensions_9c7a00() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_9c7a00() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
index f02e29b..b74b737 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_9c7a00() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9c7a00();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
index f02e29b..b74b737 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_9c7a00() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9c7a00();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.msl
index 02e96d3..ac65425 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_9c7a00(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
+  min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.msl
index 3794f09..76be688 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_9c7a00(texture1d<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.spvasm
index 12fb03b..0fdef3f 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/9c7a00.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,15 +62,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9c7a00 = OpFunction %uint None %17
          %18 = OpLabel
@@ -78,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %22 = OpLoad %7 %arg_0 None
          %23 = OpLoad %uint %arg_1 None
-         %24 = OpImageQuerySizeLod %uint %22 %23
-               OpStore %res %24
-         %26 = OpLoad %uint %res None
-               OpReturnValue %26
+         %24 = OpImageQueryLevels %uint %22
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %23 %25
+         %28 = OpImageQuerySizeLod %uint %22 %26
+               OpStore %res %28
+         %30 = OpLoad %uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %uint %textureDimensions_9c7a00
-         %32 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %uint %textureDimensions_9c7a00
+         %36 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %uint %textureDimensions_9c7a00
-         %38 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %uint %textureDimensions_9c7a00
+         %42 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %50 = OpFunctionCall %uint %textureDimensions_9c7a00
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %54 = OpFunctionCall %uint %textureDimensions_9c7a00
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %uint %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.glsl
index 7b093d6..1775a34 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9cd4ca() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usamplerCube arg_0;
 uvec2 textureDimensions_9cd4ca() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9cd4ca() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
index 9f9032d..f837e59 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9cd4ca() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9cd4ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
index 9f9032d..f837e59 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9cd4ca() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9cd4ca();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.msl
index 10086e2..62c19d3 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_9cd4ca(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.msl
index 01b9841..d5490c2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_9cd4ca(texturecube<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.spvasm
index 81beb00..9a05e4f 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/9cd4ca.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9cd4ca = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_9cd4ca
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.glsl
index 7287e30..5e5cc60 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_9e0794() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec2 textureDimensions_9e0794() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_9e0794() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
index 4d1f6d7..c0a6fa4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9e0794() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9e0794();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
index 4d1f6d7..c0a6fa4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_9e0794() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_9e0794();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.msl
index 3f9f802..4674597 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_9e0794(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.msl
index 88224ec..02c5535 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_9e0794(texture2d_array<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.spvasm
index 019ad78..8a500e4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/9e0794.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +62,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_9e0794 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -82,44 +83,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_9e0794
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_9e0794
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_9e0794
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_9e0794
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_9e0794
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.glsl
index ff24909..37a4721 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_a2ba5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isamplerCube arg_0;
 uvec2 textureDimensions_a2ba5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isamplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_a2ba5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
index 3eec7a9..83b1bd6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_a2ba5e() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a2ba5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
index 3eec7a9..83b1bd6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_a2ba5e() {
   int arg_1 = int(1);
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a2ba5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.msl
index 57102ff..1a12652 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_a2ba5e(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.msl
index 23499a6..87cecc6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_a2ba5e(texturecube<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.spvasm
index 811c9f5..70d88bb 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/a2ba5e.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
          %19 = OpTypeFunction %v2uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_a2ba5e = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v2uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
          %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_a2ba5e
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.glsl
index 2982d9e..b5d2b00 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_a48049() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uvec2 textureDimensions_a48049() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_a48049() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
index 3d5b623..ed844f5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_a48049() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a48049();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
index 3d5b623..ed844f5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_a48049() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_a48049();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.msl
index e8e565e..786a2dc 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_a48049(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.msl
index b363763..a1f5224 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_a48049(texture2d<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.spvasm
index 770ffb4..45c71ca 100644
--- a/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/a48049.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_a48049 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -80,43 +81,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageQuerySizeLod %v2uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v2uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageQuerySizeLod %v2uint %24 %28
+               OpStore %res %30
+         %33 = OpLoad %v2uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v2uint %textureDimensions_a48049
-         %35 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v2uint %textureDimensions_a48049
+         %39 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v2uint %textureDimensions_a48049
-         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v2uint %textureDimensions_a48049
+         %45 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %53 = OpFunctionCall %v2uint %textureDimensions_a48049
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %57 = OpFunctionCall %v2uint %textureDimensions_a48049
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v2uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v2uint %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.glsl
index c0870d2..6f3fc3a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_aac604() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_aac604() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_aac604() {
   uint arg_1 = 1u;
-  uint res = uvec2(textureSize(arg_0, int(arg_1))).x;
+  uint res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u))))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
index 971f45f..d2ed063 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_aac604() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_aac604();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
index 971f45f..d2ed063 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_aac604() {
   uint arg_1 = 1u;
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_aac604();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.msl
index 12de25d..e1e6158 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_aac604(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
+  min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.msl
index 2c6ee66..de3e909 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_aac604(texture1d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.spvasm
index 1c18dde..9a00776 100644
--- a/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/aac604.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,15 +62,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
+         %49 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %48 = OpConstantNull %v4float
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_aac604 = OpFunction %uint None %17
          %18 = OpLabel
@@ -78,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %22 = OpLoad %7 %arg_0 None
          %23 = OpLoad %uint %arg_1 None
-         %24 = OpImageQuerySizeLod %uint %22 %23
-               OpStore %res %24
-         %26 = OpLoad %uint %res None
-               OpReturnValue %26
+         %24 = OpImageQueryLevels %uint %22
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %23 %25
+         %28 = OpImageQuerySizeLod %uint %22 %26
+               OpStore %res %28
+         %30 = OpLoad %uint %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %uint %textureDimensions_aac604
-         %32 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %uint %textureDimensions_aac604
+         %36 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %uint %textureDimensions_aac604
-         %38 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %uint %textureDimensions_aac604
+         %42 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %48 None
-         %49 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %50 = OpFunctionCall %uint %textureDimensions_aac604
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %52 None
+         %53 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %54 = OpFunctionCall %uint %textureDimensions_aac604
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %uint %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %33
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %uint %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.glsl
index bea2ce3..83d3c40 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_b3ab5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_b3ab5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_b3ab5e() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
index 7e202a5..1971011 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_b3ab5e() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b3ab5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
index 7e202a5..1971011 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_b3ab5e() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b3ab5e();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.msl
index d2f1c82..0cdb037 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_b3ab5e(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.msl
index e798c05..5abcf3a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_b3ab5e(texturecube_array<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.spvasm
index 7cf69d6..d65bad5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/b3ab5e.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +63,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_b3ab5e = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -83,44 +84,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_b3ab5e
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.glsl
index 1af6456..a01bf00 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_b46d97() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 uint textureDimensions_b46d97() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_b46d97() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
index 7e3083a..0761d7a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_b46d97() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b46d97();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
index 7e3083a..0761d7a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_b46d97() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_b46d97();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.msl
index be500a6..3cfd7d6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_b46d97(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
+  min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.msl
index 918ad9c..6834649 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_b46d97(texture1d<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.spvasm
index ef9673c..9c50401 100644
--- a/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/b46d97.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
          %18 = OpTypeFunction %uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_b46d97 = OpFunction %uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %7 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageQuerySizeLod %uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %24
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySizeLod %uint %23 %29
+               OpStore %res %31
+         %34 = OpLoad %uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %uint %textureDimensions_b46d97
-         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %uint %textureDimensions_b46d97
          %40 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %53 = OpFunctionCall %uint %textureDimensions_b46d97
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %uint %textureDimensions_b46d97
+         %46 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %58 = OpFunctionCall %uint %textureDimensions_b46d97
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.glsl
index e47d66d..78dc91e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_bd94c8() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_bd94c8() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_bd94c8() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
index 141a657..c31f0f0 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_bd94c8() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_bd94c8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
index 141a657..c31f0f0 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_bd94c8() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_bd94c8();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.msl
index 43a55f1..dbd177e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_bd94c8(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.msl
index ebdc7a5..5869c76 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_bd94c8(depthcube_array<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.spvasm
index 4238f21..ca2feb4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/bd94c8.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +65,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_bd94c8 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,44 +82,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_bd94c8
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_bd94c8
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.glsl
index 6e6b337..36b1ef6 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_c871f3() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 uvec3 textureDimensions_c871f3() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_c871f3() {
   uint arg_1 = 1u;
-  uvec3 res = uvec3(textureSize(arg_0, int(arg_1)));
+  uvec3 res = uvec3(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
index 20e3d98..2788278 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_c871f3() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_c871f3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
index 20e3d98..2788278 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_c871f3() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_c871f3();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.msl
index 61c6d10..3fc07f4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_c871f3(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.msl
index 46b00dd..01ed586 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_c871f3(texture3d<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.spvasm
index 6382339..f536816 100644
--- a/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/c871f3.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_c871f3 = OpFunction %v3uint None %19
          %20 = OpLabel
@@ -80,43 +81,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v3uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageQuerySizeLod %v3uint %24 %28
+               OpStore %res %30
+         %33 = OpLoad %v3uint %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v3uint %textureDimensions_c871f3
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v3uint %textureDimensions_c871f3
+         %39 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v3uint %textureDimensions_c871f3
-         %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v3uint %textureDimensions_c871f3
+         %45 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %53 = OpFunctionCall %v3uint %textureDimensions_c871f3
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %57 = OpFunctionCall %v3uint %textureDimensions_c871f3
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v3uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v3uint %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.glsl
index 4df3636..793cdbd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_cf2b50() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCubeArray arg_0;
 uvec2 textureDimensions_cf2b50() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 460
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_cf2b50() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
index 9b908fc..160cb1e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_cf2b50() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_cf2b50();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
index 9b908fc..160cb1e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_cf2b50() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_cf2b50();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.msl
index 77484c4..acc7bb7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_cf2b50(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.msl
index e9903cb..7ee61e5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_cf2b50(texturecube_array<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.spvasm
index 5e398ec..fc22e87 100644
--- a/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/cf2b50.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +65,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_cf2b50 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -81,44 +82,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_cf2b50
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_cf2b50
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.glsl
index db36ee7..4f89174 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_d3accd() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp samplerCube arg_0;
 uvec2 textureDimensions_d3accd() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_d3accd() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
index 7e7651d..6860515 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_d3accd() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_d3accd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
index 7e7651d..6860515 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_d3accd() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_d3accd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.msl
index 80ab6f4..5ec346d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_d3accd(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.msl
index 7661dfe..96547ed 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_d3accd(depthcube<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.spvasm
index 705ae43..0d8724a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/d3accd.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_d3accd = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_d3accd
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_d3accd
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_d3accd
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_d3accd
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_d3accd
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_d3accd
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.glsl
index 74786df..14b9392 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_dfdc32() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_dfdc32() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_dfdc32() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
index b91caf8..efeab63 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_dfdc32() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_dfdc32();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
index b91caf8..efeab63 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_dfdc32() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_dfdc32();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.msl
index 310869a..29c9780 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_dfdc32(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.msl
index 28f8113..b32dbc2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_dfdc32(depth2d_array<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.spvasm
index 02f9e7a..75ad523 100644
--- a/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/dfdc32.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +62,19 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_dfdc32 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -82,44 +83,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_dfdc32
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_dfdc32
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_dfdc32
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_dfdc32
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_dfdc32
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.glsl
index 4a8eb28..4c0b730 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_e18a8b() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec2 textureDimensions_e18a8b() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_e18a8b() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)));
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
index af50c6c..b90433b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_e18a8b() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e18a8b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
index af50c6c..b90433b 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_e18a8b() {
   uint arg_1 = 1u;
   uint3 v = (0u).xxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e18a8b();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.msl
index a8c7721..205e4ea 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_e18a8b(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.msl
index d315080..772f2eb 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_e18a8b(texture2d<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.spvasm
index 26eca0d..82b8eeb 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/e18a8b.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,15 +63,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e18a8b = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -79,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v2uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %v2uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v2uint %23 %27
+               OpStore %res %29
+         %32 = OpLoad %v2uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+         %38 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+         %44 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %52 = OpFunctionCall %v2uint %textureDimensions_e18a8b
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %56 = OpFunctionCall %v2uint %textureDimensions_e18a8b
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v2uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v2uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.glsl
index 395286a..c693252 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_e4e310() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_e4e310() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_e4e310() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
index 77f9205..51ce05e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_e4e310() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e4e310();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
index 77f9205..51ce05e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_e4e310() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e4e310();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.msl
index 49856dc..4379021 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_e4e310(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.msl
index ec3b270..07519c7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_e4e310(texture2d_array<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.spvasm
index 76f70f2..9551400 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/e4e310.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +65,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e4e310 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -81,44 +82,47 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageQuerySizeLod %v3uint %24 %28
+         %32 = OpVectorShuffle %v2uint %30 %30 0 1
+               OpStore %res %32
+         %35 = OpLoad %v2uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_e4e310
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v2uint %textureDimensions_e4e310
+         %41 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v2uint %textureDimensions_e4e310
-         %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v2uint %textureDimensions_e4e310
+         %47 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %55 = OpFunctionCall %v2uint %textureDimensions_e4e310
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %59 = OpFunctionCall %v2uint %textureDimensions_e4e310
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v2uint %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v2uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.glsl
index e744e70..a8a2dc1 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_e5a203() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec3 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec3 textureDimensions_e5a203() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_2))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec3 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec3 vertex_main_loc0_Output;
 uvec3 textureDimensions_e5a203() {
   int arg_1 = 1;
-  uvec3 res = uvec3(textureSize(arg_0, arg_1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 res = uvec3(textureSize(arg_0, int(min(uint(arg_1), v_1))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
index 1bf7608..7ee7812 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_e5a203() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e5a203();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
index 1bf7608..7ee7812 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint3 textureDimensions_e5a203() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint3 res = v.xyz;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 res = v_1.xyz;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_e5a203();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.msl
index d7a2b09..de595aa 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint3 textureDimensions_e5a203(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint3 res = uint3(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v), tint_module_vars.arg_0.get_depth(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.msl
index 3b2be48..b7181b2 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint3 textureDimensions_e5a203(texture3d<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint3 res = uint3(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1), tint_symbol_1.get_depth(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 res = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.spvasm
index 87a117e..633b515 100644
--- a/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/e5a203.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v3uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_e5a203 = OpFunction %v3uint None %18
          %19 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-               OpStore %res %26
-         %29 = OpLoad %v3uint %res None
-               OpReturnValue %29
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+               OpStore %res %32
+         %35 = OpLoad %v3uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v3uint %textureDimensions_e5a203
-         %35 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v3uint %textureDimensions_e5a203
          %41 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
-         %54 = OpFunctionCall %v3uint %textureDimensions_e5a203
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v3uint %textureDimensions_e5a203
+         %47 = OpAccessChain %_ptr_StorageBuffer_v3uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v3uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v3uint %out %uint_1
+         %59 = OpFunctionCall %v3uint %textureDimensions_e5a203
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v3uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.glsl
index 585dbce..6a716dd 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.glsl
@@ -2,14 +2,23 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_eafe19() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 void main() {
@@ -17,14 +26,23 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 uvec2 textureDimensions_eafe19() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v_1.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +52,24 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_eafe19() {
   uint arg_1 = 1u;
-  uvec2 res = uvec2(textureSize(arg_0, int(arg_1)).xy);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(arg_1, (v.inner.tint_builtin_value_0 - 1u)))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +79,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
index c8e1020..5c7cb17 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_eafe19() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_eafe19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
index c8e1020..5c7cb17 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_eafe19() {
   uint arg_1 = 1u;
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(arg_1, (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_eafe19();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.msl
index 1b32c8a..401c95d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_eafe19(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint const v = arg_1;
+  uint const v = min(arg_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.msl
index f837572..16fec1a 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_eafe19(depth2d_array<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.spvasm
index 3499b73..ea56e83 100644
--- a/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/eafe19.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +64,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_eafe19 = OpFunction %v2uint None %18
          %19 = OpLabel
@@ -80,44 +81,47 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageQuerySizeLod %v3uint %23 %24
-         %27 = OpVectorShuffle %v2uint %25 %25 0 1
-               OpStore %res %27
-         %30 = OpLoad %v2uint %res None
-               OpReturnValue %30
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %v3uint %23 %27
+         %31 = OpVectorShuffle %v2uint %29 %29 0 1
+               OpStore %res %31
+         %34 = OpLoad %v2uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v2uint %textureDimensions_eafe19
-         %36 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v2uint %textureDimensions_eafe19
+         %40 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v2uint %textureDimensions_eafe19
-         %42 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v2uint %textureDimensions_eafe19
+         %46 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %54 = OpFunctionCall %v2uint %textureDimensions_eafe19
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %58 = OpFunctionCall %v2uint %textureDimensions_eafe19
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v2uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v2uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.glsl
index 1fac5de..9792c50 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_f17acd() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uint inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 uint textureDimensions_f17acd() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2)))).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uint prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out uint vertex_main_loc0_Output;
 uint textureDimensions_f17acd() {
   int arg_1 = 1;
-  uint res = uvec2(textureSize(arg_0, arg_1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1)))).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
index a2eae25..049e4a4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_f17acd() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_f17acd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
index a2eae25..049e4a4 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint textureDimensions_f17acd() {
   int arg_1 = int(1);
   uint2 v = (0u).xx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y);
-  uint res = v.x;
+  arg_0.GetDimensions(0u, v.x, v.y);
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.y - 1u))), v_1.x, v_1.y);
+  uint res = v_1.x;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_f17acd();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.msl
index 926ac98..6e4b7a1 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
 
 uint textureDimensions_f17acd(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
+  min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint res = uint(tint_module_vars.arg_0.get_width());
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.msl
index 538f74e..9deb93d5 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.msl
@@ -3,6 +3,7 @@
 using namespace metal;
 uint textureDimensions_f17acd(texture1d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
   uint res = tint_symbol_1.get_width(0);
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.spvasm
index 3451e91..18f1b71 100644
--- a/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/f17acd.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %uint
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_f17acd = OpFunction %uint None %17
          %18 = OpLabel
@@ -81,43 +82,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %7 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageQuerySizeLod %uint %23 %24
-               OpStore %res %25
-         %28 = OpLoad %uint %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %24
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySizeLod %uint %23 %29
+               OpStore %res %31
+         %34 = OpLoad %uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %uint %textureDimensions_f17acd
-         %34 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %uint %textureDimensions_f17acd
          %40 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_uint %out %uint_1
-         %53 = OpFunctionCall %uint %textureDimensions_f17acd
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+         %45 = OpFunctionCall %uint %textureDimensions_f17acd
+         %46 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %uint %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_uint %out %uint_1
+         %58 = OpFunctionCall %uint %textureDimensions_f17acd
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.glsl
index e04fed9..5fad81e 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.glsl
@@ -2,14 +2,24 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_fdf6e9() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 void main() {
@@ -17,14 +27,24 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec2 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 uvec2 textureDimensions_fdf6e9() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_2 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_2))).xy);
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -34,16 +54,25 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec2 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out uvec2 vertex_main_loc0_Output;
 uvec2 textureDimensions_fdf6e9() {
   int arg_1 = 1;
-  uvec2 res = uvec2(textureSize(arg_0, arg_1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 res = uvec2(textureSize(arg_0, int(min(uint(arg_1), v_1))).xy);
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +82,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
index e4e5611..fb89701 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_fdf6e9() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_fdf6e9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
index e4e5611..fb89701 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.fxc.hlsl
@@ -14,8 +14,10 @@
 uint2 textureDimensions_fdf6e9() {
   int arg_1 = int(1);
   uint4 v = (0u).xxxx;
-  arg_0.GetDimensions(uint(arg_1), v.x, v.y, v.z, v.w);
-  uint2 res = v.xy;
+  arg_0.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(uint(arg_1), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 res = v_1.xy;
   return res;
 }
 
@@ -32,13 +34,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureDimensions_fdf6e9();
-  VertexOutput v_1 = tint_symbol;
-  return v_1;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
-  return v_3;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.msl
index f3d0d7e..4e7d3cc 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 
 uint2 textureDimensions_fdf6e9(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint const v = uint(arg_1);
+  uint const v = min(uint(arg_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
   uint2 res = uint2(tint_module_vars.arg_0.get_width(v), tint_module_vars.arg_0.get_height(v));
   return res;
 }
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.msl
index 7504ce6..8d10d6d 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.msl
@@ -3,7 +3,8 @@
 using namespace metal;
 uint2 textureDimensions_fdf6e9(texture2d_array<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
-  uint2 res = uint2(tint_symbol_1.get_width(arg_1), tint_symbol_1.get_height(arg_1));
+  uint const level_idx = min(uint(arg_1), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 res = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.spvasm
index ea720d4..e4160e7 100644
--- a/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureDimensions/fdf6e9.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +62,19 @@
          %19 = OpTypeFunction %v2uint
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v2uint = OpTypePointer StorageBuffer %v2uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v2uint
-         %46 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureDimensions_fdf6e9 = OpFunction %v2uint None %19
          %20 = OpLabel
@@ -82,44 +83,48 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageQuerySizeLod %v3uint %24 %25
-         %28 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %res %28
-         %31 = OpLoad %v2uint %res None
-               OpReturnValue %31
+         %26 = OpImageQueryLevels %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %v3uint %24 %30
+         %34 = OpVectorShuffle %v2uint %32 %32 0 1
+               OpStore %res %34
+         %37 = OpLoad %v2uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
+%fragment_main = OpFunction %void None %40
          %41 = OpLabel
          %42 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
          %43 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
                OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
+%compute_main = OpFunction %void None %40
          %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
-         %56 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %48 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
+         %49 = OpAccessChain %_ptr_StorageBuffer_v2uint %1 %uint_0
+               OpStore %49 %48 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v2uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v2uint %out %uint_1
+         %61 = OpFunctionCall %v2uint %textureDimensions_fdf6e9
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v2uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
index 529a8d2..d23e741 100644
--- a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_012e11() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
index 529a8d2..d23e741 100644
--- a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_012e11() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.msl
index 70c93ff..13ca049 100644
--- a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_012e11(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.msl
index 0d012f2..cac7ba6 100644
--- a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_012e11(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.spvasm
index 32f247f..6f82387 100644
--- a/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/012e11.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_012e11 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_012e11
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_012e11
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_012e11
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_012e11
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.glsl
index ac31cdb..42948d6 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_019da0() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_019da0() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_019da0() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
index ceedf63..6315e0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_019da0() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_019da0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
index ceedf63..6315e0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_019da0() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_019da0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.msl
index e44f962..b0e41b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_019da0(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.msl
index acbf3a2..0b701d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_019da0(texture3d<float, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.spvasm
index 77c3d52..81d4094 100644
--- a/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/019da0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,16 +65,18 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %37 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %62 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_019da0 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v3int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %v3uint %27 %32
+         %36 = OpISub %v3uint %34 %37
+         %38 = OpBitcast %v3uint %28
+         %39 = OpExtInst %v3uint %33 UMin %38 %36
+         %40 = OpImageFetch %v4float %27 %39 Lod %32
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_019da0
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_019da0
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_019da0
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_019da0
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_019da0
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %66 = OpFunctionCall %v4float %textureLoad_019da0
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.glsl
index 55f6e62..d4c4bec 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_01cd01() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_01cd01() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
index 748553a..aceadc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_01cd01() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
index 748553a..aceadc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_01cd01() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.msl
index 4893ff6..42234ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_01cd01(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.msl
index 209eb86..d8024e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_01cd01(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.spvasm
index 83c5de4..124d2f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/01cd01.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_01cd01 = OpFunction %v4int None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4int %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4int %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_01cd01
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_01cd01
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_01cd01
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_01cd01
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.glsl
index 780c1de..3e32207 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_026217() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_026217() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_026217() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
index 15d03ff..4d034b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_026217();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
index 15d03ff..4d034b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_026217();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.msl
index a03fd16..e3dc1f0 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.msl
index b6dea01..b261bd9 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.spvasm
index a21e1e8..d6c64c7 100644
--- a/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/026217.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,17 +70,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %55 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_026217 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -93,44 +95,56 @@
          %32 = OpLoad %v2uint %arg_1 None
          %33 = OpLoad %uint %arg_2 None
          %34 = OpLoad %int %arg_3 None
-         %36 = OpCompositeConstruct %v3uint %32 %33
-         %37 = OpImageFetch %v4uint %31 %36 Lod %34
-               OpStore %res %37
-         %40 = OpLoad %v4uint %res None
-               OpReturnValue %40
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpExtInst %uint %41 UMin %33 %39
+         %42 = OpImageQueryLevels %uint %31
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %34
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %23
+         %49 = OpExtInst %v2uint %41 UMin %32 %48
+         %50 = OpCompositeConstruct %v3uint %49 %40
+         %51 = OpImageFetch %v4uint %31 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4uint %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_026217
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4uint %textureLoad_026217
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4uint %textureLoad_026217
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %52 %51 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
          %64 = OpFunctionCall %v4uint %textureLoad_026217
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %65 %64 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4uint %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %77 = OpFunctionCall %v4uint %textureLoad_026217
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4uint %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
index b1ea2ab..ab612d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02c48d() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
index b1ea2ab..ab612d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02c48d() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.msl
index f3e46e9..ae69584 100644
--- a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_02c48d(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.msl
index c72343e..8357905 100644
--- a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_02c48d(texture3d<uint, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.spvasm
index d5f9e5d..2a97d10 100644
--- a/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/02c48d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_02c48d = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %20 = OpISub %v3uint %19 %15
+         %21 = OpExtInst %v3uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_02c48d
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_02c48d
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_02c48d
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_02c48d
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.glsl
index eaf29d9..4066659 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_02ef1f() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_02ef1f() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
index f17854f..79094f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02ef1f() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
index f17854f..79094f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_02ef1f() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.msl
index e77d805..1c04ee0 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_02ef1f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.msl
index 54e81c7..50ccdd2 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_02ef1f(texture2d<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.spvasm
index cb45a0a..8b35497 100644
--- a/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/02ef1f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_02ef1f = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %19
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_02ef1f
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_02ef1f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_02ef1f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_02ef1f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
index caba775..14e81e9 100644
--- a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_03e03e() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
index caba775..14e81e9 100644
--- a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_03e03e() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.msl
index ca83e74..5db2406 100644
--- a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_03e03e(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.msl
index fe27de6..3183bde 100644
--- a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_03e03e(texture3d<int, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.spvasm
index 3fe3372..1db62ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/03e03e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_03e03e = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %22 = OpISub %v3uint %19 %23
+         %25 = OpBitcast %v3uint %18
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_03e03e
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_03e03e
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_03e03e
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_03e03e
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.glsl
index 6273de1..a619bbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_045ec9() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_045ec9() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_045ec9() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
index d5f4aba..eab228f 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_045ec9() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_045ec9();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
index d5f4aba..eab228f 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_045ec9() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_045ec9();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.msl
index f00cd59..e9fd8ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_045ec9(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.msl
index 95dfcbe..a107ca4 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_045ec9(texture3d<int, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.spvasm
index e55d094..cd4cf3e 100644
--- a/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/045ec9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_045ec9 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %29 = OpISub %v3uint %28 %24
+         %30 = OpExtInst %v3uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_045ec9
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_045ec9
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_045ec9
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_045ec9
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_045ec9
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_045ec9
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.glsl
index 304e525..75b4dd0 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_04b911() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  float res = texelFetch(arg_0, v_9, int(v_7)).x;
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_04b911() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  float res = texelFetch(arg_0, v_9, int(v_7)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_04b911() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  float res = texelFetch(arg_0, v_8, int(v_6)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
index 3d95c4f..7f27fb8 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  float res = arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_04b911();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
index 3d95c4f..7f27fb8 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  float res = arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_04b911();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.msl
index 583cd42..f8ba243 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.msl
index ab5e88a..fe7e1e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_04b911(depth2d_array<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.spvasm
index 72b2e25..f300ff8 100644
--- a/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/04b911.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,17 +68,17 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %56 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %55 = OpTypeFunction %VertexOutput
+         %67 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %71 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %74 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_04b911 = OpFunction %float None %15
          %16 = OpLabel
@@ -91,46 +93,57 @@
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
          %32 = OpLoad %uint %arg_3 None
-         %33 = OpBitcast %uint %31
-         %35 = OpCompositeConstruct %v3uint %30 %33
-         %36 = OpImageFetch %v4float %29 %35 Lod %32
-         %37 = OpCompositeExtract %float %36 0
-               OpStore %res %37
-         %40 = OpLoad %float %res None
-               OpReturnValue %40
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpBitcast %uint %31
+         %39 = OpExtInst %uint %40 UMin %38 %37
+         %41 = OpImageQueryLevels %uint %29
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %32 %42
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %40 UMin %30 %46
+         %48 = OpCompositeConstruct %v3uint %47 %39
+         %49 = OpImageFetch %v4float %29 %48 Lod %43
+         %50 = OpCompositeExtract %float %49 0
+               OpStore %res %50
+         %53 = OpLoad %float %res None
+               OpReturnValue %53
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_04b911
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %56
+         %57 = OpLabel
+         %58 = OpFunctionCall %float %textureLoad_04b911
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %float %textureLoad_04b911
-         %52 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %56
+         %62 = OpLabel
+         %63 = OpFunctionCall %float %textureLoad_04b911
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %64 = OpFunctionCall %float %textureLoad_04b911
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %67
+         %68 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %71
+         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %76 = OpFunctionCall %float %textureLoad_04b911
+               OpStore %75 %76 None
+         %77 = OpLoad %VertexOutput %out None
+               OpReturnValue %77
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %float %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %56
+         %79 = OpLabel
+         %80 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %81 = OpCompositeExtract %v4float %80 0
+               OpStore %vertex_main_position_Output %81 None
+         %82 = OpCompositeExtract %float %80 1
+               OpStore %vertex_main_loc0_Output %82 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.glsl
index 902e28a..7efa1c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_050c33() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_050c33() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_050c33() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
index bcb35a7..6d42a31 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_050c33() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_050c33();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
index bcb35a7..6d42a31 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_050c33() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_050c33();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.msl
index 4c0a8c8..e7c07a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_050c33(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.msl
index d7b8dd7..02f958a 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_050c33(texture2d<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.spvasm
index 6b35611..e7935be 100644
--- a/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/050c33.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_050c33 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -84,43 +88,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %30 = OpISub %v2uint %28 %31
+         %33 = OpBitcast %v2uint %27
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_050c33
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_050c33
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_050c33
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_050c33
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_050c33
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_050c33
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
index b94c580..93e374a 100644
--- a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_054350() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
index b94c580..93e374a 100644
--- a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_054350() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.msl
index 13556e2..f88a19a 100644
--- a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_054350(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.msl
index 84b57ee..0694780 100644
--- a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_054350(texture1d<uint, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.spvasm
index 47e7fe3..38d0c76 100644
--- a/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/054350.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,7 +41,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_054350 = OpFunction %v4uint None %10
@@ -49,22 +51,25 @@
                OpStore %arg_1 %uint_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %uint %arg_1 None
-         %17 = OpImageRead %v4uint %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %18 = OpISub %uint %17 %uint_1
+         %19 = OpExtInst %uint %20 UMin %16 %18
+         %21 = OpImageRead %v4uint %15 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_054350
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4uint %textureLoad_054350
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_054350
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_054350
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.glsl
index 2a89a20..8665758 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_0674b1() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_0674b1() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_0674b1() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
index 4687540..8ea8fb2 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_0674b1() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0674b1();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
index 4687540..8ea8fb2 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_0674b1() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0674b1();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.msl
index ce9e349..70d0b90 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_0674b1(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.msl
index 7b64494..449d77b 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_0674b1(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.spvasm
index bc4b9e6..a60ee2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/0674b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_0674b1 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_0674b1
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_0674b1
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_0674b1
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_0674b1
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_0674b1
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_0674b1
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.glsl
index db7fe43..139af78 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_06ac37() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_06ac37() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_06ac37() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
index e4ed3f4..ccd7f21 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_06ac37() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_06ac37();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
index e4ed3f4..ccd7f21 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_06ac37() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_06ac37();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.msl
index 78725ee..3d3e8a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_06ac37(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.msl
index d0697d0..8d469a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_06ac37(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.spvasm
index 843a441..e6e21ba 100644
--- a/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/06ac37.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_06ac37 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,44 +86,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_06ac37
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_06ac37
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_06ac37
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_06ac37
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_06ac37
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_06ac37
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.glsl
index da7418b..d29eb88 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_072e26() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_072e26() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_072e26() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
index 1455f36..7079063 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_072e26() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_072e26();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
index 1455f36..7079063 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_072e26() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_072e26();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.msl
index ef0f377..111518a 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_072e26(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.msl
index 276549e..c7b01a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_072e26(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.spvasm
index c88a4cb..35c37da 100644
--- a/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/072e26.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_072e26 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,44 +90,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_072e26
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_072e26
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_072e26
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_072e26
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_072e26
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_072e26
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.glsl
index 46c9eca..cd64d19 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_078bc4() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_078bc4() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_078bc4() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
index 754256e..a9544d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_078bc4() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_078bc4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
index 754256e..a9544d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_078bc4() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_078bc4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.msl
index 33314ee..cdb0b46 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_078bc4(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.msl
index ddf667d..27f0552 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_078bc4(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.spvasm
index f55da49..d81b1ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/078bc4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_078bc4 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_078bc4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_078bc4
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_078bc4
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_078bc4
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_078bc4
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_078bc4
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
index 92fc551..be8225d 100644
--- a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_0b515a() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
index 92fc551..be8225d 100644
--- a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_0b515a() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.msl
index 290568c..f9bc95b 100644
--- a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_0b515a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.msl
index 089fd66..e9cf678 100644
--- a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_0b515a(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.spvasm
index af1edd8..c5d8323 100644
--- a/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/0b515a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_0b515a = OpFunction %v4int None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4int %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4int %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_0b515a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_0b515a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_0b515a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_0b515a
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.glsl
index f3ca7f4..65a8e7e 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_0cb698() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_0cb698() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_0cb698() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
index 2131105..3417ecc 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_0cb698() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0cb698();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
index 2131105..3417ecc 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_0cb698() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_0cb698();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.msl
index 27d15f3..bbb351e 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_0cb698(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.msl
index 71d9b88..18da811 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_0cb698(texture1d<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.spvasm
index 99a8d76..2b3792f 100644
--- a/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/0cb698.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_0cb698 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -84,43 +86,49 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4int %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpExtInst %uint %31 UMin %27 %29
+         %32 = OpImageQuerySizeLod %uint %25 %30
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %31 UMin %26 %33
+         %35 = OpImageFetch %v4int %25 %34 Lod %30
+               OpStore %res %35
+         %38 = OpLoad %v4int %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_0cb698
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_0cb698
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_0cb698
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_0cb698
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_0cb698
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %62 = OpFunctionCall %v4int %textureLoad_0cb698
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4int %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.glsl
index 518a914..57dfae7 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_10db82() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_10db82() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_10db82() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
index 82d919a..b0abcbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_10db82() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_10db82();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
index 82d919a..b0abcbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_10db82() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_10db82();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.msl
index 561f82f..0c84f7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_10db82(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.msl
index 258dc61..5341161 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_10db82(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.spvasm
index 46029c4..49c6e81 100644
--- a/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/10db82.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_10db82 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,44 +86,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_10db82
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_10db82
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_10db82
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_10db82
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_10db82
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_10db82
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.glsl
index 0a0067b..863a968 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_126466() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_126466() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
index 7bde1de..5bf346f 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_126466() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
index 7bde1de..5bf346f 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_126466() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.msl
index bd82823..c4313f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_126466(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.msl
index 9d8d09e..2881e79 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_126466(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.spvasm
index 010d157..ceb5ece 100644
--- a/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/126466.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,11 +42,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_126466 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -53,22 +58,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_126466
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_126466
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_126466
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_126466
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.glsl
index 4fdac81..ffb7a27 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_127e12() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_127e12() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 uvec4 textureLoad_127e12() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
index d9deb44..caa7aa3 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_127e12() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_127e12();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
index d9deb44..caa7aa3 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_127e12() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_127e12();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.msl
index 56f1bd7..42489db 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_127e12(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.msl
index ab9e5e0..bdb5095 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_127e12(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.spvasm
index 8865555..a50c99a 100644
--- a/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/127e12.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,19 +67,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_127e12 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %32 = OpCompositeConstruct %v3int %29 %30
-         %33 = OpImageRead %v4uint %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4uint %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %30
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %28
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %29
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4uint %28 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_127e12
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_127e12
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4uint %textureLoad_127e12
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4uint %textureLoad_127e12
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %74 = OpFunctionCall %v4uint %textureLoad_127e12
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4uint %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.glsl
index 099393e..723ed92 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_1373dc() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_1373dc() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1373dc() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
index 1288b80..7550668 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_1373dc() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1373dc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
index 1288b80..7550668 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_1373dc() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1373dc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.msl
index 924fba8..bde716f 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_1373dc(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.msl
index 5d7b2d2..dce4996 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_1373dc(texture1d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.spvasm
index 9c14e2f..6da936d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1373dc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,14 +66,14 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1373dc = OpFunction %v4float None %15
          %16 = OpLabel
@@ -83,43 +85,50 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %uint %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpBitcast %uint %27
+         %31 = OpExtInst %uint %32 UMin %30 %29
+         %33 = OpImageQuerySizeLod %uint %25 %31
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %32 UMin %26 %34
+         %36 = OpImageFetch %v4float %25 %35 Lod %31
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_1373dc
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_1373dc
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_1373dc
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_1373dc
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_1373dc
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_1373dc
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.glsl
index f0a5f2d..321661c 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_13d539() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_13d539() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_13d539() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
index 9f2f395..daa26cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_13d539() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13d539();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
index 9f2f395..daa26cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_13d539() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13d539();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.msl
index 441d436..4ca696e 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_13d539(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.msl
index e876cd8..964802c 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_13d539(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.spvasm
index 4fe509a..a92e086 100644
--- a/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/13d539.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_13d539 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %24
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4int %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_13d539
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_13d539
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_13d539
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_13d539
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_13d539
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_13d539
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.glsl
index b4ad166..da6397b 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_13e90c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_13e90c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_13e90c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
index 807eb74..48528aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_13e90c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13e90c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
index 807eb74..48528aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_13e90c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_13e90c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.msl
index 29518a7..2273412 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_13e90c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.msl
index a765166..e77fe34 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_13e90c(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.spvasm
index e68e648..a374a8e 100644
--- a/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/13e90c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_13e90c = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_13e90c
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_13e90c
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_13e90c
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_13e90c
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_13e90c
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_13e90c
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.glsl
index 53b8499..54b24cf 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_143d84() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_143d84() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_143d84() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
index 0037110..7652ea1 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_143d84() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_143d84();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
index 0037110..7652ea1 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_143d84() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_143d84();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.msl
index 5424c6d..344f50f 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_143d84(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.msl
index 315186c..5ff27a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_143d84(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.spvasm
index c703191..f033ef9 100644
--- a/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/143d84.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_143d84 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,45 +91,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_143d84
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_143d84
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_143d84
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_143d84
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_143d84
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_143d84
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.glsl
index 026bba1..a046fe9 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_1471b8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_1471b8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_1471b8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
index d9f500a..19ff2cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_1471b8() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1471b8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
index d9f500a..19ff2cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_1471b8() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1471b8();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.msl
index 865118e..5d66a24 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_1471b8(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.msl
index daf7f99..476c5fb 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1471b8(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.spvasm
index 990f91c..bfb229f 100644
--- a/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1471b8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1471b8 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %24
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4int %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_1471b8
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_1471b8
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_1471b8
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_1471b8
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_1471b8
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_1471b8
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
index 9b6cb77..a1d6251 100644
--- a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_14cc4c() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
index 9b6cb77..a1d6251 100644
--- a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_14cc4c() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.msl
index e785aaa..0ee3465 100644
--- a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_14cc4c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.msl
index d83527c..9f5d1b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_14cc4c(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.spvasm
index f2eb1e1..4a22c93 100644
--- a/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/14cc4c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_14cc4c = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_14cc4c
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_14cc4c
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_14cc4c
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_14cc4c
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.glsl
index d73222f..2c9043b 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1561a7() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1561a7() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1561a7() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
index 149ce15..8bbd131 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1561a7() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1561a7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
index 149ce15..8bbd131 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1561a7() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1561a7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.msl
index 51fe2b9..351adfa 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_1561a7(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.msl
index 530b24f..70743f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1561a7(texture1d<uint, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.spvasm
index 230ea65..6289df5 100644
--- a/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1561a7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,18 +64,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1561a7 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageRead %v4uint %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4uint %24 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_1561a7
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4uint %textureLoad_1561a7
          %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_1561a7
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4uint %textureLoad_1561a7
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_1561a7
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.glsl
index c99f654..1b3b8ee 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_15e675() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_15e675() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_15e675() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
index ae35843..f3c90ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_15e675() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_15e675();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
index ae35843..f3c90ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_15e675() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_15e675();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.msl
index 18e92d1..728523e 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_15e675(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.msl
index 84e1c73..0200a98 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_15e675(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.spvasm
index 95b41c5..43ac545 100644
--- a/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/15e675.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_15e675 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %23
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4uint %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_15e675
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_15e675
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_15e675
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_15e675
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_15e675
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_15e675
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.glsl
index ce22350..6da112f 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_1619bf() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_1619bf() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
index 1d6cfa1..be22714 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_1619bf() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
index 1d6cfa1..be22714 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_1619bf() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.msl
index d234c1c..7be434a 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_1619bf(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.msl
index 9b86f79..6db6caf 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1619bf(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.spvasm
index d6e4df0..14bf7f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1619bf.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_1619bf = OpFunction %v4int None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %16
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4int %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_1619bf
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_1619bf
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_1619bf
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_1619bf
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.glsl
index c8b9dd9..c75972c 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_168dc8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_168dc8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_168dc8() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  ivec2 v_8 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
index 689972a..c3ba186 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_168dc8();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
index 689972a..c3ba186 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_168dc8();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.msl
index d62dd67..850efda 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.ir.msl
@@ -20,7 +20,11 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  int const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u))), v_2, v_3);
   return res;
 }
 
@@ -43,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.msl
index 9c71db4..5895050 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_168dc8(texture2d_array<int, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.spvasm
index 3d0a576..cce3ac0 100644
--- a/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/168dc8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,17 +69,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %55 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_168dc8 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -92,45 +94,57 @@
          %31 = OpLoad %v2uint %arg_1 None
          %32 = OpLoad %int %arg_2 None
          %33 = OpLoad %int %arg_3 None
-         %34 = OpBitcast %uint %32
-         %36 = OpCompositeConstruct %v3uint %31 %34
-         %37 = OpImageFetch %v4int %30 %36 Lod %33
-               OpStore %res %37
-         %40 = OpLoad %v4int %res None
-               OpReturnValue %40
+         %34 = OpImageQuerySizeLod %v3uint %30 %uint_0
+         %37 = OpCompositeExtract %uint %34 2
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpBitcast %uint %32
+         %40 = OpExtInst %uint %41 UMin %39 %38
+         %42 = OpImageQueryLevels %uint %30
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %33
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %30 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %24
+         %49 = OpExtInst %v2uint %41 UMin %31 %48
+         %50 = OpCompositeConstruct %v3uint %49 %40
+         %51 = OpImageFetch %v4int %30 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4int %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_168dc8
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4int %textureLoad_168dc8
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4int %textureLoad_168dc8
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %52 %51 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
          %64 = OpFunctionCall %v4int %textureLoad_168dc8
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %65 %64 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4int %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %77 = OpFunctionCall %v4int %textureLoad_168dc8
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4int %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
index f8475d3..bc9eeff 100644
--- a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_170593() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
index f8475d3..bc9eeff 100644
--- a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_170593() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.msl
index c5a0e0c..0786100 100644
--- a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_170593(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.msl
index 4cade6f..e1cbd6b 100644
--- a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_170593(texture2d<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.spvasm
index 33bcba1..04fc111 100644
--- a/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/170593.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_170593 = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %19
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_170593
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_170593
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_170593
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_170593
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
index 0736613..dfaffb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_17095b() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
index 0736613..dfaffb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_17095b() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.msl
index 7ec83be..2327e6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_17095b(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.msl
index 63c9667..2b06b06 100644
--- a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_17095b(texture1d<uint, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.spvasm
index 28810a1..a380a01 100644
--- a/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/17095b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,7 +41,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_17095b = OpFunction %v4uint None %10
@@ -49,22 +51,25 @@
                OpStore %arg_1 %uint_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %uint %arg_1 None
-         %17 = OpImageRead %v4uint %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %18 = OpISub %uint %17 %uint_1
+         %19 = OpExtInst %uint %20 UMin %16 %18
+         %21 = OpImageRead %v4uint %15 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_17095b
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4uint %textureLoad_17095b
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_17095b
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_17095b
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.glsl
index 5e3725b..ca62fc4 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_18ac11() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_18ac11() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_18ac11() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
index 0a90c4b..47e3280 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_18ac11() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_18ac11();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
index 0a90c4b..47e3280 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_18ac11() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_18ac11();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.msl
index 26429cb..f2b0bb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_18ac11(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.msl
index a22189d..999bfd3 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_18ac11(texture1d<int, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.spvasm
index 0a7973f..8720d5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/18ac11.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_18ac11 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageRead %v4int %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageRead %v4int %24 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_18ac11
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_18ac11
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_18ac11
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_18ac11
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_18ac11
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_18ac11
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.glsl
index 2b3b000..3e0fbc0 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_19cf87() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_19cf87() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  float res = texelFetch(arg_0, v_6, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_19cf87() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
index cc7b950..e66fbaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float textureLoad_19cf87() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float res = arg_0.Load(int3(v_5, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19cf87();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
index cc7b950..e66fbaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float textureLoad_19cf87() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float res = arg_0.Load(int3(v_5, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19cf87();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.msl
index 0296779..f453d61 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float textureLoad_19cf87(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.msl
index 9839df8..73fb428 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_19cf87(depth2d<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.spvasm
index 1c16842..adee70b 100644
--- a/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/19cf87.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %48 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_19cf87 = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +89,52 @@
          %25 = OpLoad %7 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-         %29 = OpCompositeExtract %float %28 0
-               OpStore %res %29
-         %32 = OpLoad %float %res None
-               OpReturnValue %32
+         %28 = OpImageQueryLevels %uint %25
+         %30 = OpISub %uint %28 %uint_1
+         %32 = OpBitcast %uint %27
+         %33 = OpExtInst %uint %34 UMin %32 %30
+         %35 = OpImageQuerySizeLod %v2uint %25 %33
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpBitcast %v2uint %26
+         %40 = OpExtInst %v2uint %34 UMin %39 %37
+         %41 = OpImageFetch %v4float %25 %40 Lod %33
+         %42 = OpCompositeExtract %float %41 0
+               OpStore %res %42
+         %45 = OpLoad %float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_19cf87
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_19cf87
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
+%fragment_main = OpFunction %void None %48
          %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_19cf87
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+         %50 = OpFunctionCall %float %textureLoad_19cf87
+         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %51 %50 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %float %textureLoad_19cf87
+         %57 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %57 %56 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %60
          %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %69 = OpFunctionCall %float %textureLoad_19cf87
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %float %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.glsl
index 8cb44b4..72b3a72 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_19d6be() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_19d6be() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
index 7c735b1..6f916ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_19d6be() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
index 7c735b1..6f916ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_19d6be() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.msl
index 6d80001..dd01c4a 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_19d6be(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.msl
index b304e70..2e5e8e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_19d6be(texture3d<uint, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.spvasm
index 2f176a5..e207c22 100644
--- a/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/19d6be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_19d6be = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %20 = OpISub %v3uint %19 %15
+         %21 = OpExtInst %v3uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_19d6be
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_19d6be
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_19d6be
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_19d6be
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.glsl
index 6c44cfe..05bb03c 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_19e5ca() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_19e5ca() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_19e5ca() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
index d5c83fc..dd7fcff 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_19e5ca() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19e5ca();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
index d5c83fc..dd7fcff 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_19e5ca() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_19e5ca();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.msl
index cc035f4..0f1438e 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_19e5ca(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.msl
index 06e9873..0dcd750 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_19e5ca(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.spvasm
index c9721b1..b94c747 100644
--- a/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/19e5ca.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_19e5ca = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,45 +91,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_19e5ca
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_19e5ca
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_19e5ca
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_19e5ca
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_19e5ca
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_19e5ca
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.glsl
index 133fd76a7..7a3f8e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_1a062f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_1a062f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_1a062f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
index 22481a6..f43e3ee 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_1a062f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a062f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
index 22481a6..f43e3ee 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_1a062f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a062f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.msl
index ac37333..7265463 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_1a062f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.msl
index c9b6425..c0239c2 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_1a062f(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.spvasm
index 43d5b35..cd668dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1a062f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1a062f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,44 +90,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_1a062f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_1a062f
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_1a062f
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_1a062f
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_1a062f
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_1a062f
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.glsl
index 4365220..58eb1d1 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1a8452() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_1a8452() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1a8452() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
index 45990d5..0fc8859 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1a8452() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a8452();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
index 45990d5..0fc8859 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_1a8452() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1a8452();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.msl
index f82e18c..48e3701 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_1a8452(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.msl
index 09944fe..5291276 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1a8452(texture1d<uint, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.spvasm
index 2a811aa..ae2f67e 100644
--- a/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1a8452.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,18 +64,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1a8452 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageRead %v4uint %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4uint %24 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_1a8452
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4uint %textureLoad_1a8452
          %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_1a8452
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4uint %textureLoad_1a8452
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_1a8452
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.glsl
index d8f5363..c3e319b 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_1aa950() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_1aa950() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_1aa950() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
index 449c15d..b315080 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_1aa950() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1aa950();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
index 449c15d..b315080 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_1aa950() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1aa950();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.msl
index 350ce78..e8e594d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_1aa950(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.msl
index d4a48e3..ceeee81 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1aa950(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.spvasm
index 4a95fbc..54a88be 100644
--- a/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1aa950.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1aa950 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4int %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_1aa950
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_1aa950
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_1aa950
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_1aa950
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_1aa950
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %73 = OpFunctionCall %v4int %textureLoad_1aa950
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4int %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.glsl
index e773142..d506529 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_1b051f() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_1b051f() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1b051f() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_1), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
index 85c9d70..13ca8e6 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b051f();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
index 85c9d70..13ca8e6 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b051f();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.msl
index a671e28..ea2d5e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint const v = arg_2;
-  uint const v_1 = arg_3;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.msl
index de2ba31..1d63040 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b051f(texture2d_array<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.spvasm
index 3fe92e7..042f360 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1b051f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 86
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %55 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %73 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %76 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1b051f = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -92,45 +96,56 @@
          %31 = OpLoad %v2int %arg_1 None
          %32 = OpLoad %uint %arg_2 None
          %33 = OpLoad %uint %arg_3 None
-         %34 = OpBitcast %int %32
-         %36 = OpCompositeConstruct %v3int %31 %34
-         %37 = OpImageFetch %v4uint %30 %36 Lod %33
-               OpStore %res %37
-         %40 = OpLoad %v4uint %res None
-               OpReturnValue %40
+         %34 = OpImageQuerySizeLod %v3uint %30 %uint_0
+         %37 = OpCompositeExtract %uint %34 2
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpExtInst %uint %40 UMin %32 %38
+         %41 = OpImageQueryLevels %uint %30
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %33 %42
+         %44 = OpImageQuerySizeLod %v3uint %30 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %31
+         %50 = OpExtInst %v2uint %40 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %39
+         %52 = OpImageFetch %v4uint %30 %51 Lod %43
+               OpStore %res %52
+         %55 = OpLoad %v4uint %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_1b051f
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_1b051f
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4uint %textureLoad_1b051f
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %58
+         %64 = OpLabel
+         %65 = OpFunctionCall %v4uint %textureLoad_1b051f
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %66 %65 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %64 = OpFunctionCall %v4uint %textureLoad_1b051f
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %76 None
+         %77 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %78 = OpFunctionCall %v4uint %textureLoad_1b051f
+               OpStore %77 %78 None
+         %79 = OpLoad %VertexOutput %out None
+               OpReturnValue %79
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4uint %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %58
+         %81 = OpLabel
+         %82 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %83 = OpCompositeExtract %v4float %82 0
+               OpStore %vertex_main_position_Output %83 None
+         %84 = OpCompositeExtract %v4uint %82 1
+               OpStore %vertex_main_loc0_Output %84 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.glsl
index 3b0b86b..c240a22 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_1b4332() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_1b4332() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
index a820b63..a279417 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_1b4332() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
index a820b63..a279417 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_1b4332() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.msl
index 8bc9298..ae4d214 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_1b4332(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.msl
index 74773a1..4a73bbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b4332(texture3d<uint, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.spvasm
index 65d1830..ee57b86 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1b4332.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_1b4332 = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %22 = OpISub %v3uint %20 %23
+         %25 = OpBitcast %v3uint %19
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_1b4332
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_1b4332
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_1b4332
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_1b4332
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.glsl
index 351bccd..a1a9a9b 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_1b8588() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_1b8588() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1b8588() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_1), v_4), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
index 7a3c959..d3cf79c 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_1b8588() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  uint4 res = uint4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b8588();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
index 7a3c959..d3cf79c 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_1b8588() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  uint4 res = uint4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1b8588();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.msl
index c4d9a3c..c6c1733 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 uint4 textureLoad_1b8588(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.msl
index 7e98e8a..708c594 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_1b8588(texture1d<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.spvasm
index b5ac4fa..b12ffd5 100644
--- a/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1b8588.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,18 +64,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1b8588 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -85,43 +87,51 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4uint %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %31 = OpBitcast %uint %27
+         %32 = OpExtInst %uint %33 UMin %31 %29
+         %34 = OpImageQuerySizeLod %uint %25 %32
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %26
+         %37 = OpExtInst %uint %33 UMin %36 %35
+         %38 = OpImageFetch %v4uint %25 %37 Lod %32
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_1b8588
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_1b8588
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_1b8588
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_1b8588
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_1b8588
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_1b8588
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
index 54b40c9..fb9f8cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1bc5ab() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
index 54b40c9..fb9f8cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1bc5ab() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.msl
index 2e9505b..ca51e17 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_1bc5ab(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.msl
index f9c8bdc..db5a569 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_1bc5ab(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.spvasm
index 6fd60ee..752cf1d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1bc5ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1bc5ab = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_1bc5ab
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_1bc5ab
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_1bc5ab
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_1bc5ab
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.glsl
index cb457f7..a526308 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.glsl
@@ -107,7 +107,7 @@
 vec4 textureLoad_1bfdfb() {
   uvec2 arg_1 = uvec2(1u);
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, arg_1);
+  vec4 res = tint_TextureLoadExternal(v_17, min(arg_1, ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 void main() {
@@ -220,7 +220,7 @@
 vec4 textureLoad_1bfdfb() {
   uvec2 arg_1 = uvec2(1u);
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, arg_1);
+  vec4 res = tint_TextureLoadExternal(v_17, min(arg_1, ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -336,7 +336,7 @@
 vec4 textureLoad_1bfdfb() {
   uvec2 arg_1 = uvec2(1u);
   tint_ExternalTextureParams v_16 = tint_convert_tint_ExternalTextureParams(v_1.inner);
-  vec4 res = tint_TextureLoadExternal(v_16, arg_1);
+  vec4 res = tint_TextureLoadExternal(v_16, min(arg_1, ((v_16.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
index bf24ea3..d16946d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.dxc.hlsl
@@ -60,79 +60,92 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_1bfdfb() {
   uint2 arg_1 = (1u).xx;
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, arg_1);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, arg_1);
   return res;
 }
 
@@ -149,13 +162,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1bfdfb();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
index bf24ea3..d16946d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.fxc.hlsl
@@ -60,79 +60,92 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_1bfdfb() {
   uint2 arg_1 = (1u).xx;
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, arg_1);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, arg_1);
   return res;
 }
 
@@ -149,13 +162,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1bfdfb();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.msl
index 150a4eb..b71c2b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.ir.msl
@@ -126,7 +126,7 @@
 float4 textureLoad_1bfdfb(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   tint_ExternalTextureParams const v_19 = tint_load_struct_packed_vec3(tint_module_vars.arg_0_params);
-  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, arg_1);
+  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, min(arg_1, ((v_19.apparentSize + uint2(1u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.msl
index 69f578e..60cf65b 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.msl
@@ -120,7 +120,7 @@
 
 float4 textureLoad_1bfdfb(texture2d<float, access::sample> tint_symbol_1, texture2d<float, access::sample> tint_symbol_2, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_3) {
   uint2 arg_1 = uint2(1u);
-  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, arg_1, tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
+  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, min(arg_1, (((*(tint_symbol_3)).apparentSize + uint2(1u)) - uint2(1u))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.spvasm
index 864ec93..3fb6d6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1bfdfb.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 184
+; Bound: 188
 ; Schema: 0
                OpCapability Shader
-         %84 = OpExtInstImport "GLSL.std.450"
+         %48 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -193,19 +193,19 @@
 %tint_ExternalTextureParams = OpTypeStruct %uint %uint %mat3v4float %tint_GammaTransferParams %tint_GammaTransferParams %mat3v3float %mat3v2float %mat3v2float %v2float %v2float %v2float %v2float %v2uint %v2float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %51 = OpTypeFunction %void
+         %56 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %62 = OpTypeFunction %VertexOutput
+         %67 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %66 = OpConstantNull %VertexOutput
-         %68 = OpConstantNull %v4float
-         %76 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
+         %71 = OpConstantNull %VertexOutput
+         %73 = OpConstantNull %v4float
+         %81 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
        %bool = OpTypeBool
-        %125 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+        %129 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %158 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %162 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
 %textureLoad_1bfdfb = OpFunction %v4float None %26
          %27 = OpLabel
       %arg_1 = OpVariable %_ptr_Function_v2uint Function
@@ -217,159 +217,163 @@
          %37 = OpLoad %tint_ExternalTextureParams_std140 %34 None
          %38 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %37
          %43 = OpLoad %v2uint %arg_1 None
-         %44 = OpFunctionCall %v4float %tint_TextureLoadExternal %32 %33 %38 %43
-               OpStore %res %44
-         %48 = OpLoad %v4float %res None
-               OpReturnValue %48
+         %44 = OpCompositeExtract %v2uint %38 12
+         %45 = OpIAdd %v2uint %44 %30
+         %46 = OpISub %v2uint %45 %30
+         %47 = OpExtInst %v2uint %48 UMin %43 %46
+         %49 = OpFunctionCall %v4float %tint_TextureLoadExternal %32 %33 %38 %47
+               OpStore %res %49
+         %53 = OpLoad %v4float %res None
+               OpReturnValue %53
                OpFunctionEnd
-%fragment_main = OpFunction %void None %51
-         %52 = OpLabel
-         %53 = OpFunctionCall %v4float %textureLoad_1bfdfb
-         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %54 %53 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %51
+%fragment_main = OpFunction %void None %56
          %57 = OpLabel
          %58 = OpFunctionCall %v4float %textureLoad_1bfdfb
          %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %62
-         %63 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %66
-         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %67 %68 None
-         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %70 = OpFunctionCall %v4float %textureLoad_1bfdfb
-               OpStore %69 %70 None
-         %71 = OpLoad %VertexOutput %out None
-               OpReturnValue %71
+%compute_main = OpFunction %void None %56
+         %62 = OpLabel
+         %63 = OpFunctionCall %v4float %textureLoad_1bfdfb
+         %64 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %64 %63 None
+               OpReturn
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %76
+%vertex_main_inner = OpFunction %VertexOutput None %67
+         %68 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %71
+         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %72 %73 None
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %75 = OpFunctionCall %v4float %textureLoad_1bfdfb
+               OpStore %74 %75 None
+         %76 = OpLoad %VertexOutput %out None
+               OpReturnValue %76
+               OpFunctionEnd
+%tint_TextureLoadExternal = OpFunction %v4float None %81
     %plane_0 = OpFunctionParameter %8
     %plane_1 = OpFunctionParameter %8
      %params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2uint
-         %77 = OpLabel
-         %78 = OpCompositeExtract %uint %params 1
-         %79 = OpCompositeExtract %mat3v4float %params 2
-         %80 = OpCompositeExtract %mat3v2float %params 7
-         %81 = OpCompositeExtract %v2uint %params 12
-         %82 = OpCompositeExtract %v2float %params 13
-         %83 = OpExtInst %v2uint %84 UMin %coords %81
-         %85 = OpConvertUToF %v2float %83
-         %86 = OpCompositeConstruct %v3float %85 %float_1
-         %88 = OpMatrixTimesVector %v2float %80 %86
-         %89 = OpExtInst %v2float %84 RoundEven %88
-         %90 = OpConvertFToU %v2uint %89
-         %91 = OpCompositeExtract %uint %params 0
-         %92 = OpIEqual %bool %91 %uint_1
-               OpSelectionMerge %94 None
-               OpBranchConditional %92 %95 %96
-         %95 = OpLabel
-         %97 = OpImageFetch %v4float %plane_0 %90 Lod %uint_0
-         %98 = OpVectorShuffle %v3float %97 %97 0 1 2
-         %99 = OpCompositeExtract %float %97 3
-               OpBranch %94
-         %96 = OpLabel
-        %100 = OpImageFetch %v4float %plane_0 %90 Lod %uint_0
-        %101 = OpCompositeExtract %float %100 0
-        %102 = OpFMul %v2float %89 %82
-        %103 = OpConvertFToU %v2uint %102
-        %104 = OpImageFetch %v4float %plane_1 %103 Lod %uint_0
-        %105 = OpVectorShuffle %v2float %104 %104 0 1
-        %106 = OpCompositeConstruct %v4float %101 %105 %float_1
-        %107 = OpVectorTimesMatrix %v3float %106 %79
-               OpBranch %94
-         %94 = OpLabel
-        %108 = OpPhi %v3float %98 %95 %107 %96
-        %109 = OpPhi %float %99 %95 %float_1 %96
-        %110 = OpIEqual %bool %78 %uint_0
-               OpSelectionMerge %111 None
-               OpBranchConditional %110 %112 %113
-        %112 = OpLabel
-        %114 = OpCompositeExtract %tint_GammaTransferParams %params 3
-        %115 = OpCompositeExtract %tint_GammaTransferParams %params 4
-        %116 = OpCompositeExtract %mat3v3float %params 5
-        %117 = OpFunctionCall %v3float %tint_GammaCorrection %108 %114
-        %119 = OpMatrixTimesVector %v3float %116 %117
-        %120 = OpFunctionCall %v3float %tint_GammaCorrection %119 %115
-               OpBranch %111
-        %113 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %121 = OpPhi %v3float %120 %112 %108 %113
-        %122 = OpCompositeConstruct %v4float %121 %109
-               OpReturnValue %122
+         %82 = OpLabel
+         %83 = OpCompositeExtract %uint %params 1
+         %84 = OpCompositeExtract %mat3v4float %params 2
+         %85 = OpCompositeExtract %mat3v2float %params 7
+         %86 = OpCompositeExtract %v2uint %params 12
+         %87 = OpCompositeExtract %v2float %params 13
+         %88 = OpExtInst %v2uint %48 UMin %coords %86
+         %89 = OpConvertUToF %v2float %88
+         %90 = OpCompositeConstruct %v3float %89 %float_1
+         %92 = OpMatrixTimesVector %v2float %85 %90
+         %93 = OpExtInst %v2float %48 RoundEven %92
+         %94 = OpConvertFToU %v2uint %93
+         %95 = OpCompositeExtract %uint %params 0
+         %96 = OpIEqual %bool %95 %uint_1
+               OpSelectionMerge %98 None
+               OpBranchConditional %96 %99 %100
+         %99 = OpLabel
+        %101 = OpImageFetch %v4float %plane_0 %94 Lod %uint_0
+        %102 = OpVectorShuffle %v3float %101 %101 0 1 2
+        %103 = OpCompositeExtract %float %101 3
+               OpBranch %98
+        %100 = OpLabel
+        %104 = OpImageFetch %v4float %plane_0 %94 Lod %uint_0
+        %105 = OpCompositeExtract %float %104 0
+        %106 = OpFMul %v2float %93 %87
+        %107 = OpConvertFToU %v2uint %106
+        %108 = OpImageFetch %v4float %plane_1 %107 Lod %uint_0
+        %109 = OpVectorShuffle %v2float %108 %108 0 1
+        %110 = OpCompositeConstruct %v4float %105 %109 %float_1
+        %111 = OpVectorTimesMatrix %v3float %110 %84
+               OpBranch %98
+         %98 = OpLabel
+        %112 = OpPhi %v3float %102 %99 %111 %100
+        %113 = OpPhi %float %103 %99 %float_1 %100
+        %114 = OpIEqual %bool %83 %uint_0
+               OpSelectionMerge %115 None
+               OpBranchConditional %114 %116 %117
+        %116 = OpLabel
+        %118 = OpCompositeExtract %tint_GammaTransferParams %params 3
+        %119 = OpCompositeExtract %tint_GammaTransferParams %params 4
+        %120 = OpCompositeExtract %mat3v3float %params 5
+        %121 = OpFunctionCall %v3float %tint_GammaCorrection %112 %118
+        %123 = OpMatrixTimesVector %v3float %120 %121
+        %124 = OpFunctionCall %v3float %tint_GammaCorrection %123 %119
+               OpBranch %115
+        %117 = OpLabel
+               OpBranch %115
+        %115 = OpLabel
+        %125 = OpPhi %v3float %124 %116 %112 %117
+        %126 = OpCompositeConstruct %v4float %125 %113
+               OpReturnValue %126
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %125
+%tint_GammaCorrection = OpFunction %v3float None %129
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-        %126 = OpLabel
-        %127 = OpCompositeExtract %float %params_0 0
-        %128 = OpCompositeExtract %float %params_0 1
-        %129 = OpCompositeExtract %float %params_0 2
-        %130 = OpCompositeExtract %float %params_0 3
-        %131 = OpCompositeExtract %float %params_0 4
-        %132 = OpCompositeExtract %float %params_0 5
-        %133 = OpCompositeExtract %float %params_0 6
-        %134 = OpCompositeConstruct %v3float %127 %127 %127
-        %135 = OpCompositeConstruct %v3float %131 %131 %131
-        %136 = OpExtInst %v3float %84 FAbs %v
-        %137 = OpExtInst %v3float %84 FSign %v
-        %138 = OpFOrdLessThan %v3bool %136 %135
-        %140 = OpVectorTimesScalar %v3float %136 %130
-        %141 = OpCompositeConstruct %v3float %133 %133 %133
-        %142 = OpFAdd %v3float %140 %141
-        %143 = OpFMul %v3float %137 %142
-        %144 = OpVectorTimesScalar %v3float %136 %128
-        %145 = OpCompositeConstruct %v3float %129 %129 %129
+        %130 = OpLabel
+        %131 = OpCompositeExtract %float %params_0 0
+        %132 = OpCompositeExtract %float %params_0 1
+        %133 = OpCompositeExtract %float %params_0 2
+        %134 = OpCompositeExtract %float %params_0 3
+        %135 = OpCompositeExtract %float %params_0 4
+        %136 = OpCompositeExtract %float %params_0 5
+        %137 = OpCompositeExtract %float %params_0 6
+        %138 = OpCompositeConstruct %v3float %131 %131 %131
+        %139 = OpCompositeConstruct %v3float %135 %135 %135
+        %140 = OpExtInst %v3float %48 FAbs %v
+        %141 = OpExtInst %v3float %48 FSign %v
+        %142 = OpFOrdLessThan %v3bool %140 %139
+        %144 = OpVectorTimesScalar %v3float %140 %134
+        %145 = OpCompositeConstruct %v3float %137 %137 %137
         %146 = OpFAdd %v3float %144 %145
-        %147 = OpExtInst %v3float %84 Pow %146 %134
-        %148 = OpCompositeConstruct %v3float %132 %132 %132
-        %149 = OpFAdd %v3float %147 %148
-        %150 = OpFMul %v3float %137 %149
-        %151 = OpSelect %v3float %138 %143 %150
-               OpReturnValue %151
+        %147 = OpFMul %v3float %141 %146
+        %148 = OpVectorTimesScalar %v3float %140 %132
+        %149 = OpCompositeConstruct %v3float %133 %133 %133
+        %150 = OpFAdd %v3float %148 %149
+        %151 = OpExtInst %v3float %48 Pow %150 %138
+        %152 = OpCompositeConstruct %v3float %136 %136 %136
+        %153 = OpFAdd %v3float %151 %152
+        %154 = OpFMul %v3float %141 %153
+        %155 = OpSelect %v3float %142 %147 %154
+               OpReturnValue %155
                OpFunctionEnd
-%vertex_main = OpFunction %void None %51
-        %153 = OpLabel
-        %154 = OpFunctionCall %VertexOutput %vertex_main_inner
-        %155 = OpCompositeExtract %v4float %154 0
-               OpStore %vertex_main_position_Output %155 None
-        %156 = OpCompositeExtract %v4float %154 1
-               OpStore %vertex_main_loc0_Output %156 None
+%vertex_main = OpFunction %void None %56
+        %157 = OpLabel
+        %158 = OpFunctionCall %VertexOutput %vertex_main_inner
+        %159 = OpCompositeExtract %v4float %158 0
+               OpStore %vertex_main_position_Output %159 None
+        %160 = OpCompositeExtract %v4float %158 1
+               OpStore %vertex_main_loc0_Output %160 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %158
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %162
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %159 = OpLabel
-        %160 = OpCompositeExtract %uint %tint_input 0
-        %161 = OpCompositeExtract %uint %tint_input 1
-        %162 = OpCompositeExtract %mat3v4float %tint_input 2
-        %163 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %164 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %165 = OpCompositeExtract %v3float %tint_input 5
-        %166 = OpCompositeExtract %v3float %tint_input 6
-        %167 = OpCompositeExtract %v3float %tint_input 7
-        %168 = OpCompositeConstruct %mat3v3float %165 %166 %167
-        %169 = OpCompositeExtract %v2float %tint_input 8
-        %170 = OpCompositeExtract %v2float %tint_input 9
-        %171 = OpCompositeExtract %v2float %tint_input 10
-        %172 = OpCompositeConstruct %mat3v2float %169 %170 %171
-        %173 = OpCompositeExtract %v2float %tint_input 11
-        %174 = OpCompositeExtract %v2float %tint_input 12
-        %175 = OpCompositeExtract %v2float %tint_input 13
+        %163 = OpLabel
+        %164 = OpCompositeExtract %uint %tint_input 0
+        %165 = OpCompositeExtract %uint %tint_input 1
+        %166 = OpCompositeExtract %mat3v4float %tint_input 2
+        %167 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %168 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %169 = OpCompositeExtract %v3float %tint_input 5
+        %170 = OpCompositeExtract %v3float %tint_input 6
+        %171 = OpCompositeExtract %v3float %tint_input 7
+        %172 = OpCompositeConstruct %mat3v3float %169 %170 %171
+        %173 = OpCompositeExtract %v2float %tint_input 8
+        %174 = OpCompositeExtract %v2float %tint_input 9
+        %175 = OpCompositeExtract %v2float %tint_input 10
         %176 = OpCompositeConstruct %mat3v2float %173 %174 %175
-        %177 = OpCompositeExtract %v2float %tint_input 14
-        %178 = OpCompositeExtract %v2float %tint_input 15
-        %179 = OpCompositeExtract %v2float %tint_input 16
-        %180 = OpCompositeExtract %v2float %tint_input 17
-        %181 = OpCompositeExtract %v2uint %tint_input 18
-        %182 = OpCompositeExtract %v2float %tint_input 19
-        %183 = OpCompositeConstruct %tint_ExternalTextureParams %160 %161 %162 %163 %164 %168 %172 %176 %177 %178 %179 %180 %181 %182
-               OpReturnValue %183
+        %177 = OpCompositeExtract %v2float %tint_input 11
+        %178 = OpCompositeExtract %v2float %tint_input 12
+        %179 = OpCompositeExtract %v2float %tint_input 13
+        %180 = OpCompositeConstruct %mat3v2float %177 %178 %179
+        %181 = OpCompositeExtract %v2float %tint_input 14
+        %182 = OpCompositeExtract %v2float %tint_input 15
+        %183 = OpCompositeExtract %v2float %tint_input 16
+        %184 = OpCompositeExtract %v2float %tint_input 17
+        %185 = OpCompositeExtract %v2uint %tint_input 18
+        %186 = OpCompositeExtract %v2float %tint_input 19
+        %187 = OpCompositeConstruct %tint_ExternalTextureParams %164 %165 %166 %167 %168 %172 %176 %180 %181 %182 %183 %184 %185 %186
+               OpReturnValue %187
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.glsl
index 8b9bdd7..7e50dee 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_1c562a() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_1c562a() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_1c562a() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
index e88f9a8..2a95465 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_1c562a() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1c562a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
index e88f9a8..2a95465 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_1c562a() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1c562a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.msl
index 8febded..02e9f83 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_1c562a(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.msl
index 4658aca..49aa2dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_1c562a(texture3d<uint, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.spvasm
index 5c47b11..1fdf0b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1c562a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %48 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1c562a = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -85,43 +87,49 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v3uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4uint %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4uint %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %v3uint %27 %32
+         %35 = OpISub %v3uint %34 %23
+         %36 = OpExtInst %v3uint %33 UMin %28 %35
+         %37 = OpImageFetch %v4uint %27 %36 Lod %32
+               OpStore %res %37
+         %40 = OpLoad %v4uint %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_1c562a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_1c562a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4uint %textureLoad_1c562a
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4uint %textureLoad_1c562a
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %57 = OpFunctionCall %v4uint %textureLoad_1c562a
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %64 = OpFunctionCall %v4uint %textureLoad_1c562a
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4uint %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4uint %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
index d6fd4e7..f025ef4 100644
--- a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1d43ae() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
index d6fd4e7..f025ef4 100644
--- a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_1d43ae() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.msl
index 9203002..919655f 100644
--- a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_1d43ae(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.msl
index e278688..ea552f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_1d43ae(texture1d<int, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.spvasm
index 232d602..b397393 100644
--- a/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1d43ae.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,11 +39,12 @@
          %10 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_1d43ae = OpFunction %v4int None %10
          %11 = OpLabel
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %int %arg_1 None
-         %17 = OpImageRead %v4int %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %19 = OpISub %uint %17 %uint_1
+         %21 = OpBitcast %uint %16
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4int %15 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_1d43ae
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %23
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4int %textureLoad_1d43ae
          %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_1d43ae
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.glsl
index e7843ff..d57ba08 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_1e6baa() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_1e6baa() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
index 04888de..99222d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1e6baa() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
index 04888de..99222d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1e6baa() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.msl
index 5cc83c7..cc7f9c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_1e6baa(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.msl
index a0ce59e..b8cd017 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_1e6baa(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.spvasm
index 0b0b07a..6792844 100644
--- a/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1e6baa.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1e6baa = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_1e6baa
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_1e6baa
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_1e6baa
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_1e6baa
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.glsl
index 01cbdfc..d57ec00 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_1eb93f() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_1eb93f() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1eb93f() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
index 34e0c95..cb61486 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1eb93f() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1eb93f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
index 34e0c95..cb61486 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_1eb93f() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1eb93f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.msl
index 95bd2ef..bb2d53a 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_1eb93f(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.msl
index ccf757a..3e1534e 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_1eb93f(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.spvasm
index 0918439..f0c8804 100644
--- a/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1eb93f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1eb93f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_1eb93f
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_1eb93f
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_1eb93f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_1eb93f
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_1eb93f
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_1eb93f
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.glsl
index e30a3eb..6885766 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_1f2016() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_1f2016() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_1f2016() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_1), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
index a5e3654..c480e59 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_1f2016() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1f2016();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
index a5e3654..c480e59 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_1f2016() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_1f2016();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.msl
index 54ac382..9e9ea27 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_1f2016(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.msl
index 7bd25e7..c23da0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_1f2016(texture3d<float, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.spvasm
index 38c5040..ce7815e 100644
--- a/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1f2016.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %38 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %47 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %63 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_1f2016 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,51 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %30 = OpISub %uint %28 %uint_1
+         %32 = OpBitcast %uint %27
+         %33 = OpExtInst %uint %34 UMin %32 %30
+         %35 = OpImageQuerySizeLod %v3uint %25 %33
+         %37 = OpISub %v3uint %35 %38
+         %39 = OpBitcast %v3uint %26
+         %40 = OpExtInst %v3uint %34 UMin %39 %37
+         %41 = OpImageFetch %v4float %25 %40 Lod %33
+               OpStore %res %41
+         %44 = OpLoad %v4float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_1f2016
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_1f2016
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
+%fragment_main = OpFunction %void None %47
          %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_1f2016
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %49 = OpFunctionCall %v4float %textureLoad_1f2016
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4float %textureLoad_1f2016
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %67 = OpFunctionCall %v4float %textureLoad_1f2016
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4float %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.glsl
index 04a6f4b..8d11d75 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_1fde63() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_1fde63() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
index 4e4767e..2ab776d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1fde63() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
index 4e4767e..2ab776d 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_1fde63() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.msl
index 416942b..20a281a 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_1fde63(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.msl
index dcfddd9..c978da3 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_1fde63(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.spvasm
index 0fd978f..8eec9b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/1fde63.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_1fde63 = OpFunction %v4float None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_1fde63
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_1fde63
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_1fde63
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_1fde63
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.glsl
index 37ef612..7191141 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_206a08() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_206a08() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_206a08() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
index c1cafca..2055796 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_206a08() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_206a08();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
index c1cafca..2055796 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_206a08() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_206a08();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.msl
index 183fc5f..9563c71 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_206a08(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.msl
index 785681e..ab4363c 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_206a08(texture1d<uint, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.spvasm
index 113b456..c8f58cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/206a08.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_206a08 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -80,43 +82,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageRead %v4uint %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageRead %v4uint %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_206a08
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_206a08
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_206a08
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_206a08
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %52 = OpFunctionCall %v4uint %textureLoad_206a08
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_206a08
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.glsl
index 0d424c7..a0f0170 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_20fa2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_20fa2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_20fa2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
index 0218e18..b56e5fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_20fa2f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_20fa2f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
index 0218e18..b56e5fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_20fa2f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_20fa2f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.msl
index 98f1cd8..10b97c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_20fa2f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.msl
index 57fc89a..303c706 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_20fa2f(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.spvasm
index 00fba56..05a81a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/20fa2f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_20fa2f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,44 +91,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_20fa2f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_20fa2f
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_20fa2f
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_20fa2f
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_20fa2f
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_20fa2f
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.glsl
index 517116b..9953e8e 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_216c37() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_216c37() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_216c37() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
index b562123..c2ff386 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_216c37() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_216c37();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
index b562123..c2ff386 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_216c37() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_216c37();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.msl
index d4a26b5..49d7026 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_216c37(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.msl
index b5179f1..c024cb5 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_216c37(texture1d<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.spvasm
index 66376f5..582e0a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/216c37.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_216c37 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -86,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4uint %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4uint %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %29
+         %33 = OpExtInst %uint %34 UMin %32 %31
+         %35 = OpImageQuerySizeLod %uint %27 %33
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %34 UMin %28 %36
+         %38 = OpImageFetch %v4uint %27 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_216c37
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_216c37
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4uint %textureLoad_216c37
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_216c37
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %57 = OpFunctionCall %v4uint %textureLoad_216c37
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_216c37
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4uint %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.glsl
index 6323076..5d44b38 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_21d1c4() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_21d1c4() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_21d1c4() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
index b33cf56..c4da3bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_21d1c4() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_21d1c4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
index b33cf56..c4da3bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_21d1c4() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_21d1c4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.msl
index 5f4c9fc..7ebf6aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_21d1c4(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.msl
index 5607ebc..1d9bf89 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_21d1c4(texture3d<float, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.spvasm
index 61381e3..80157de 100644
--- a/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/21d1c4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_21d1c4 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -82,43 +84,49 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpExtInst %uint %31 UMin %27 %29
+         %32 = OpImageQuerySizeLod %v3uint %25 %30
+         %33 = OpISub %v3uint %32 %21
+         %34 = OpExtInst %v3uint %31 UMin %26 %33
+         %35 = OpImageFetch %v4float %25 %34 Lod %30
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_21d1c4
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_21d1c4
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_21d1c4
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_21d1c4
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_21d1c4
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_21d1c4
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.glsl
index 5dca0e2..648628e 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_223246() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_223246() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_223246() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec3 v_4 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
index a28045b..067476e 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_223246() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_223246();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
index a28045b..067476e 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_223246() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_223246();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.msl
index c21139a..0150ee2 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_223246(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.msl
index fa2b08a..ebba173 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_223246(texture3d<int, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.spvasm
index d653b5f..f727289 100644
--- a/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/223246.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_223246 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +89,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v3uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %31
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySizeLod %v3uint %29 %35
+         %38 = OpISub %v3uint %37 %24
+         %39 = OpExtInst %v3uint %36 UMin %30 %38
+         %40 = OpImageFetch %v4int %29 %39 Lod %35
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_223246
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_223246
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_223246
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_223246
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_223246
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_223246
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.glsl
index 532146b..c7f18fc0 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_22e963() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_22e963() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_22e963() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
index 3523505..b28ce15 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_22e963() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_22e963();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
index 3523505..b28ce15 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_22e963() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_22e963();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.msl
index e1adbc6..211a5c1 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_22e963(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.msl
index 5035f21..d325105 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_22e963(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.spvasm
index df637ca..bdd0d53 100644
--- a/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/22e963.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_22e963 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,44 +89,52 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %31 = OpCompositeConstruct %v3uint %28 %29
-         %32 = OpImageRead %v4uint %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %35 UMin %28 %38
+         %40 = OpCompositeConstruct %v3uint %39 %34
+         %41 = OpImageRead %v4uint %27 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_22e963
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_22e963
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_22e963
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_22e963
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_22e963
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_22e963
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.glsl
index 52b8454..fb32409 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_23007a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_23007a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_23007a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
index fc7dcf4..a0bb488 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_23007a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23007a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
index fc7dcf4..a0bb488 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_23007a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23007a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.msl
index 885219a..fee6f7d 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_23007a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.msl
index 5f7b69b..d7b45ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_23007a(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.spvasm
index 2816ae1..9775f87 100644
--- a/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/23007a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,14 +70,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_23007a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,45 +89,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_23007a
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_23007a
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_23007a
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_23007a
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_23007a
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_23007a
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.glsl
index 2adcaec..32a602a 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_2363be() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_2363be() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2363be() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
index e8df295..11f2d07 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2363be();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
index e8df295..11f2d07 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2363be();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.msl
index 9a31e29..689aee7 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.msl
index a265421..d3391df 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2363be(texture2d_array<int, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.spvasm
index 6268cf7..50d749b 100644
--- a/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2363be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 73
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,17 +70,17 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %44 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %56 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %60 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %63 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2363be = OpFunction %v4int None %18
          %19 = OpLabel
@@ -93,45 +95,56 @@
          %32 = OpLoad %v2uint %arg_1 None
          %33 = OpLoad %int %arg_2 None
          %34 = OpLoad %uint %arg_3 None
-         %35 = OpBitcast %uint %33
-         %37 = OpCompositeConstruct %v3uint %32 %35
-         %38 = OpImageFetch %v4int %31 %37 Lod %34
-               OpStore %res %38
-         %41 = OpLoad %v4int %res None
-               OpReturnValue %41
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpBitcast %uint %33
+         %41 = OpExtInst %uint %42 UMin %40 %39
+         %43 = OpImageQueryLevels %uint %31
+         %44 = OpISub %uint %43 %uint_1
+         %45 = OpExtInst %uint %42 UMin %34 %44
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %24
+         %49 = OpExtInst %v2uint %42 UMin %32 %48
+         %50 = OpCompositeConstruct %v3uint %49 %41
+         %51 = OpImageFetch %v4int %31 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4int %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_2363be
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4int %textureLoad_2363be
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %51 = OpLabel
-         %52 = OpFunctionCall %v4int %textureLoad_2363be
-         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %53 %52 None
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
+         %64 = OpFunctionCall %v4int %textureLoad_2363be
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %65 %64 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %56
-         %57 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %60
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %61 %63 None
-         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %65 = OpFunctionCall %v4int %textureLoad_2363be
-               OpStore %64 %65 None
-         %66 = OpLoad %VertexOutput %out None
-               OpReturnValue %66
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %77 = OpFunctionCall %v4int %textureLoad_2363be
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
                OpFunctionEnd
-%vertex_main = OpFunction %void None %44
-         %68 = OpLabel
-         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %70 = OpCompositeExtract %v4float %69 0
-               OpStore %vertex_main_position_Output %70 None
-         %71 = OpCompositeExtract %v4int %69 1
-               OpStore %vertex_main_loc0_Output %71 None
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4int %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.glsl
index 0d040ba..6be8a63 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_23ff89() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_23ff89() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_23ff89() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
index 38796f8..1d55333 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_23ff89() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23ff89();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
index 38796f8..1d55333 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_23ff89() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_23ff89();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.msl
index 1befc79..27bec18 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_23ff89(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.msl
index 24769ad..1460f43 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_23ff89(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.spvasm
index 7f6130e..8913da5 100644
--- a/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/23ff89.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_23ff89 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,44 +89,52 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %31 = OpCompositeConstruct %v3uint %28 %29
-         %32 = OpImageRead %v4uint %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %35 UMin %28 %38
+         %40 = OpCompositeConstruct %v3uint %39 %34
+         %41 = OpImageRead %v4uint %27 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_23ff89
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_23ff89
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_23ff89
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_23ff89
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_23ff89
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_23ff89
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
index 69ac650..b6dfc42 100644
--- a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_25b67f() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
index 69ac650..b6dfc42 100644
--- a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_25b67f() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.msl
index aabec76..79e17be 100644
--- a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_25b67f(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.msl
index f386cae..299ecd2 100644
--- a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_25b67f(texture2d<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.spvasm
index 29ca6be..51aa587 100644
--- a/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/25b67f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_25b67f = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %20 = OpISub %v2uint %19 %15
+         %21 = OpExtInst %v2uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_25b67f
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_25b67f
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_25b67f
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_25b67f
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
index a00eb9e..51e607c 100644
--- a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_26b8f6() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
index a00eb9e..51e607c 100644
--- a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_26b8f6() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.msl
index b45c3fc..017a1db 100644
--- a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_26b8f6(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.msl
index 18576a3..38712c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_26b8f6(texture3d<uint, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.spvasm
index 5ca8a79..0682f3e 100644
--- a/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/26b8f6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_26b8f6 = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %20 = OpISub %v3uint %19 %15
+         %21 = OpExtInst %v3uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_26b8f6
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_26b8f6
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_26b8f6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_26b8f6
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.glsl
index 1033c9c..d30a5b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_26c4f8() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_26c4f8() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_26c4f8() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
index 627119a..425d9ff 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_26c4f8() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26c4f8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
index 627119a..425d9ff 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_26c4f8() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26c4f8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.msl
index 85be0ec..346cb6d 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_26c4f8(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.msl
index 41c951d..105e949 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_26c4f8(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.spvasm
index f079c39..289afcc 100644
--- a/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/26c4f8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_26c4f8 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,44 +84,48 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+         %35 = OpVectorShuffle %v4float %34 %34 2 1 0 3
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_26c4f8
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_26c4f8
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_26c4f8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_26c4f8
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_26c4f8
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_26c4f8
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.glsl
index e358d12..bf3e246 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_26d7f1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_26d7f1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_26d7f1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
index 2d967b2..c1efb1f 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_26d7f1() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26d7f1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
index 2d967b2..c1efb1f 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_26d7f1() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_26d7f1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.msl
index 21667fe..c9aad5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_26d7f1(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.msl
index a7aa9c5..da2e189 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_26d7f1(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.spvasm
index c180a7a..ab9823b 100644
--- a/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/26d7f1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -70,15 +72,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_26d7f1 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -90,45 +92,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %23
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4uint %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_26d7f1
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_26d7f1
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_26d7f1
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_26d7f1
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_26d7f1
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_26d7f1
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.glsl
index 4935ffb..2e0db9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_272e7a() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_272e7a() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
index bb95fe8..cf7a10f 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_272e7a() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
index bb95fe8..cf7a10f 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_272e7a() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.msl
index c5f3efb..f7236b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_272e7a(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.msl
index cea4b0b..1e367bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_272e7a(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.spvasm
index a28fd50..1896200 100644
--- a/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/272e7a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_272e7a = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_272e7a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_272e7a
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_272e7a
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_272e7a
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.glsl
index e9672c9..7a9e741 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_276643() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_276643() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_276643() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
index bf6e4fb..bb76766 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_276643() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276643();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
index bf6e4fb..bb76766 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_276643() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276643();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.msl
index d4b6e8d..d2a7aab 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_276643(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.msl
index c6a14df..c9b59b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_276643(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.spvasm
index 6cebc20..78c40c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/276643.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_276643 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_276643
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_276643
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_276643
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_276643
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_276643
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_276643
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.glsl
index 10e36d5..fe9f986 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_276a2c() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_276a2c() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_276a2c() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
index 3d9aee0d..b089c2e 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_276a2c() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276a2c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
index 3d9aee0d..b089c2e 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_276a2c() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_276a2c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.msl
index b47e08a..08ca48a 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_276a2c(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.msl
index e4ac877..7a22fc9 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_276a2c(texture1d<uint, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.spvasm
index d254220..e742776 100644
--- a/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/276a2c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,18 +64,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_276a2c = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageRead %v4uint %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4uint %24 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_276a2c
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4uint %textureLoad_276a2c
          %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_276a2c
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4uint %textureLoad_276a2c
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_276a2c
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.glsl
index 29fabc6..5d49895 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_2887d7() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_2887d7() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2887d7() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
index 2c8caaa..940cbf4 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2887d7() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2887d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
index 2c8caaa..940cbf4 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_2887d7() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2887d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.msl
index 17bb8c6..a3e3a13 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_2887d7(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.msl
index 0abf816..1648349 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2887d7(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.spvasm
index d564f7f..0b334ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2887d7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2887d7 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_2887d7
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_2887d7
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_2887d7
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_2887d7
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_2887d7
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.glsl
index 60d4928..279e0b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_2a82d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_2a82d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_2a82d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
index ace6a48..bbfb2ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_2a82d9() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2a82d9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
index ace6a48..bbfb2ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_2a82d9() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2a82d9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.msl
index 47f8236..959a70a 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_2a82d9(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.msl
index e9b49c0..1ff73b6 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_2a82d9(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.spvasm
index 8dd848b..0b647e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2a82d9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,15 +70,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2a82d9 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -88,44 +90,52 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %32 = OpCompositeConstruct %v3uint %29 %30
-         %33 = OpImageRead %v4int %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4int %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %30 %34
+         %37 = OpImageQuerySize %v3uint %28
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %24
+         %40 = OpExtInst %v2uint %36 UMin %29 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4int %28 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_2a82d9
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_2a82d9
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_2a82d9
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_2a82d9
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %60 = OpFunctionCall %v4int %textureLoad_2a82d9
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_2a82d9
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4int %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.glsl
index da0dfbb..a579874 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2ae485() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2ae485() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2ae485() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
index 1929328..b286ff0 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2ae485() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2ae485();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
index 1929328..b286ff0 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2ae485() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2ae485();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.msl
index c201ab5..795eeef 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_2ae485(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.msl
index 6b41a13..9818120 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2ae485(texture2d<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.spvasm
index ae77a8d..ccf357b 100644
--- a/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2ae485.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2ae485 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %30 = OpISub %v2uint %27 %31
+         %33 = OpBitcast %v2uint %26
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_2ae485
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_2ae485
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_2ae485
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_2ae485
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_2ae485
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_2ae485
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.glsl
index e847e10..7281b5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2c72ae() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2c72ae() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2c72ae() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
index 57ebaea..2bcd34f 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2c72ae() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2c72ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
index 57ebaea..2bcd34f 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2c72ae() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2c72ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.msl
index b4171c0..0fd53e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_2c72ae(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.msl
index dd950a5..565bbff 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_2c72ae(texture2d<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.spvasm
index 77a71f8..d25c057 100644
--- a/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2c72ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2c72ae = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %29 = OpISub %v2uint %28 %24
+         %30 = OpExtInst %v2uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_2c72ae
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_2c72ae
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_2c72ae
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_2c72ae
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_2c72ae
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_2c72ae
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
index 3e85328..4f81718 100644
--- a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_2cee30() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
index 3e85328..4f81718 100644
--- a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_2cee30() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.msl
index 4849af0..b6e8b00 100644
--- a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_2cee30(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.msl
index 6770f3f..3a23d87 100644
--- a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2cee30(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.spvasm
index 78f775b..af77040 100644
--- a/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2cee30.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_2cee30 = OpFunction %v4int None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %16
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4int %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_2cee30
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_2cee30
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_2cee30
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_2cee30
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.glsl
index 59e0251..fcbd8af 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_2d479c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_2d479c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_2d479c() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
index bfc8ae9..438d3f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_2d479c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d479c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
index bfc8ae9..438d3f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_2d479c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d479c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.msl
index 8b18512..63dbcd4 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_2d479c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.msl
index 4af8cb3..c8a6d55 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2d479c(texture2d<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.spvasm
index a8de371..4939b4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2d479c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,16 +65,18 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %62 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2d479c = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %v2uint %27 %32
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %28
+         %39 = OpExtInst %v2uint %33 UMin %38 %36
+         %40 = OpImageFetch %v4float %27 %39 Lod %32
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_2d479c
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_2d479c
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_2d479c
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_2d479c
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_2d479c
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%vertex_main_inner = OpFunction %VertexOutput None %58
          %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %66 = OpFunctionCall %v4float %textureLoad_2d479c
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %46
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.glsl
index 00f67d6..3cab45e 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2d6cf7() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_2d6cf7() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_2d6cf7() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
index dfdf9bd..b8cc595 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2d6cf7() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d6cf7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
index dfdf9bd..b8cc595 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_2d6cf7() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2d6cf7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.msl
index 419d35f..2070a3c 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_2d6cf7(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.msl
index 7202e95..220bd58 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_2d6cf7(texture1d<int, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.spvasm
index de7aa14..80cf035 100644
--- a/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2d6cf7.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2d6cf7 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +85,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageRead %v4int %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4int %23 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_2d6cf7
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4int %textureLoad_2d6cf7
          %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_2d6cf7
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4int %textureLoad_2d6cf7
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_2d6cf7
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
index 130efc8..3395621 100644
--- a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_2dbfc2() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
index 130efc8..3395621 100644
--- a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_2dbfc2() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.msl
index 946d9a8..4465b4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_2dbfc2(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.msl
index 8a93346..67e7aa8 100644
--- a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2dbfc2(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.spvasm
index fe9c8e9..a517042 100644
--- a/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2dbfc2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_2dbfc2 = OpFunction %v4float None %10
@@ -59,25 +61,33 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-         %29 = OpVectorShuffle %v4float %28 %28 2 1 0 3
-               OpStore %res %29
-         %32 = OpLoad %v4float %res None
-               OpReturnValue %32
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+         %38 = OpVectorShuffle %v4float %37 %37 2 1 0 3
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_2dbfc2
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_2dbfc2
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_2dbfc2
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_2dbfc2
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.glsl
index c45565b..41f498a 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 vec4 textureLoad_2e09aa() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 vec4 textureLoad_2e09aa() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 vec4 textureLoad_2e09aa() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
index 79f21aa..0aacab0 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e09aa();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
index 79f21aa..0aacab0 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e09aa();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.msl
index 433ee1a..a36fe50 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_2e09aa(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_2;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.msl
index 879ab79..311e28d 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_2e09aa(texture2d_ms<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.spvasm
index ae2869f..20d98ab 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2e09aa.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2e09aa = OpFunction %v4float None %15
          %16 = OpLabel
@@ -82,43 +84,46 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Sample %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %25
+         %29 = OpISub %v2uint %28 %21
+         %30 = OpExtInst %v2uint %31 UMin %26 %29
+         %32 = OpImageFetch %v4float %25 %30 Sample %27
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_2e09aa
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_2e09aa
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_2e09aa
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_2e09aa
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_2e09aa
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_2e09aa
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.glsl
index 814191e..36a89a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_2e3552() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_2e3552() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_2e3552() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
index 48a1ec5..c8c18fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_2e3552() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e3552();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
index 48a1ec5..c8c18fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_2e3552() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_2e3552();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.msl
index 8e26982..b302502 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_2e3552(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.msl
index e5c13d5..07b5b96 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_2e3552(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.spvasm
index 83df8ec..2f40319 100644
--- a/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2e3552.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_2e3552 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +88,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_2e3552
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_2e3552
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_2e3552
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_2e3552
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_2e3552
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_2e3552
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.glsl
index 0b9c4d1..88b885e 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_2eaf31() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_2eaf31() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
index f7f3a95..96e7e05 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2eaf31() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
index f7f3a95..96e7e05 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_2eaf31() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.msl
index 20353c2..b9a08b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_2eaf31(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.msl
index 158258d..423bfa3 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_2eaf31(texture2d<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.spvasm
index 9f9a161..938c01f 100644
--- a/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/2eaf31.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_2eaf31 = OpFunction %v4int None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_2eaf31
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_2eaf31
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_2eaf31
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_2eaf31
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.glsl
index 9285783..361ae92 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_313c73() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_313c73() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_313c73() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
index cc6c07f..e3764bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_313c73() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_313c73();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
index cc6c07f..e3764bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_313c73() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_313c73();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.msl
index 58502e4..af61b16 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_313c73(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.msl
index 2de39d1..0504136 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_313c73(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.spvasm
index db51bff..1bdab67 100644
--- a/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/313c73.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,15 +70,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_313c73 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -88,44 +90,52 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %32 = OpCompositeConstruct %v3uint %29 %30
-         %33 = OpImageRead %v4int %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4int %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %30 %34
+         %37 = OpImageQuerySize %v3uint %28
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %24
+         %40 = OpExtInst %v2uint %36 UMin %29 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4int %28 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_313c73
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_313c73
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_313c73
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_313c73
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %60 = OpFunctionCall %v4int %textureLoad_313c73
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_313c73
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4int %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.glsl
index b89d9f0..901565a 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_31db4b() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_31db4b() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_31db4b() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
index 1d9151a..7796331 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_31db4b() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_31db4b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
index 1d9151a..7796331 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_31db4b() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_31db4b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.msl
index 6aa96ab..612cc15 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_31db4b(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.msl
index 420a743..d1d63c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_31db4b(texture1d<uint, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.spvasm
index 2f6e15c..ccf3198 100644
--- a/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/31db4b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_31db4b = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -80,43 +82,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageRead %v4uint %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageRead %v4uint %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_31db4b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_31db4b
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_31db4b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_31db4b
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %52 = OpFunctionCall %v4uint %textureLoad_31db4b
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_31db4b
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.glsl
index 802403f..cb47976 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_321210() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_321210() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_321210() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
index dfc3cec..d7aa382 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_321210() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_321210();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
index dfc3cec..d7aa382 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_321210() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_321210();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.msl
index bd5281a..72d8329 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_321210(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.msl
index ef6f7f7..1204096 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_321210(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.spvasm
index 1a49270..7d552f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/321210.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_321210 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4uint %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_321210
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_321210
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_321210
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_321210
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_321210
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_321210
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
index a088283..e7c8980 100644
--- a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_32a7b8() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
index a088283..e7c8980 100644
--- a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_32a7b8() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.msl
index ac08589..3d46db8 100644
--- a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_32a7b8(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.msl
index 41f6f06..d4e0880 100644
--- a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_32a7b8(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.spvasm
index 77aaee6..c471833 100644
--- a/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/32a7b8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_32a7b8 = OpFunction %v4int None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %16
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4int %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_32a7b8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_32a7b8
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_32a7b8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_32a7b8
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.glsl
index a458707..8366aaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_33d3aa() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_33d3aa() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_33d3aa() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
index 0b60b48..ddd0cc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_33d3aa() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_33d3aa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
index 0b60b48..ddd0cc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_33d3aa() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_33d3aa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.msl
index 0bfcef3..5323daf 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_33d3aa(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.msl
index 91706f2..5280fb7 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_33d3aa(texture1d<int, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.spvasm
index 6f94850..7136dca 100644
--- a/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/33d3aa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_33d3aa = OpFunction %v4int None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageRead %v4int %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageRead %v4int %24 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_33d3aa
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_33d3aa
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_33d3aa
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_33d3aa
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_33d3aa
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_33d3aa
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.glsl
index 4ba7053..7f010e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_348827() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_348827() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_348827() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
index 4c7652c..14e8b3c 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_348827() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_348827();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
index 4c7652c..14e8b3c 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_348827() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_348827();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.msl
index 3b44d2f..cf0f119 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_348827(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.msl
index 0dbaa34..069f8fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_348827(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.spvasm
index 60e3f08..5058628 100644
--- a/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/348827.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_348827 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,44 +89,52 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %31 = OpCompositeConstruct %v3uint %28 %29
-         %32 = OpImageRead %v4uint %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %35 UMin %28 %38
+         %40 = OpCompositeConstruct %v3uint %39 %34
+         %41 = OpImageRead %v4uint %27 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_348827
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_348827
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_348827
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_348827
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_348827
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_348827
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.glsl
index 028862e..f02cfe5 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_34d97c() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_34d97c() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
index e748847..2b6b160 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_34d97c() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
index e748847..2b6b160 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_34d97c() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.msl
index aa295e8..d0dac18 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_34d97c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.msl
index bb23595..9014c92 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_34d97c(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.spvasm
index da829a7..458d711 100644
--- a/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/34d97c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,13 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_34d97c = OpFunction %v4uint None %10
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4uint %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %22
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %21
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4uint %20 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_34d97c
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_34d97c
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_34d97c
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_34d97c
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.glsl
index bd24dac..39ffd1e 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_35a5e2() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_35a5e2() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
index a8e480f..d204d4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_35a5e2() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
index a8e480f..d204d4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_35a5e2() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.msl
index 24f2f04..6bcbc05 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_35a5e2(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.msl
index 7b83d8f..0b4ea13 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_35a5e2(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.spvasm
index 0a21164..eab1b89 100644
--- a/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/35a5e2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_35a5e2 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +55,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_35a5e2
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_35a5e2
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_35a5e2
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.glsl
index a19e22e..23ab290 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_35d464() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_35d464() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_35d464() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
index aba5399..50ded7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_35d464() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_35d464();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
index aba5399..50ded7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_35d464() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_35d464();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.msl
index fb03288..300c32b 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_35d464(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.msl
index c089022..edaa1c0 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_35d464(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.spvasm
index 27fa3730..77785cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/35d464.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_35d464 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,44 +91,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_35d464
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_35d464
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_35d464
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_35d464
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_35d464
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_35d464
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.glsl
index 84fcf3d..665988e 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_374351() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_374351() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_374351() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
index 05100d6..705878c 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_374351() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_374351();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
index 05100d6..705878c 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_374351() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_374351();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.msl
index 963e48a..640dc1b 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_374351(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.msl
index 5cba369..fc052b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_374351(texture3d<uint, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.spvasm
index 2ebce1b..101912a 100644
--- a/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/374351.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_374351 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %28 = OpISub %v3uint %27 %23
+         %29 = OpExtInst %v3uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_374351
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_374351
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_374351
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_374351
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_374351
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_374351
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.glsl
index e3316fb..5c71cac 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_388688() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_388688() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_388688() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
index 7021991..65da92d 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_388688() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_388688();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
index 7021991..65da92d 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_388688() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_388688();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.msl
index 3d0bb3e..e296f9b 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_388688(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.msl
index 97682fc..2d1fb33 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_388688(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.spvasm
index 6759aee..e8642ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/388688.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_388688 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_388688
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_388688
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_388688
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_388688
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_388688
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_388688
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.glsl
index 8310272..3df2d96 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_38f8ab() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_38f8ab() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_38f8ab() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
index 20670be..8ba42bb 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  int4 res = int4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_38f8ab();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
index 20670be..8ba42bb 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  int4 res = int4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_38f8ab();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.msl
index 30a0b55..91b9921 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_38f8ab(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.msl
index 2fe843a..ec59d64 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_38f8ab(texture2d_ms<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.spvasm
index 4c49d16..033170b 100644
--- a/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/38f8ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_38f8ab = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,47 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Sample %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQuerySize %v2uint %29
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %30
+         %37 = OpExtInst %v2uint %38 UMin %36 %34
+         %39 = OpImageFetch %v4int %29 %37 Sample %31
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_38f8ab
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_38f8ab
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_38f8ab
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_38f8ab
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_38f8ab
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %66 = OpFunctionCall %v4int %textureLoad_38f8ab
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %45
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4int %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
index 8d6870f..b8af608 100644
--- a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_39016c() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
index 8d6870f..b8af608 100644
--- a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_39016c() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.msl
index 4871f73..5f8af71 100644
--- a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_39016c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.msl
index 1f1b220..5b0cab8 100644
--- a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_39016c(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.spvasm
index a99648d..30641d0 100644
--- a/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/39016c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_39016c = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_39016c
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_39016c
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_39016c
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_39016c
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
index 5f85ec0..9e54666 100644
--- a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_395447() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
index 5f85ec0..9e54666 100644
--- a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_395447() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.msl
index b367aa0..02b19e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_395447(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.msl
index 8d9206b..5ced912 100644
--- a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_395447(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.spvasm
index 400f2fb..f1bf376 100644
--- a/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/395447.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_395447 = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_395447
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_395447
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_395447
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_395447
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.glsl
index 320a8ae..0c79769 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_39ef40() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_39ef40() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_39ef40() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
index e190d8f..edbc18d 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_39ef40() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_39ef40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
index e190d8f..edbc18d 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_39ef40() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_39ef40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.msl
index 9bbfb59..fab0c9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_39ef40(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.msl
index 2eab689..fe1c8ed 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_39ef40(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.spvasm
index f767151..1fe84a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/39ef40.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_39ef40 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_39ef40
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_39ef40
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_39ef40
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_39ef40
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_39ef40
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_39ef40
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
index b654741..3ed811f 100644
--- a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_3a2350() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
index b654741..3ed811f 100644
--- a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_3a2350() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.msl
index b0e1dcb..5c2af18 100644
--- a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_3a2350(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.msl
index fac3071..242fcf2 100644
--- a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3a2350(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.spvasm
index 415fc15..6277cc8 100644
--- a/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3a2350.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_3a2350 = OpFunction %v4uint None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4uint %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_3a2350
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_3a2350
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_3a2350
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_3a2350
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.glsl
index d00800e..b053ca7 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_3aea13() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_3aea13() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
index 65ced96..0fd7d10 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_3aea13() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
index 65ced96..0fd7d10 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_3aea13() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.msl
index c66998e..5888141 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_3aea13(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.msl
index 64ee6e4..1f03ff9 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_3aea13(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.spvasm
index 68915a7..8e73b5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3aea13.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_3aea13 = OpFunction %v4int None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4int %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_3aea13
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_3aea13
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_3aea13
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_3aea13
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.glsl
index 3e3921b..d6f3e54 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_3bbc2b() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_3bbc2b() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
index 30f854e..6442b04 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3bbc2b() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
index 30f854e..6442b04 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3bbc2b() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.msl
index f2fca79..0f6efa3 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_3bbc2b(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.msl
index 7c7a78d..21a10c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3bbc2b(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.spvasm
index a2f62ec..cdea56d 100644
--- a/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3bbc2b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_3bbc2b = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_3bbc2b
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_3bbc2b
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_3bbc2b
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.glsl
index 7fd2138..64ab9bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_3c0d9e() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_3c0d9e() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_3c0d9e() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
index 3fd29b6..18d4d02 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_3c0d9e() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c0d9e();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
index 3fd29b6..18d4d02 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_3c0d9e() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c0d9e();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.msl
index ad9096a..8f903f7 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_3c0d9e(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.msl
index 06cedd0..1439738 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3c0d9e(texture2d<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.spvasm
index d0b07ea..40ead98 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3c0d9e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c0d9e = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %30 = OpISub %v2uint %28 %31
+         %33 = OpBitcast %v2uint %27
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_3c0d9e
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_3c0d9e
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.glsl
index d97031e..909cd35 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3c9587() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3c9587() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3c9587() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
index 191bbd2..12bb844 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c9587() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c9587();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
index 191bbd2..12bb844 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3c9587() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c9587();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.msl
index 895deee..81709e5 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_3c9587(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.msl
index 28fe43b..6b0adf4 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3c9587(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.spvasm
index d170c1c..ef10d99 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3c9587.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c9587 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_3c9587
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_3c9587
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_3c9587
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_3c9587
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_3c9587
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_3c9587
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.glsl
index 68d4ef4..240684b 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_3c96e8() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_3c96e8() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3c96e8() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_1), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  vec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
index 566c6db..282946f 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c96e8();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
index 566c6db..282946f 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3c96e8();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.msl
index 575e9a1..51cc3f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint const v = arg_2;
-  uint const v_1 = arg_3;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.msl
index bfa41ac..7c10d45 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3c96e8(texture2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.spvasm
index 36e75e8..ae6136a 100644
--- a/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3c96e8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 83
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %46 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %56 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %53 = OpTypeFunction %VertexOutput
+         %67 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
-         %59 = OpConstantNull %v4float
+         %71 = OpConstantNull %VertexOutput
+         %73 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3c96e8 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -89,45 +93,56 @@
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %uint %arg_2 None
          %31 = OpLoad %uint %arg_3 None
-         %32 = OpBitcast %int %30
-         %34 = OpCompositeConstruct %v3int %29 %32
-         %35 = OpImageFetch %v4float %28 %34 Lod %31
-               OpStore %res %35
-         %38 = OpLoad %v4float %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %35 = OpCompositeExtract %uint %32 2
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %38 UMin %30 %36
+         %39 = OpImageQueryLevels %uint %28
+         %40 = OpISub %uint %39 %uint_1
+         %41 = OpExtInst %uint %38 UMin %31 %40
+         %42 = OpImageQuerySizeLod %v3uint %28 %41
+         %43 = OpVectorShuffle %v2uint %42 %42 0 1
+         %45 = OpISub %v2uint %43 %46
+         %47 = OpBitcast %v2uint %29
+         %48 = OpExtInst %v2uint %38 UMin %47 %45
+         %49 = OpCompositeConstruct %v3uint %48 %37
+         %50 = OpImageFetch %v4float %28 %49 Lod %41
+               OpStore %res %50
+         %53 = OpLoad %v4float %res None
+               OpReturnValue %53
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_3c96e8
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %56
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_3c96e8
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4float %textureLoad_3c96e8
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %56
+         %62 = OpLabel
+         %63 = OpFunctionCall %v4float %textureLoad_3c96e8
+         %64 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %59 None
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %61 = OpFunctionCall %v4float %textureLoad_3c96e8
-               OpStore %60 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+%vertex_main_inner = OpFunction %VertexOutput None %67
+         %68 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %71
+         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %72 %73 None
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %75 = OpFunctionCall %v4float %textureLoad_3c96e8
+               OpStore %74 %75 None
+         %76 = OpLoad %VertexOutput %out None
+               OpReturnValue %76
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4float %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main = OpFunction %void None %56
+         %78 = OpLabel
+         %79 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %80 = OpCompositeExtract %v4float %79 0
+               OpStore %vertex_main_position_Output %80 None
+         %81 = OpCompositeExtract %v4float %79 1
+               OpStore %vertex_main_loc0_Output %81 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
index 722e0b1..77ece63 100644
--- a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3cfb9c() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
index 722e0b1..77ece63 100644
--- a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_3cfb9c() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.msl
index cfc3580..f10df48 100644
--- a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_3cfb9c(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.msl
index 1f2e32a..89d0e97 100644
--- a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_3cfb9c(texture3d<uint, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.spvasm
index 14624eb..716bc8c 100644
--- a/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3cfb9c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_3cfb9c = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %22 = OpISub %v3uint %20 %23
+         %25 = OpBitcast %v3uint %19
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_3cfb9c
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_3cfb9c
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_3cfb9c
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_3cfb9c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.glsl
index 9d7062c..99aead2 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_3d001b() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_3d001b() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_3d001b() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
index cd4b32c..c631dd5 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d001b() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d001b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
index cd4b32c..c631dd5 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_3d001b() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d001b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.msl
index c224203..fc66553 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_3d001b(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.msl
index 0240a38..76a388f 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_3d001b(texture3d<int, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.spvasm
index 8799f7f..8aa4197 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3d001b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d001b = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %30 = OpISub %v3uint %27 %31
+         %33 = OpBitcast %v3uint %26
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_3d001b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_3d001b
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_3d001b
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_3d001b
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_3d001b
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_3d001b
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.glsl
index 648d33c..7cde528 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_3d3fd1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_3d3fd1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_3d3fd1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
index 0b208d3..0146eba 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d3fd1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
index 0b208d3..0146eba 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d3fd1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.msl
index fd7fbde..d697a96 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.msl
index ec6453f..8836a11 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.spvasm
index f43aee8..2e97b41 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3d3fd1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,17 +70,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %55 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d3fd1 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -93,44 +95,56 @@
          %32 = OpLoad %v2uint %arg_1 None
          %33 = OpLoad %uint %arg_2 None
          %34 = OpLoad %int %arg_3 None
-         %36 = OpCompositeConstruct %v3uint %32 %33
-         %37 = OpImageFetch %v4int %31 %36 Lod %34
-               OpStore %res %37
-         %40 = OpLoad %v4int %res None
-               OpReturnValue %40
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpExtInst %uint %41 UMin %33 %39
+         %42 = OpImageQueryLevels %uint %31
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %34
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %24
+         %49 = OpExtInst %v2uint %41 UMin %32 %48
+         %50 = OpCompositeConstruct %v3uint %49 %40
+         %51 = OpImageFetch %v4int %31 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4int %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_3d3fd1
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4int %textureLoad_3d3fd1
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4int %textureLoad_3d3fd1
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %52 %51 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
          %64 = OpFunctionCall %v4int %textureLoad_3d3fd1
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %65 %64 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4int %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %77 = OpFunctionCall %v4int %textureLoad_3d3fd1
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4int %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.glsl
index 59d8ec5..c21c740 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_3d9c90() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_3d9c90() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3d9c90() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
index 7602494..d21a573 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3d9c90() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d9c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
index 7602494..d21a573 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3d9c90() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3d9c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.msl
index 3526af5..8ed1698 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_3d9c90(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.msl
index 6dd846f..9da03cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3d9c90(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.spvasm
index 8344fac..34f0713 100644
--- a/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3d9c90.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3d9c90 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_3d9c90
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_3d9c90
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_3d9c90
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_3d9c90
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_3d9c90
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_3d9c90
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.glsl
index e3fb8b0..b5f77f8 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_3da3ed() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_3da3ed() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3da3ed() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(v_1), v_3), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
index c4c7837..bd38651 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_3da3ed() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  float4 res = float4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3da3ed();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
index c4c7837..bd38651 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_3da3ed() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  float4 res = float4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3da3ed();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.msl
index 5a8b998..5919c46 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 float4 textureLoad_3da3ed(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.msl
index 42451a4..ea09202 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3da3ed(texture1d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.spvasm
index 60de1be..f301dce 100644
--- a/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3da3ed.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,14 +66,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3da3ed = OpFunction %v4float None %15
          %16 = OpLabel
@@ -83,43 +85,50 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %int %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpExtInst %uint %31 UMin %27 %29
+         %32 = OpImageQuerySizeLod %uint %25 %30
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %26
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageFetch %v4float %25 %35 Lod %30
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_3da3ed
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_3da3ed
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_3da3ed
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_3da3ed
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_3da3ed
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_3da3ed
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.glsl
index 982555d..41e5905 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_3e16a8() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_3e16a8() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
index 8457545..724837d 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3e16a8() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
index 8457545..724837d 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_3e16a8() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.msl
index 50b1ba6..0951fc4 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_3e16a8(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.msl
index 36cd2cb0..63d4fe5 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_3e16a8(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.spvasm
index f814192..0196d39 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3e16a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,11 +42,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_3e16a8 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -53,22 +58,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_3e16a8
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_3e16a8
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_3e16a8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_3e16a8
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.glsl
index 271b3e3..83ae4b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3e5f6a() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_3e5f6a() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_3e5f6a() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
index ff4b43d..4e1bf70 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3e5f6a() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3e5f6a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
index ff4b43d..4e1bf70 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_3e5f6a() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_3e5f6a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.msl
index 389d4c0..5163466 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_3e5f6a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.msl
index 0004b64..90ecf76 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_3e5f6a(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.spvasm
index 6d54bb9..30c0137 100644
--- a/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/3e5f6a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_3e5f6a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_3e5f6a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_3e5f6a
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_3e5f6a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_3e5f6a
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_3e5f6a
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_3e5f6a
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
index d4d50ad..9603bab 100644
--- a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_40ee8b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
index d4d50ad..9603bab 100644
--- a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_40ee8b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.msl
index b7f5a59..43c7022 100644
--- a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_40ee8b(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.msl
index 982e1c3..a040269 100644
--- a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_40ee8b(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.spvasm
index 865be8d..d837fbe 100644
--- a/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/40ee8b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_40ee8b = OpFunction %v4int None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4int %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_40ee8b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_40ee8b
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_40ee8b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_40ee8b
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
index 382e5e6..eb4ad64 100644
--- a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4212a1() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
index 382e5e6..eb4ad64 100644
--- a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4212a1() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.msl
index 3996eb0..455379b 100644
--- a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_4212a1(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.msl
index 6e09a59..75488a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4212a1(texture2d<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.spvasm
index 29cbecf..3043ba9 100644
--- a/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4212a1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4212a1 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %22 = OpISub %v2uint %19 %23
+         %25 = OpBitcast %v2uint %18
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_4212a1
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_4212a1
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_4212a1
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_4212a1
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.glsl
index 4b3919e..4f3f717 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_424afd() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_424afd() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
index 241c1d6..b23e07b 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_424afd() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
index 241c1d6..b23e07b 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_424afd() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.msl
index d96aa32..70a3a25 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_424afd(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.msl
index 80e6915..3279be2 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_424afd(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.spvasm
index 44adb8f..bd68ae3 100644
--- a/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/424afd.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_424afd = OpFunction %v4int None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2int %arg_1 None
          %21 = OpLoad %int %arg_2 None
-         %23 = OpCompositeConstruct %v3int %20 %21
-         %24 = OpImageRead %v4int %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %25 = OpCompositeExtract %uint %22 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %21
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %19
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %20
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4int %19 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_424afd
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_424afd
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_424afd
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_424afd
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
index eca7a23..dda86de 100644
--- a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_42a631() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
index eca7a23..dda86de 100644
--- a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_42a631() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.msl
index cf9762c..5e46aff 100644
--- a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_42a631(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.msl
index 25bd2af..7d0135c 100644
--- a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_42a631(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.spvasm
index d0a988c..c9950e8 100644
--- a/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/42a631.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_42a631 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_42a631
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_42a631
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_42a631
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.glsl
index f353820..545ed92 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_43484a() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_43484a() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
index 91475ca..9095eb7 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_43484a() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
index 91475ca..9095eb7 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_43484a() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.msl
index 235797b..966fdb7 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_43484a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.msl
index 9db0f07..5bf67c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_43484a(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.spvasm
index 1784732..7580a8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/43484a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_43484a = OpFunction %v4float None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_43484a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_43484a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_43484a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_43484a
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.glsl
index 68973af..c471607 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_439e2a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_439e2a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_439e2a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
index 86eea58..36081f0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_439e2a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_439e2a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
index 86eea58..36081f0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_439e2a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_439e2a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.msl
index 9e22025..ef2f951 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_439e2a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.msl
index c34825b..6bc5293 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_439e2a(texture2d<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.spvasm
index 17a16ca..83593c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/439e2a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_439e2a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +86,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %29
+         %33 = OpExtInst %uint %34 UMin %32 %31
+         %35 = OpImageQuerySizeLod %v2uint %27 %33
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %34 UMin %28 %36
+         %38 = OpImageFetch %v4float %27 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_439e2a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_439e2a
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_439e2a
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_439e2a
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_439e2a
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_439e2a
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
index 7756224..a4e7007 100644
--- a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43cd86() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
index 7756224..a4e7007 100644
--- a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_43cd86() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.msl
index 2dbceb5..8e430cb 100644
--- a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_43cd86(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.msl
index 0157db0..3762f5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_43cd86(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.spvasm
index e47517d..5f25efd 100644
--- a/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/43cd86.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_43cd86 = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_43cd86
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_43cd86
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_43cd86
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_43cd86
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.glsl
index a5aedcc..7e59511 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_44c826() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_44c826() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_44c826() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
index d288014..8e8b66e 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_44c826() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_44c826();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
index d288014..8e8b66e 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_44c826() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_44c826();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.msl
index f0afb48..1e0f9c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_44c826(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.msl
index 86fc460..c372083 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_44c826(texture1d<uint, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.spvasm
index 6a413d1..901ef26 100644
--- a/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/44c826.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_44c826 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageRead %v4uint %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageRead %v4uint %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_44c826
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_44c826
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_44c826
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_44c826
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %52 = OpFunctionCall %v4uint %textureLoad_44c826
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_44c826
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
index cb7597b..915cc84 100644
--- a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_4542ae() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
index cb7597b..915cc84 100644
--- a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_4542ae() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.msl
index a054cba..c69be15 100644
--- a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_4542ae(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.msl
index c8c8c95..d236ade 100644
--- a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4542ae(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.spvasm
index c68f7c5..eaaa464 100644
--- a/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4542ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4542ae = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_4542ae
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_4542ae
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_4542ae
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_4542ae
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.glsl
index b4a07fd..8dac80f 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_454347() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_454347() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_454347() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
index 7764281..2c34e85 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_454347() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_454347();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
index 7764281..2c34e85 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_454347() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_454347();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.msl
index 3d217e6..2faf121 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_454347(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.msl
index aedc684..67ceb45 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_454347(texture1d<uint, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.spvasm
index 8e63a72..6afc843 100644
--- a/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/454347.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_454347 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -80,43 +82,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageRead %v4uint %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageRead %v4uint %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_454347
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_454347
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_454347
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_454347
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %52 = OpFunctionCall %v4uint %textureLoad_454347
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_454347
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.glsl
index 58d92be..cc4d827 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_4638a0() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_4638a0() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_4638a0() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
index 6de18cf..90104bc 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4638a0() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4638a0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
index 6de18cf..90104bc 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4638a0() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4638a0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.msl
index 520f273..8f61b86 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_4638a0(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.msl
index 7b8e59b..4f6585a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4638a0(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.spvasm
index 208b1f9..0810362 100644
--- a/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4638a0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4638a0 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4int %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_4638a0
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_4638a0
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_4638a0
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_4638a0
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_4638a0
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %73 = OpFunctionCall %v4int %textureLoad_4638a0
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4int %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.glsl
index c50d921..0f65cd9 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_469912() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_469912() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
index 774db1a..376f3c2 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_469912() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
index 774db1a..376f3c2 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_469912() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.msl
index d171504..a0871c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_469912(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.msl
index 3d03cea..b7d4e81 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_469912(texture1d<int, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.spvasm
index 579bebf..36d7b5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/469912.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
          %10 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_469912 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %int %arg_1 None
-         %17 = OpImageRead %v4int %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %19 = OpISub %uint %17 %uint_1
+         %21 = OpBitcast %uint %16
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4int %15 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_469912
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %23
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4int %textureLoad_469912
          %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_469912
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.glsl
index 476990d..f0a1cfa 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_46a93f() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  vec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_46a93f() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  vec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_46a93f() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  vec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
index fca89ad..9393bbc 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46a93f();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
index fca89ad..9393bbc 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46a93f();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.msl
index 6667513..e85f8da 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.msl
index 76ac82a..9d5999e 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_46a93f(texture2d_array<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.spvasm
index 3acb8e0..019a3a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/46a93f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,16 +68,16 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %55 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %54 = OpTypeFunction %VertexOutput
+         %66 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
-         %60 = OpConstantNull %v4float
+         %70 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_46a93f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -90,45 +92,56 @@
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
          %32 = OpLoad %uint %arg_3 None
-         %33 = OpBitcast %uint %31
-         %35 = OpCompositeConstruct %v3uint %30 %33
-         %36 = OpImageFetch %v4float %29 %35 Lod %32
-               OpStore %res %36
-         %39 = OpLoad %v4float %res None
-               OpReturnValue %39
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpBitcast %uint %31
+         %39 = OpExtInst %uint %40 UMin %38 %37
+         %41 = OpImageQueryLevels %uint %29
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %32 %42
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %40 UMin %30 %46
+         %48 = OpCompositeConstruct %v3uint %47 %39
+         %49 = OpImageFetch %v4float %29 %48 Lod %43
+               OpStore %res %49
+         %52 = OpLoad %v4float %res None
+               OpReturnValue %52
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_46a93f
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %55
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4float %textureLoad_46a93f
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %v4float %textureLoad_46a93f
-         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %51 %50 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%compute_main = OpFunction %void None %55
+         %61 = OpLabel
          %62 = OpFunctionCall %v4float %textureLoad_46a93f
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %63 %62 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4float %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main_inner = OpFunction %VertexOutput None %66
+         %67 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %70
+         %71 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %71 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %74 = OpFunctionCall %v4float %textureLoad_46a93f
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %55
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4float %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.glsl
index 3310334..1beaf87 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_46dbf5() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_46dbf5() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_46dbf5() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
index 24176e6..f94bfdd 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46dbf5() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46dbf5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
index 24176e6..f94bfdd 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_46dbf5() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_46dbf5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.msl
index 903b843..57aa384 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_46dbf5(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.msl
index 79210b3..43c4235 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_46dbf5(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.spvasm
index 2c0194b..9763baa 100644
--- a/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/46dbf5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_46dbf5 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_46dbf5
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_46dbf5
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_46dbf5
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_46dbf5
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_46dbf5
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_46dbf5
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
index d84eac2..693c0ce 100644
--- a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_473d3e() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
index d84eac2..693c0ce 100644
--- a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_473d3e() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.msl
index 04f927a..44c5eb2 100644
--- a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_473d3e(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.msl
index fc79f41..81624e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_473d3e(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.spvasm
index 6c4b962..af6c5c7 100644
--- a/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/473d3e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_473d3e = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_473d3e
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_473d3e
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_473d3e
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_473d3e
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.glsl
index e607861..b236651 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_47e818() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_47e818() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_4 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_47e818() {
   uvec3 arg_1 = uvec3(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec3 v_3 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
index b8ae1ee..ee52463 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_47e818() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_47e818();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
index b8ae1ee..ee52463 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_47e818() {
   uint3 arg_1 = (1u).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_47e818();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.msl
index d849c03..268f31c 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_47e818(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.msl
index a82ce04..5796ada 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_47e818(texture3d<int, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.spvasm
index e87f43d..6fd4334 100644
--- a/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/47e818.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_47e818 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -86,43 +88,49 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v3uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %31 = OpImageFetch %v4int %28 %29 Lod %30
-               OpStore %res %31
-         %34 = OpLoad %v4int %res None
-               OpReturnValue %34
+         %31 = OpImageQueryLevels %uint %28
+         %32 = OpISub %uint %31 %uint_1
+         %33 = OpExtInst %uint %34 UMin %30 %32
+         %35 = OpImageQuerySizeLod %v3uint %28 %33
+         %36 = OpISub %v3uint %35 %24
+         %37 = OpExtInst %v3uint %34 UMin %29 %36
+         %38 = OpImageFetch %v4int %28 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_47e818
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_47e818
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_47e818
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_47e818
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %58 = OpFunctionCall %v4int %textureLoad_47e818
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_47e818
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4int %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.glsl
index e4b9065..63e75bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_482627() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_482627() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
index 34e09fc..6b14cd1 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_482627() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
index 34e09fc..6b14cd1 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_482627() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.msl
index 6f4f1e9..9c2cf00 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_482627(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.msl
index 1aeb021..c96feb4 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_482627(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.spvasm
index 351bea8..4a83dc9 100644
--- a/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/482627.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_482627 = OpFunction %v4float None %10
@@ -58,23 +60,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_482627
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_482627
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_482627
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_482627
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.glsl
index 29ab9c6..d637e1e 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_484344() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_484344() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_484344() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
index c7129d5..487aa21 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_484344() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_484344();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
index c7129d5..487aa21 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_484344() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_484344();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.msl
index e93d94c..d63d150 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_484344(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.msl
index a262898..689ba17 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_484344(texture2d<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.spvasm
index edb227f..47cf801 100644
--- a/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/484344.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %38 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %47 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %63 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_484344 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,51 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %30 = OpISub %uint %28 %uint_1
+         %32 = OpBitcast %uint %27
+         %33 = OpExtInst %uint %34 UMin %32 %30
+         %35 = OpImageQuerySizeLod %v2uint %25 %33
+         %37 = OpISub %v2uint %35 %38
+         %39 = OpBitcast %v2uint %26
+         %40 = OpExtInst %v2uint %34 UMin %39 %37
+         %41 = OpImageFetch %v4float %25 %40 Lod %33
+               OpStore %res %41
+         %44 = OpLoad %v4float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_484344
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_484344
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
+%fragment_main = OpFunction %void None %47
          %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_484344
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+         %49 = OpFunctionCall %v4float %textureLoad_484344
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4float %textureLoad_484344
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %56 %55 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %67 = OpFunctionCall %v4float %textureLoad_484344
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %47
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4float %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.glsl
index b89a8b6..9a108e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_4951bb() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_4951bb() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_4951bb() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
index 06813b7..47a6c52 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_4951bb() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4951bb();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
index 06813b7..47a6c52 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_4951bb() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4951bb();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.msl
index a323a65..311b5fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_4951bb(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.msl
index d47d703..f0e4154 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4951bb(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.spvasm
index 195310d..d370aff 100644
--- a/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4951bb.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,14 +70,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4951bb = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,45 +89,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_4951bb
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_4951bb
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_4951bb
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_4951bb
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_4951bb
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_4951bb
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.glsl
index d02e0b3..9db2f35 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 uvec4 textureLoad_49f76f() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 uvec4 textureLoad_49f76f() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 uvec4 textureLoad_49f76f() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
index 9220411..42bd961 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_49f76f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
index 9220411..42bd961 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_49f76f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.msl
index 05cdf6b..3b8fb7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_49f76f(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_2;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.msl
index fe9c7d0..f3137b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_49f76f(texture2d_ms<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.spvasm
index af5b306..f930d6f 100644
--- a/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/49f76f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %48 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_49f76f = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -85,43 +87,46 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4uint %27 %28 Sample %29
-               OpStore %res %30
-         %33 = OpLoad %v4uint %res None
-               OpReturnValue %33
+         %30 = OpImageQuerySize %v2uint %27
+         %31 = OpISub %v2uint %30 %23
+         %32 = OpExtInst %v2uint %33 UMin %28 %31
+         %34 = OpImageFetch %v4uint %27 %32 Sample %29
+               OpStore %res %34
+         %37 = OpLoad %v4uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_49f76f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_49f76f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4uint %textureLoad_49f76f
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_49f76f
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %57 = OpFunctionCall %v4uint %textureLoad_49f76f
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %61 = OpFunctionCall %v4uint %textureLoad_49f76f
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4uint %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
index fad4f49..2411631 100644
--- a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4a5c55() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
index fad4f49..2411631 100644
--- a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_4a5c55() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.msl
index 80979eb..2a868c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_4a5c55(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.msl
index 4eefa82..39ca577 100644
--- a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_4a5c55(texture3d<int, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.spvasm
index 0001ec6..934e964 100644
--- a/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4a5c55.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_4a5c55 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_4a5c55
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_4a5c55
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_4a5c55
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_4a5c55
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.glsl
index 104b8cb..9b09392 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_4acb64() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  vec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_4acb64() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  vec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4acb64() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_4));
+  vec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
index 5a7dce9..b54e176 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4acb64();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
index 5a7dce9..b54e176 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4acb64();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.msl
index a09db67..914b099 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint const v = arg_2;
-  int const v_1 = arg_3;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.msl
index bf23799..61b9b57 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4acb64(texture2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.spvasm
index 48bf019..485ee23 100644
--- a/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4acb64.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %54 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
-         %60 = OpConstantNull %v4float
+         %73 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4acb64 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -90,45 +94,57 @@
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
          %32 = OpLoad %int %arg_3 None
-         %33 = OpBitcast %int %31
-         %35 = OpCompositeConstruct %v3int %30 %33
-         %36 = OpImageFetch %v4float %29 %35 Lod %32
-               OpStore %res %36
-         %39 = OpLoad %v4float %res None
-               OpReturnValue %39
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpExtInst %uint %39 UMin %31 %37
+         %40 = OpImageQueryLevels %uint %29
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %32
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %30
+         %50 = OpExtInst %v2uint %39 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %38
+         %52 = OpImageFetch %v4float %29 %51 Lod %43
+               OpStore %res %52
+         %55 = OpLoad %v4float %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_4acb64
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4float %textureLoad_4acb64
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %v4float %textureLoad_4acb64
-         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %51 %50 None
+%compute_main = OpFunction %void None %58
+         %64 = OpLabel
+         %65 = OpFunctionCall %v4float %textureLoad_4acb64
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %66 %65 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %62 = OpFunctionCall %v4float %textureLoad_4acb64
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %77 = OpFunctionCall %v4float %textureLoad_4acb64
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4float %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %58
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4float %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
index 1b63fd6..9eda8cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_4c15b2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
index 1b63fd6..9eda8cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_4c15b2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.msl
index f88a255..8f79243 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_4c15b2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.msl
index 1e01079..c2ad3d0 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4c15b2(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.spvasm
index ad52e50..8be48f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4c15b2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4c15b2 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_4c15b2
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_4c15b2
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_4c15b2
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_4c15b2
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.glsl
index e335c7a..5126160 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4c1a1e() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4c1a1e() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
index fe064c4..ddfe737 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4c1a1e() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
index fe064c4..ddfe737 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4c1a1e() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.msl
index 35dec90..576fbfd 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_4c1a1e(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.msl
index 65643f9..11a4a84 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_4c1a1e(texture3d<uint, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.spvasm
index d832811..82e2a0b 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4c1a1e.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,9 +42,12 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4c1a1e = OpFunction %v4uint None %10
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %22 = OpISub %v3uint %20 %23
+         %25 = OpBitcast %v3uint %19
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_4c1a1e
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_4c1a1e
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_4c1a1e
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_4c1a1e
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.glsl
index 80b3e02..51dc784 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_4c423f() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_4c423f() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4c423f() {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
index 5139889..47f483f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4c423f() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c423f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
index 5139889..47f483f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4c423f() {
   uint arg_1 = 1u;
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  int4 res = int4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c423f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.msl
index 6a390e4..6ae47cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_4c423f(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.msl
index f926758..e5cbcab 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_4c423f(texture1d<int, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.spvasm
index b817ac9..81de600 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4c423f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4c423f = OpFunction %v4int None %18
          %19 = OpLabel
@@ -86,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4int %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4int %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %29
+         %33 = OpExtInst %uint %34 UMin %32 %31
+         %35 = OpImageQuerySizeLod %uint %27 %33
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %34 UMin %28 %36
+         %38 = OpImageFetch %v4int %27 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_4c423f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_4c423f
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4int %textureLoad_4c423f
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_4c423f
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %57 = OpFunctionCall %v4int %textureLoad_4c423f
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_4c423f
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4int %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.glsl
index 1ca625e..f9a8623 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_4c67be() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_4c67be() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4c67be() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
index e4556ad..8e5816a 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4c67be() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c67be();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
index e4556ad..8e5816a 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4c67be() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4c67be();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.msl
index 871a134..cb81c28 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_4c67be(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.msl
index 99033de..41d369b 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_4c67be(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.spvasm
index 95b4cea..531973a 100644
--- a/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4c67be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4c67be = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_4c67be
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_4c67be
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_4c67be
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_4c67be
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_4c67be
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_4c67be
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.glsl
index 6ea72a9..c4de9cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4ccf9a() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage3D arg_0;
 uvec4 textureLoad_4ccf9a() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
index d350d7f..9097e4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4ccf9a() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
index d350d7f..9097e4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_4ccf9a() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.msl
index d02b0e0..fd3872d 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_4ccf9a(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.msl
index ac41b9f..5367bb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_4ccf9a(texture3d<uint, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.spvasm
index f2e29c7..0db691f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4ccf9a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4ccf9a = OpFunction %v4uint None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %20 = OpISub %v3uint %19 %15
+         %21 = OpExtInst %v3uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_4ccf9a
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_4ccf9a
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_4ccf9a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_4ccf9a
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.glsl
index d2cb11d..0689e03 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_4cdca5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_4cdca5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_4cdca5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
index 77c2888..a0d53c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4cdca5() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4cdca5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
index 77c2888..a0d53c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_4cdca5() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4cdca5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.msl
index 7691320..620e0f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_4cdca5(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.msl
index 98d78ba..1e5614b 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4cdca5(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.spvasm
index 41da416..d9204c7 100644
--- a/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4cdca5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4cdca5 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4int %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_4cdca5
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_4cdca5
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_4cdca5
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_4cdca5
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_4cdca5
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %73 = OpFunctionCall %v4int %textureLoad_4cdca5
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4int %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.glsl
index a657188..665ce87 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 float textureLoad_4db25c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 float textureLoad_4db25c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 float textureLoad_4db25c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_2, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
index 20b67ef..f8dce48 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(v_2, int(v)).x;
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4db25c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
index 20b67ef..f8dce48 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(v_2, int(v)).x;
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4db25c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.msl
index 182fa51..8f6d3a7 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float textureLoad_4db25c(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_2;
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.msl
index c317622..f35b9d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float textureLoad_4db25c(depth2d_ms<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.spvasm
index 009b00c..51543ee 100644
--- a/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4db25c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %47 = OpTypeFunction %VertexOutput
+         %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4db25c = OpFunction %float None %15
          %16 = OpLabel
@@ -83,44 +85,47 @@
          %25 = OpLoad %7 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Sample %27
-         %29 = OpCompositeExtract %float %28 0
-               OpStore %res %29
-         %32 = OpLoad %float %res None
-               OpReturnValue %32
+         %28 = OpImageQuerySize %v2uint %25
+         %29 = OpISub %v2uint %28 %21
+         %30 = OpExtInst %v2uint %31 UMin %26 %29
+         %32 = OpImageFetch %v4float %25 %30 Sample %27
+         %33 = OpCompositeExtract %float %32 0
+               OpStore %res %33
+         %36 = OpLoad %float %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_4db25c
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %float %textureLoad_4db25c
+         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %float %textureLoad_4db25c
-         %44 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %float %textureLoad_4db25c
+         %48 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %56 = OpFunctionCall %float %textureLoad_4db25c
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %51
+         %52 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %55
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %56 %58 None
+         %59 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %60 = OpFunctionCall %float %textureLoad_4db25c
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %39
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
index a98c74c..229f470 100644
--- a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_4e2c5c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
index a98c74c..229f470 100644
--- a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_4e2c5c() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.msl
index aa969df..760998f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_4e2c5c(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.msl
index e6a17b3..29f79d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4e2c5c(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.spvasm
index 3020738..a681926 100644
--- a/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4e2c5c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_4e2c5c = OpFunction %v4float None %10
@@ -59,24 +63,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_4e2c5c
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_4e2c5c
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_4e2c5c
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_4e2c5c
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.glsl
index 345f0d1..5a406df 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_4f5496() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_4f5496() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
index 7cd0221..9cba93a 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_4f5496() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
index 7cd0221..9cba93a 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_4f5496() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.msl
index 6358e8d..3624b5e 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_4f5496(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.msl
index e766e0f..6df2a00 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_4f5496(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.spvasm
index d843cbe..f35360f 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4f5496.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,10 +43,13 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_4f5496 = OpFunction %v4uint None %10
@@ -57,23 +62,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4uint %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %22
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %21
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4uint %20 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_4f5496
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_4f5496
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_4f5496
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_4f5496
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
index 164848f..3f18555 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4f90bb() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
index 164848f..3f18555 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_4f90bb() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.msl
index 75db10d..ef32ba2 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_4f90bb(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.msl
index 109861d..ec6bb12 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_4f90bb(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.spvasm
index 8a4f0f8..ec49779 100644
--- a/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4f90bb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_4f90bb = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,23 +57,27 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-         %21 = OpVectorShuffle %v4float %20 %20 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+         %30 = OpVectorShuffle %v4float %29 %29 2 1 0 3
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_4f90bb
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_4f90bb
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_4f90bb
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_4f90bb
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.glsl
index e1621f7..d1fa80d 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_4fa6ae() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_4fa6ae() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_4fa6ae() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u))))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
index 1709f00..4494282 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4fa6ae() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fa6ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
index 1709f00..4494282 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_4fa6ae() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fa6ae();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.msl
index e85ce57..1415cf6 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_4fa6ae(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.msl
index c814c25..60faf27 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_4fa6ae(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.spvasm
index a1a26c2..7b1516c 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4fa6ae.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4fa6ae = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,44 +80,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+         %30 = OpVectorShuffle %v4float %29 %29 2 1 0 3
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_4fa6ae
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_4fa6ae
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_4fa6ae
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_4fa6ae
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_4fa6ae
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_4fa6ae
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.glsl
index b4ef7aa..4f460f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_4fd803() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_4fd803() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_4fd803() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_1), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
index dab5e12..ecbb217 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_4fd803() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fd803();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
index dab5e12..ecbb217 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_4fd803() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_4fd803();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.msl
index 6d12e46..2eb1076 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_4fd803(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.msl
index 03c1c89..43bfb71 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_4fd803(texture3d<int, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.spvasm
index a410b62..52806ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/4fd803.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %40 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_4fd803 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,51 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v3int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4int %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4int %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %32 = OpISub %uint %30 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySizeLod %v3uint %27 %35
+         %39 = OpISub %v3uint %37 %40
+         %41 = OpBitcast %v3uint %28
+         %42 = OpExtInst %v3uint %36 UMin %41 %39
+         %43 = OpImageFetch %v4int %27 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4int %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_4fd803
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_4fd803
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
+%fragment_main = OpFunction %void None %49
          %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_4fd803
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+         %51 = OpFunctionCall %v4int %textureLoad_4fd803
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %49
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4int %textureLoad_4fd803
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %58 %57 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %61
          %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %70 = OpFunctionCall %v4int %textureLoad_4fd803
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4int %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.glsl
index 6a85351..75177b2 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_505aa2() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_505aa2() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_505aa2() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
index 6a1baf3..5a98acc 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_505aa2() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_505aa2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
index 6a1baf3..5a98acc 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_505aa2() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_505aa2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.msl
index ad4cac1..8a3e53b 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_505aa2(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.msl
index 38796cc..0cf5b20 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_505aa2(texture3d<int, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.spvasm
index bb4b58e..aff05a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/505aa2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_505aa2 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %30 = OpISub %v3uint %27 %31
+         %33 = OpBitcast %v3uint %26
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_505aa2
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_505aa2
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_505aa2
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_505aa2
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_505aa2
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_505aa2
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.glsl
index 41cad35..eabb534 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_50915c() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_50915c() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_50915c() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
index c02b976..e2a64ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_50915c() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_50915c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
index c02b976..e2a64ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_50915c() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_50915c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.msl
index 1527551..05195fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_50915c(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.msl
index 9556682..8d6f33d 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_50915c(texture3d<uint, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.spvasm
index af3a2f7..3ab06fb 100644
--- a/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/50915c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_50915c = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %28 = OpISub %v3uint %27 %23
+         %29 = OpExtInst %v3uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_50915c
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_50915c
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_50915c
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_50915c
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_50915c
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_50915c
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
index 112e615..6de11db 100644
--- a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5154e1() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
index 112e615..6de11db 100644
--- a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5154e1() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.msl
index fb533e0..d77aab0 100644
--- a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_5154e1(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.msl
index dbab521..2111aa8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5154e1(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.spvasm
index 2846594..13d0e96 100644
--- a/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5154e1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5154e1 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_5154e1
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_5154e1
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_5154e1
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_5154e1
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.glsl
index db83fc9..96f8d6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_519ab5() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_519ab5() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_519ab5() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
index d6c46f3..4739d28 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_519ab5() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_519ab5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
index d6c46f3..4739d28 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_519ab5() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_519ab5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.msl
index 6694b56..5733be1 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_519ab5(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.msl
index ea5c936..6f6ca55 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_519ab5(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.spvasm
index 905f1c2..17e8f89 100644
--- a/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/519ab5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_519ab5 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_519ab5
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_519ab5
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_519ab5
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_519ab5
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_519ab5
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.glsl
index 8819632..0fc8c12 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_53378a() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_53378a() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_53378a() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
index 1e145f6..691bf04 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_53378a() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53378a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
index 1e145f6..691bf04 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_53378a() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53378a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.msl
index 0df93fb..c19ee1f 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_53378a(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.msl
index b510dad..e25f673 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_53378a(texture2d<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.spvasm
index 35e30df..d997138 100644
--- a/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/53378a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_53378a = OpFunction %v4int None %18
          %19 = OpLabel
@@ -84,43 +88,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %30 = OpISub %v2uint %27 %31
+         %33 = OpBitcast %v2uint %26
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_53378a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_53378a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_53378a
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_53378a
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_53378a
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_53378a
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
index 98f6085..f94f94c 100644
--- a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_53941c() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
index 98f6085..f94f94c 100644
--- a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_53941c() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.msl
index 61946e0..1716fce 100644
--- a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_53941c(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.msl
index 7b9f7ec..5153b32 100644
--- a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_53941c(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.spvasm
index b86031f..c6e837d 100644
--- a/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/53941c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_53941c = OpFunction %v4int None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4int %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4int %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_53941c
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_53941c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_53941c
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_53941c
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.glsl
index a22c44c..3702367 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_53e142() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_53e142() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_53e142() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  ivec2 v_8 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
index fdd4903..47538a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53e142();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
index fdd4903..47538a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_53e142();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.msl
index cbb29d9..c8fed49 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.ir.msl
@@ -20,7 +20,11 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  int const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u))), v_2, v_3);
   return res;
 }
 
@@ -43,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.msl
index fe5a2c8..5d5c56d 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_53e142(texture2d_array<uint, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.spvasm
index e1aaa9d..be5bd51 100644
--- a/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/53e142.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,17 +69,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %55 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_53e142 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -92,45 +94,57 @@
          %31 = OpLoad %v2uint %arg_1 None
          %32 = OpLoad %int %arg_2 None
          %33 = OpLoad %int %arg_3 None
-         %34 = OpBitcast %uint %32
-         %36 = OpCompositeConstruct %v3uint %31 %34
-         %37 = OpImageFetch %v4uint %30 %36 Lod %33
-               OpStore %res %37
-         %40 = OpLoad %v4uint %res None
-               OpReturnValue %40
+         %34 = OpImageQuerySizeLod %v3uint %30 %uint_0
+         %37 = OpCompositeExtract %uint %34 2
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpBitcast %uint %32
+         %40 = OpExtInst %uint %41 UMin %39 %38
+         %42 = OpImageQueryLevels %uint %30
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %33
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %30 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %23
+         %49 = OpExtInst %v2uint %41 UMin %31 %48
+         %50 = OpCompositeConstruct %v3uint %49 %40
+         %51 = OpImageFetch %v4uint %30 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4uint %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_53e142
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4uint %textureLoad_53e142
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4uint %textureLoad_53e142
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %52 %51 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
          %64 = OpFunctionCall %v4uint %textureLoad_53e142
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %65 %64 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4uint %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %77 = OpFunctionCall %v4uint %textureLoad_53e142
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4uint %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.glsl
index 62d909b..5e56d51 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_54a59b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  vec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_54a59b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  vec4 res = texelFetch(arg_0, v_10, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_54a59b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  ivec2 v_8 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
index ca3cea7..c053fa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54a59b();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
index ca3cea7..c053fa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(v_5))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54a59b();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.msl
index 7ffb800..f876a82 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.ir.msl
@@ -20,7 +20,11 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  int const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u))), v_2, v_3);
   return res;
 }
 
@@ -43,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.msl
index eae98bb..d7d150a 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_54a59b(texture2d_array<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.spvasm
index d46db0f..36f6e35 100644
--- a/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/54a59b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,16 +67,16 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %55 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %53 = OpTypeFunction %VertexOutput
+         %66 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
-         %59 = OpConstantNull %v4float
+         %70 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_54a59b = OpFunction %v4float None %15
          %16 = OpLabel
@@ -89,45 +91,57 @@
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %int %arg_2 None
          %31 = OpLoad %int %arg_3 None
-         %32 = OpBitcast %uint %30
-         %34 = OpCompositeConstruct %v3uint %29 %32
-         %35 = OpImageFetch %v4float %28 %34 Lod %31
-               OpStore %res %35
-         %38 = OpLoad %v4float %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %35 = OpCompositeExtract %uint %32 2
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpBitcast %uint %30
+         %38 = OpExtInst %uint %39 UMin %37 %36
+         %40 = OpImageQueryLevels %uint %28
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %31
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %28 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %39 UMin %29 %46
+         %48 = OpCompositeConstruct %v3uint %47 %38
+         %49 = OpImageFetch %v4float %28 %48 Lod %43
+               OpStore %res %49
+         %52 = OpLoad %v4float %res None
+               OpReturnValue %52
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_54a59b
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %55
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4float %textureLoad_54a59b
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4float %textureLoad_54a59b
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %55
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4float %textureLoad_54a59b
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %59 None
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %61 = OpFunctionCall %v4float %textureLoad_54a59b
-               OpStore %60 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+%vertex_main_inner = OpFunction %VertexOutput None %66
+         %67 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %70
+         %71 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %71 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %74 = OpFunctionCall %v4float %textureLoad_54a59b
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4float %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main = OpFunction %void None %55
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4float %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.glsl
index 1d54572..cbed592 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_54e0ce() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_54e0ce() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_54e0ce() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1)).zyxw;
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u))))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
index ec15eb8..0ec72a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54e0ce() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54e0ce();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
index ec15eb8..0ec72a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_54e0ce() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_54e0ce();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.msl
index fe0c01c..384e35e 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_54e0ce(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.msl
index ddedb6c..57a917d 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_54e0ce(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.spvasm
index 343fffc..e31850b 100644
--- a/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/54e0ce.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_54e0ce = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,44 +80,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+         %30 = OpVectorShuffle %v4float %29 %29 2 1 0 3
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_54e0ce
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_54e0ce
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_54e0ce
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_54e0ce
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_54e0ce
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_54e0ce
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.glsl
index d9d418d..9f02ba1 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_54fb38() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_54fb38() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
index dd5fb3c..36f07ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_54fb38() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
index dd5fb3c..36f07ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_54fb38() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.msl
index 13d360f..610543b 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_54fb38(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.msl
index dd5b906..6fec180 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_54fb38(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.spvasm
index 7941460..ddf97a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/54fb38.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_54fb38 = OpFunction %v4uint None %10
@@ -57,23 +59,31 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2uint %arg_1 None
          %21 = OpLoad %uint %arg_2 None
-         %23 = OpCompositeConstruct %v3uint %20 %21
-         %24 = OpImageRead %v4uint %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %24 = OpCompositeExtract %uint %22 2
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %21 %25
+         %28 = OpImageQuerySize %v3uint %19
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %30 = OpISub %v2uint %29 %15
+         %31 = OpExtInst %v2uint %27 UMin %20 %30
+         %32 = OpCompositeConstruct %v3uint %31 %26
+         %33 = OpImageRead %v4uint %19 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_54fb38
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_54fb38
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_54fb38
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_54fb38
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.glsl
index 9d3d8c5..a244d57 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_55e745() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_55e745() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_55e745() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
index 5f502df..51da2a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_55e745() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_55e745();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
index 5f502df..51da2a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_55e745() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_55e745();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.msl
index 8ee155c..d562cdc 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_55e745(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.msl
index a0628a9..b0b752a 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_55e745(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.spvasm
index 7cb9a98..98d9c67 100644
--- a/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/55e745.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_55e745 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %24
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4int %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_55e745
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_55e745
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_55e745
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_55e745
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_55e745
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_55e745
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.glsl
index a3853ca..ccbe949 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_560573() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_560573() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 ivec4 textureLoad_560573() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
index 12063ce..108081d 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_560573() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_560573();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
index 12063ce..108081d 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_560573() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_560573();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.msl
index f19a3fe..f2ea0a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_560573(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.msl
index 02e4a2f..02dfa9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_560573(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.spvasm
index 8bcf87e..f5eb2af 100644
--- a/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/560573.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,20 +66,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_560573 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %31 = OpCompositeConstruct %v3int %28 %29
-         %32 = OpImageRead %v4int %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %29
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %27
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %28
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4int %27 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4int %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_560573
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_560573
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_560573
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4int %textureLoad_560573
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4int %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_560573
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.glsl
index 0b8b061..28f7592 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_56a000() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_56a000() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
index 31d21e5..262cce5 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_56a000() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
index 31d21e5..262cce5 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_56a000() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.msl
index c163988..7660ae0 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_56a000(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.msl
index 13cf132..72e4f22 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_56a000(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.spvasm
index ffff866..57fab9d 100644
--- a/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/56a000.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_56a000 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +55,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_56a000
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_56a000
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_56a000
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.glsl
index 93d6b10..5eac745 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_582015() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_582015() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 ivec4 textureLoad_582015() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
index 9985cdf..07873cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_582015() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_582015();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
index 9985cdf..07873cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_582015() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_582015();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.msl
index 8ce43d1..bc39ed8 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_582015(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.msl
index cb48091..5c13bed 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_582015(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.spvasm
index ec46ab8..0382236 100644
--- a/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/582015.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,20 +66,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_582015 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %31 = OpCompositeConstruct %v3int %28 %29
-         %32 = OpImageRead %v4int %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %29
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %27
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %28
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4int %27 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4int %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_582015
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_582015
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_582015
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4int %textureLoad_582015
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4int %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_582015
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.glsl
index 9bf5604..3beefb7 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_589eaa() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_589eaa() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_589eaa() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
index 4fca667..77aaa3a 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_589eaa() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_589eaa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
index 4fca667..77aaa3a 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_589eaa() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_589eaa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.msl
index 2c98cd6..e07cf95 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_589eaa(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.msl
index f15aa95..e8a3b2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_589eaa(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.spvasm
index 6c6deaf..e0cc88a 100644
--- a/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/589eaa.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_589eaa = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_589eaa
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_589eaa
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_589eaa
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_589eaa
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_589eaa
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_589eaa
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.glsl
index 37abfd4..0d1f009 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_5a2f9d() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_5a2f9d() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_5a2f9d() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_1), v_4), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
index ab8d797..4d601a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_5a2f9d() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  int4 res = int4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5a2f9d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
index ab8d797..4d601a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_5a2f9d() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  int4 res = int4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5a2f9d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.msl
index 23bbd0a..04f36b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 int4 textureLoad_5a2f9d(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.msl
index b5909bf..67b5f5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5a2f9d(texture1d<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.spvasm
index 4efd92f..ee37a3e 100644
--- a/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5a2f9d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5a2f9d = OpFunction %v4int None %18
          %19 = OpLabel
@@ -85,43 +87,51 @@
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
          %26 = OpLoad %int %arg_2 None
-         %27 = OpImageFetch %v4int %24 %25 Lod %26
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQueryLevels %uint %24
+         %29 = OpISub %uint %27 %uint_1
+         %31 = OpBitcast %uint %26
+         %32 = OpExtInst %uint %33 UMin %31 %29
+         %34 = OpImageQuerySizeLod %uint %24 %32
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %25
+         %37 = OpExtInst %uint %33 UMin %36 %35
+         %38 = OpImageFetch %v4int %24 %37 Lod %32
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_5a2f9d
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_5a2f9d
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_5a2f9d
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_5a2f9d
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_5a2f9d
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_5a2f9d
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.glsl
index 652520a..01c0eee 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5abbf2() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5abbf2() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5abbf2() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
index 1b0af41..73f5153 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5abbf2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5abbf2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
index 1b0af41..73f5153 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5abbf2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5abbf2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.msl
index b3d0a1f..3b942eb 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_5abbf2(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.msl
index 7606370..404fd15 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_5abbf2(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.spvasm
index 456d472..24eb932 100644
--- a/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5abbf2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5abbf2 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_5abbf2
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_5abbf2
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_5abbf2
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_5abbf2
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_5abbf2
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_5abbf2
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
index 8eaf5fc..529363d 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5b0f5b() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
index 8eaf5fc..529363d 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_5b0f5b() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.msl
index 99451b1..482665f 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_5b0f5b(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.msl
index cf603ad..803b322 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5b0f5b(texture3d<uint, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.spvasm
index 29818e4..26feb71d 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5b0f5b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_5b0f5b = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %22 = OpISub %v3uint %20 %23
+         %25 = OpBitcast %v3uint %19
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_5b0f5b
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_5b0f5b
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_5b0f5b
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_5b0f5b
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
index d30de4b..38836a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5b4947() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
index d30de4b..38836a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5b4947() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.msl
index f9ee8de..9d4d877 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_5b4947(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.msl
index f2d658c..ab0fc34 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5b4947(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.spvasm
index f20de45..9e17321 100644
--- a/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5b4947.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5b4947 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,23 +57,27 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-         %21 = OpVectorShuffle %v4float %20 %20 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+         %30 = OpVectorShuffle %v4float %29 %29 2 1 0 3
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_5b4947
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_5b4947
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_5b4947
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_5b4947
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.glsl
index 4ca84ec..75e32c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_5bb7fb() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_5bb7fb() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5bb7fb() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
index ecca816..8912eb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5bb7fb() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5bb7fb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
index ecca816..8912eb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5bb7fb() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5bb7fb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.msl
index 705cac4..7c2fcae 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_5bb7fb(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.msl
index b8b0f51..f274cc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5bb7fb(texture1d<uint, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.spvasm
index 04f2b7a..a3279fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5bb7fb.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5bb7fb = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +85,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageRead %v4uint %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4uint %24 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_5bb7fb
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4uint %textureLoad_5bb7fb
          %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_5bb7fb
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4uint %textureLoad_5bb7fb
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_5bb7fb
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
index 3e31956..d463ea6 100644
--- a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5c69f8() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
index 3e31956..d463ea6 100644
--- a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_5c69f8() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.msl
index 771f50e..25a98ee 100644
--- a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_5c69f8(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.msl
index 7a16683..6ba31a5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_5c69f8(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.spvasm
index c7796c5..7182135 100644
--- a/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5c69f8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_5c69f8 = OpFunction %v4float None %10
@@ -51,23 +53,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-         %21 = OpVectorShuffle %v4float %20 %20 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+         %25 = OpVectorShuffle %v4float %24 %24 2 1 0 3
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_5c69f8
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_5c69f8
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_5c69f8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_5c69f8
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.glsl
index ff09785..5348fb8 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_5cd3fc() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_5cd3fc() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
index 887fd3b..aac4862 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5cd3fc() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
index 887fd3b..aac4862 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5cd3fc() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.msl
index 7f23026c..226aa7b 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_5cd3fc(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.msl
index 509e1e6..35bb7ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5cd3fc(texture2d<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.spvasm
index 7ac58fd..ceb5c1b 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5cd3fc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5cd3fc = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %22 = OpISub %v2uint %19 %23
+         %25 = OpBitcast %v2uint %18
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_5cd3fc
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_5cd3fc
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_5cd3fc
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_5cd3fc
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.glsl
index 1e4c90d..61a2c87 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5cee3b() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5cee3b() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5cee3b() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
index 058c217..fe14e8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5cee3b() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5cee3b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
index 058c217..fe14e8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5cee3b() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5cee3b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.msl
index ce8ba3d..c23336c 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_5cee3b(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.msl
index cc905fd..d9fc75b 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_5cee3b(texture3d<uint, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.spvasm
index 8468eeb..7394a044 100644
--- a/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5cee3b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5cee3b = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %28 = OpISub %v3uint %27 %23
+         %29 = OpExtInst %v3uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_5cee3b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_5cee3b
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_5cee3b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_5cee3b
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_5cee3b
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_5cee3b
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.glsl
index 8e5d1a4..3374bbe 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_5d0a2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_5d0a2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 uvec4 textureLoad_5d0a2f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
index 45ac3db..70c8559 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_5d0a2f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d0a2f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
index 45ac3db..70c8559 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_5d0a2f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d0a2f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.msl
index 56bf45e..82de3bc 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_5d0a2f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.msl
index f3c0141..37218a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_5d0a2f(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.spvasm
index f3ada36..bc453ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5d0a2f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,19 +67,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5d0a2f = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %32 = OpCompositeConstruct %v3int %29 %30
-         %33 = OpImageRead %v4uint %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4uint %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %30
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %28
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %29
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4uint %28 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_5d0a2f
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4uint %textureLoad_5d0a2f
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %74 = OpFunctionCall %v4uint %textureLoad_5d0a2f
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4uint %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.glsl
index 7a0a4b2..d23a262 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_5d4042() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_5d4042() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_5d4042() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
index 82d68ae..e64d299 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_5d4042() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d4042();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
index 82d68ae..e64d299 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_5d4042() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5d4042();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.msl
index a0afc05..143927f 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_5d4042(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.msl
index 52671a3..a398724 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5d4042(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.spvasm
index 50dfd86..3231746 100644
--- a/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5d4042.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5d4042 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +88,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_5d4042
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_5d4042
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_5d4042
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_5d4042
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_5d4042
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_5d4042
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.glsl
index 5d7ce86..a7c2006 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5dd4c7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5dd4c7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5dd4c7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
index 239dc53..08204ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5dd4c7() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5dd4c7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
index 239dc53..08204ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5dd4c7() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5dd4c7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.msl
index 398fe04..cf199f0 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_5dd4c7(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.msl
index 874fffb..ac5320c 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_5dd4c7(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.spvasm
index 11ab1bd..2f5ddfc 100644
--- a/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5dd4c7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5dd4c7 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -81,43 +85,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_5dd4c7
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_5dd4c7
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_5dd4c7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_5dd4c7
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_5dd4c7
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_5dd4c7
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
index 8a0d812..67c7372 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5e17a7() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
index 8a0d812..67c7372 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_5e17a7() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.msl
index e10f3a5..5a21eb20 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_5e17a7(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.msl
index ff0921c..5764483 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_5e17a7(texture1d<int, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.spvasm
index 3cfc9d1..c9d8543 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5e17a7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,11 +39,12 @@
          %10 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_5e17a7 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %int %arg_1 None
-         %17 = OpImageRead %v4int %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %19 = OpISub %uint %17 %uint_1
+         %21 = OpBitcast %uint %16
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4int %15 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_5e17a7
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %23
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4int %textureLoad_5e17a7
          %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_5e17a7
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
index c235a3a..6514157 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_5e1843() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
index c235a3a..6514157 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_5e1843() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.msl
index d202e91..583193d 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_5e1843(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.msl
index ebbe49c..928f484 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_5e1843(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.spvasm
index b747279..dded934 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5e1843.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,7 +45,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_5e1843 = OpFunction %v4uint None %10
@@ -56,23 +58,31 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2uint %arg_1 None
          %21 = OpLoad %uint %arg_2 None
-         %23 = OpCompositeConstruct %v3uint %20 %21
-         %24 = OpImageRead %v4uint %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %24 = OpCompositeExtract %uint %22 2
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %21 %25
+         %28 = OpImageQuerySize %v3uint %19
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %30 = OpISub %v2uint %29 %15
+         %31 = OpExtInst %v2uint %27 UMin %20 %30
+         %32 = OpCompositeConstruct %v3uint %31 %26
+         %33 = OpImageRead %v4uint %19 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_5e1843
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_5e1843
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_5e1843
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_5e1843
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.glsl
index 6209271..be7e7fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_5e8d3f() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_5e8d3f() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_5e8d3f() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
index a6fa03d..8ac77f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5e8d3f() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5e8d3f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
index a6fa03d..8ac77f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_5e8d3f() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5e8d3f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.msl
index 48edaf1..5001f97 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_5e8d3f(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.msl
index 010bbac..0011401 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_5e8d3f(texture3d<int, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.spvasm
index d406cad..afd633a 100644
--- a/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5e8d3f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5e8d3f = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %29 = OpISub %v3uint %28 %24
+         %30 = OpExtInst %v3uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_5e8d3f
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_5e8d3f
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_5e8d3f
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_5e8d3f
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_5e8d3f
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_5e8d3f
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.glsl
index 6a82937..b09e96dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_5ed6ad() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_5ed6ad() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_5ed6ad() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
index 6ad6eb3..31a0db5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_5ed6ad() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5ed6ad();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
index 6ad6eb3..31a0db5 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_5ed6ad() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5ed6ad();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.msl
index d6f911d..3b19870 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_5ed6ad(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.msl
index 8eb760d..98975da 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_5ed6ad(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.spvasm
index 58947df..8acb5b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5ed6ad.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,14 +68,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5ed6ad = OpFunction %v4float None %15
          %16 = OpLabel
@@ -85,44 +87,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_5ed6ad
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_5ed6ad
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_5ed6ad
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_5ed6ad
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_5ed6ad
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_5ed6ad
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.glsl
index 9909ee6..340fff9 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5f4473() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_5f4473() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_5f4473() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
index 169ad2e..3be3b7e 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5f4473() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5f4473();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
index 169ad2e..3be3b7e 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_5f4473() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5f4473();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.msl
index 3a592d3..028ff52 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_5f4473(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.msl
index aed5711..d99c5c0 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_5f4473(texture3d<uint, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.spvasm
index 227f48e..76bcdfb 100644
--- a/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5f4473.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5f4473 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %28 = OpISub %v3uint %27 %23
+         %29 = OpExtInst %v3uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_5f4473
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_5f4473
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_5f4473
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_5f4473
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_5f4473
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_5f4473
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.glsl
index bb87fbc..1b09568 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5feb4d() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_5feb4d() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_5feb4d() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
index 293a0d2..4228b39 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5feb4d() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5feb4d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
index 293a0d2..4228b39 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_5feb4d() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_5feb4d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.msl
index 70dfb66..c0778d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_5feb4d(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.msl
index f628968..e62322c 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_5feb4d(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.spvasm
index bb532b7..1b96584 100644
--- a/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/5feb4d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_5feb4d = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_5feb4d
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_5feb4d
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_5feb4d
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_5feb4d
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_5feb4d
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_5feb4d
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.glsl
index ae7a37d..5d3b3fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6154d4() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6154d4() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6154d4() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
index eff19b1..8595788 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6154d4() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6154d4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
index eff19b1..8595788 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6154d4() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6154d4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.msl
index 3deb203..eb50fed 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_6154d4(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.msl
index 0ce7c72..4432d3a 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6154d4(texture2d<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.spvasm
index 73527a8..3aa09de 100644
--- a/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6154d4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %49 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6154d4 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,51 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %31 = OpImageFetch %v4uint %28 %29 Lod %30
-               OpStore %res %31
-         %34 = OpLoad %v4uint %res None
-               OpReturnValue %34
+         %31 = OpImageQueryLevels %uint %28
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %30
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySizeLod %v2uint %28 %35
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %29
+         %42 = OpExtInst %v2uint %36 UMin %41 %39
+         %43 = OpImageFetch %v4uint %28 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4uint %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_6154d4
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_6154d4
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
+%fragment_main = OpFunction %void None %49
          %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_6154d4
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+         %51 = OpFunctionCall %v4uint %textureLoad_6154d4
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %49
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4uint %textureLoad_6154d4
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %58 %57 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %61
          %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %70 = OpFunctionCall %v4uint %textureLoad_6154d4
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4uint %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.glsl
index b5d0035..c3aa8eb 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_61e2e8() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_61e2e8() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
index d14e41f..7484979 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_61e2e8() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
index d14e41f..7484979 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_61e2e8() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.msl
index b041a13..2736aea 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_61e2e8(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.msl
index ecbb6e2..9f22d87 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_61e2e8(texture3d<int, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.spvasm
index 8c8eddcc..53fbc8d 100644
--- a/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/61e2e8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_61e2e8 = OpFunction %v4int None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_61e2e8
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_61e2e8
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_61e2e8
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_61e2e8
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.glsl
index 2433028..8700835 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_620caa() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_620caa() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_620caa() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
index 9647d1c..1293673 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_620caa() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_620caa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
index 9647d1c..1293673 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_620caa() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_620caa();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.msl
index 135cdf2..cae35eb 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_620caa(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.msl
index 9c5ebb6..51a00a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_620caa(texture2d<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.spvasm
index d156cf0..e2648a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/620caa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_620caa = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +85,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %29 = OpISub %v2uint %28 %24
+         %30 = OpExtInst %v2uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_620caa
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_620caa
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_620caa
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_620caa
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_620caa
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_620caa
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
index 5abc6a4..32ff271 100644
--- a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_622278() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
index 5abc6a4..32ff271 100644
--- a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_622278() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.msl
index ea527d4..f2e0005 100644
--- a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_622278(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.msl
index 58ea1f2..6151898 100644
--- a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_622278(texture3d<uint, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.spvasm
index 206785d..145dc13 100644
--- a/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/622278.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_622278 = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %22 = OpISub %v3uint %20 %23
+         %25 = OpBitcast %v3uint %19
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_622278
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_622278
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_622278
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_622278
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.glsl
index 265e2cf..c8c524a 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 float textureLoad_6273b1() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 float textureLoad_6273b1() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 float textureLoad_6273b1() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  float res = texelFetch(arg_0, v_3, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
index bfd15c2..5105ddb 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float res = arg_0.Load(v_3, int(v)).x;
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6273b1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
index bfd15c2..5105ddb 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float res = arg_0.Load(v_3, int(v)).x;
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6273b1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.msl
index c53431a..8bca4f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float textureLoad_6273b1(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  int const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.msl
index ec05444..7989adf 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_6273b1(depth2d_ms<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.spvasm
index a40ef1f..637d801 100644
--- a/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6273b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6273b1 = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +89,48 @@
          %25 = OpLoad %7 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Sample %27
-         %29 = OpCompositeExtract %float %28 0
-               OpStore %res %29
-         %32 = OpLoad %float %res None
-               OpReturnValue %32
+         %28 = OpImageQuerySize %v2uint %25
+         %31 = OpISub %v2uint %28 %32
+         %34 = OpBitcast %v2uint %26
+         %35 = OpExtInst %v2uint %36 UMin %34 %31
+         %37 = OpImageFetch %v4float %25 %35 Sample %27
+         %38 = OpCompositeExtract %float %37 0
+               OpStore %res %38
+         %41 = OpLoad %float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_6273b1
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %float %textureLoad_6273b1
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_6273b1
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %float %textureLoad_6273b1
+         %53 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_6273b1
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %65 = OpFunctionCall %float %textureLoad_6273b1
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.glsl
index 5165f67..5c02245 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_62d125() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image3D arg_0;
 vec4 textureLoad_62d125() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_62d125() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
index cf7dd70..0e13ed1 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_62d125() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d125();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
index cf7dd70..0e13ed1 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_62d125() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d125();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.msl
index ae361c4..093aa95 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_62d125(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.msl
index 0a04364..b13aa5f 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_62d125(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.spvasm
index 660af66..b7e5cf6 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/62d125.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_62d125 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_62d125
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_62d125
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_62d125
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_62d125
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_62d125
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_62d125
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.glsl
index 0ac83f7..7894fbb 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_62d1de() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_62d1de() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_62d1de() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(v_1), v_3), 0u));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
index 7eebbdf..f470b9d 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_62d1de() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  int4 res = int4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d1de();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
index 7eebbdf..f470b9d 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_62d1de() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  int4 res = int4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  int4 res = int4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_62d1de();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.msl
index 10f4c9b..fa84d6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 int4 textureLoad_62d1de(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.msl
index a29ca91..24815b6 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_62d1de(texture1d<int, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.spvasm
index a9b0e8e..50c5897 100644
--- a/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/62d1de.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_62d1de = OpFunction %v4int None %18
          %19 = OpLabel
@@ -86,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4int %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4int %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %uint %27 %32
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %28
+         %37 = OpExtInst %uint %33 UMin %36 %35
+         %38 = OpImageFetch %v4int %27 %37 Lod %32
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_62d1de
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_62d1de
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4int %textureLoad_62d1de
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_62d1de
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %57 = OpFunctionCall %v4int %textureLoad_62d1de
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_62d1de
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4int %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.glsl
index 503a64e..b36ba6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 ivec4 textureLoad_639962() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 ivec4 textureLoad_639962() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 ivec4 textureLoad_639962() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
index 88277fd..6d4b625 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_639962();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
index 88277fd..6d4b625 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_639962();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.msl
index ff955b5..da102b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_639962(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_2;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.msl
index df06d79..e2e37f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_639962(texture2d_ms<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.spvasm
index 079b6b3..b7d92c0 100644
--- a/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/639962.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_639962 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -86,43 +88,46 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %31 = OpImageFetch %v4int %28 %29 Sample %30
-               OpStore %res %31
-         %34 = OpLoad %v4int %res None
-               OpReturnValue %34
+         %31 = OpImageQuerySize %v2uint %28
+         %32 = OpISub %v2uint %31 %24
+         %33 = OpExtInst %v2uint %34 UMin %29 %32
+         %35 = OpImageFetch %v4int %28 %33 Sample %30
+               OpStore %res %35
+         %38 = OpLoad %v4int %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_639962
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4int %textureLoad_639962
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_639962
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4int %textureLoad_639962
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %58 = OpFunctionCall %v4int %textureLoad_639962
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %62 = OpFunctionCall %v4int %textureLoad_639962
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4int %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4int %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.glsl
index 21550aa..a22ddc8 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_63be18() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_63be18() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_63be18() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
index f88a0f6..3aa5a7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_63be18() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_63be18();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
index f88a0f6..3aa5a7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_63be18() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_63be18();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.msl
index 093f4d1..bb5e360 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_63be18(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.msl
index 9919104..1617ce0 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_63be18(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.spvasm
index 084eb57..e61e1c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/63be18.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_63be18 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,44 +91,52 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %32 = OpCompositeConstruct %v3uint %29 %30
-         %33 = OpImageRead %v4int %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4int %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %30 %34
+         %37 = OpImageQuerySize %v3uint %28
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %24
+         %40 = OpExtInst %v2uint %36 UMin %29 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4int %28 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_63be18
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_63be18
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_63be18
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_63be18
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %60 = OpFunctionCall %v4int %textureLoad_63be18
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_63be18
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4int %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
index a651ca4..0ab8501 100644
--- a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_64c372() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
index a651ca4..0ab8501 100644
--- a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_64c372() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.msl
index 4a05d57..336ab77 100644
--- a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_64c372(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.msl
index 343477b..6bd4491 100644
--- a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_64c372(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.spvasm
index f66a25e..ef6091e 100644
--- a/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/64c372.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,10 +43,13 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_64c372 = OpFunction %v4uint None %10
@@ -57,23 +62,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4uint %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %22
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %21
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4uint %20 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_64c372
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_64c372
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_64c372
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_64c372
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.glsl
index 0c881fa..36bc719 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_656d76() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_656d76() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_656d76() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
index 5ae20bc..56239c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_656d76();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
index 5ae20bc..56239c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_656d76();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.msl
index 40a54ef..af20d10 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int const v = arg_2;
+  int2 const v = arg_1;
   uint const v_1 = arg_3;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.msl
index 9c49e7f..7a78fc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_656d76(texture2d_array<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.spvasm
index 0ff9c5d..31642f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/656d76.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
 %_ptr_Function_int = OpTypePointer Function %int
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %55 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_656d76 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -93,44 +97,57 @@
          %32 = OpLoad %v2int %arg_1 None
          %33 = OpLoad %int %arg_2 None
          %34 = OpLoad %uint %arg_3 None
-         %36 = OpCompositeConstruct %v3int %32 %33
-         %37 = OpImageFetch %v4uint %31 %36 Lod %34
-               OpStore %res %37
-         %40 = OpLoad %v4uint %res None
-               OpReturnValue %40
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpBitcast %uint %33
+         %41 = OpExtInst %uint %42 UMin %40 %39
+         %43 = OpImageQueryLevels %uint %31
+         %44 = OpISub %uint %43 %uint_1
+         %45 = OpExtInst %uint %42 UMin %34 %44
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %32
+         %52 = OpExtInst %v2uint %42 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %41
+         %54 = OpImageFetch %v4uint %31 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4uint %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_656d76
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4uint %textureLoad_656d76
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4uint %textureLoad_656d76
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %60
+         %66 = OpLabel
+         %67 = OpFunctionCall %v4uint %textureLoad_656d76
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %68 %67 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %64 = OpFunctionCall %v4uint %textureLoad_656d76
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %80 = OpFunctionCall %v4uint %textureLoad_656d76
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4uint %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4uint %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.glsl
index c7af811..9accf09 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_65a4d0() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_65a4d0() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_65a4d0() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
index aa2f282..7e07933 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_65a4d0() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_65a4d0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
index aa2f282..7e07933 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_65a4d0() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_65a4d0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.msl
index ea10560..f3ccfc6 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_65a4d0(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.msl
index 316396b..d4a0594 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_65a4d0(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.spvasm
index d794314..4decce0 100644
--- a/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/65a4d0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_65a4d0 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +88,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_65a4d0
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_65a4d0
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_65a4d0
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_65a4d0
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_65a4d0
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_65a4d0
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
index 6afc617..472d104 100644
--- a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_666010() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
index 6afc617..472d104 100644
--- a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_666010() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.msl
index 890e898..6253156 100644
--- a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_666010(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.msl
index d58c86a..99f0539 100644
--- a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_666010(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.spvasm
index 3a3dc75..771d1c1 100644
--- a/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/666010.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_666010 = OpFunction %v4float None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_666010
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_666010
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_666010
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_666010
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.glsl
index 53b2658..e685a3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_6678b6() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_6678b6() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_6678b6() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
index 6f2b8d9..2ac59cb 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_6678b6() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6678b6();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
index 6f2b8d9..2ac59cb 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_6678b6() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6678b6();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.msl
index 28ce4be..c5ed98f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_6678b6(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.msl
index c3796ba..e52f22b 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_6678b6(texture1d<int, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.spvasm
index 9dfec99..b20431f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6678b6.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6678b6 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageRead %v4int %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4int %23 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_6678b6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4int %textureLoad_6678b6
          %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_6678b6
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4int %textureLoad_6678b6
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_6678b6
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.glsl
index 643b5c8..3f04552 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_66be47() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_6)).x;
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_66be47() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_6)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_66be47() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_1), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  float res = texelFetch(arg_0, v_8, int(v_5)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
index aaedfda..12e83e8 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_66be47();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
index aaedfda..12e83e8 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_66be47();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.msl
index 06de223..ecab331 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint const v = arg_2;
-  uint const v_1 = arg_3;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.msl
index 121975e..a1f9808 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_66be47(depth2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.spvasm
index 853d56e..768d506 100644
--- a/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/66be47.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %46 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %54 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %61 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_66be47 = OpFunction %float None %15
          %16 = OpLabel
@@ -90,46 +94,57 @@
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %uint %arg_2 None
          %31 = OpLoad %uint %arg_3 None
-         %32 = OpBitcast %int %30
-         %34 = OpCompositeConstruct %v3int %29 %32
-         %35 = OpImageFetch %v4float %28 %34 Lod %31
-         %36 = OpCompositeExtract %float %35 0
-               OpStore %res %36
-         %39 = OpLoad %float %res None
-               OpReturnValue %39
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %35 = OpCompositeExtract %uint %32 2
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %38 UMin %30 %36
+         %39 = OpImageQueryLevels %uint %28
+         %40 = OpISub %uint %39 %uint_1
+         %41 = OpExtInst %uint %38 UMin %31 %40
+         %42 = OpImageQuerySizeLod %v3uint %28 %41
+         %43 = OpVectorShuffle %v2uint %42 %42 0 1
+         %45 = OpISub %v2uint %43 %46
+         %47 = OpBitcast %v2uint %29
+         %48 = OpExtInst %v2uint %38 UMin %47 %45
+         %49 = OpCompositeConstruct %v3uint %48 %37
+         %50 = OpImageFetch %v4float %28 %49 Lod %41
+         %51 = OpCompositeExtract %float %50 0
+               OpStore %res %51
+         %54 = OpLoad %float %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_66be47
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %float %textureLoad_66be47
+         %60 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %float %textureLoad_66be47
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %51 %50 None
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
+         %64 = OpFunctionCall %float %textureLoad_66be47
+         %65 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %65 %64 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %61 None
-         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %63 = OpFunctionCall %float %textureLoad_66be47
-               OpStore %62 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %77 = OpFunctionCall %float %textureLoad_66be47
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %float %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %float %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.glsl
index a59520f..4fec1ba 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_67d826() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_67d826() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
index d576aff..31a9c80 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_67d826() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
index d576aff..31a9c80 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_67d826() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.msl
index 1c722c3..ab45946 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_67d826(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.msl
index fd74f96..819d1de 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_67d826(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.spvasm
index 5d2a8fc..c64b144 100644
--- a/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/67d826.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_67d826 = OpFunction %v4float None %10
@@ -59,24 +63,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_67d826
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_67d826
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_67d826
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_67d826
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.glsl
index b405cf1..a2e534e 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_67edca() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_67edca() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_67edca() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
index cee1663..9113dbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_67edca() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_67edca();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
index cee1663..9113dbf 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_67edca() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_67edca();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.msl
index 510b4d9..ccadb8b 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_67edca(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.msl
index 3d7c706..978c13a 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_67edca(texture3d<uint, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.spvasm
index 4a6ead5..235423df 100644
--- a/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/67edca.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_67edca = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %30 = OpISub %v3uint %28 %31
+         %33 = OpBitcast %v3uint %27
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_67edca
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_67edca
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_67edca
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_67edca
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_67edca
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_67edca
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
index 99ae523..4cfb2be 100644
--- a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_68d273() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
index 99ae523..4cfb2be 100644
--- a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_68d273() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.msl
index 63dfcf7..4e7a191 100644
--- a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_68d273(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.msl
index ff98e33..72b3c4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_68d273(texture3d<int, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.spvasm
index d4dff79..52e430b 100644
--- a/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/68d273.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_68d273 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_68d273
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_68d273
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_68d273
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_68d273
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.glsl
index 315d33b..4251ec2 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 float textureLoad_6925bc() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 float textureLoad_6925bc() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 float textureLoad_6925bc() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  float res = texelFetch(arg_0, v_3, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
index c149b89..83bff49 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float res = arg_0.Load(v_3, int(v)).x;
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6925bc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
index c149b89..83bff49 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float res = arg_0.Load(v_3, int(v)).x;
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6925bc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.msl
index dcbfd7b..409eb60 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float textureLoad_6925bc(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.msl
index adc92bd..908d57c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_6925bc(depth2d_ms<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.spvasm
index aa671e5..97d5d0e 100644
--- a/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6925bc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,17 +65,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %49 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6925bc = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +89,48 @@
          %27 = OpLoad %7 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Sample %29
-         %31 = OpCompositeExtract %float %30 0
-               OpStore %res %31
-         %34 = OpLoad %float %res None
-               OpReturnValue %34
+         %30 = OpImageQuerySize %v2uint %27
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %28
+         %35 = OpExtInst %v2uint %36 UMin %34 %32
+         %37 = OpImageFetch %v4float %27 %35 Sample %29
+         %38 = OpCompositeExtract %float %37 0
+               OpStore %res %38
+         %41 = OpLoad %float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_6925bc
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %float %textureLoad_6925bc
+         %47 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_6925bc
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %float %textureLoad_6925bc
+         %53 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_6925bc
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %65 = OpFunctionCall %float %textureLoad_6925bc
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.glsl
index e9b29c0..facfa5e 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_69fee5() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_69fee5() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
index 289f923..65f60a5 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_69fee5() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
index 289f923..65f60a5 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_69fee5() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.msl
index 51ad6bb..e16aae5 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_69fee5(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.msl
index 668a56b..4ad1dfb 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_69fee5(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.spvasm
index 9d3c526..11e6c5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/69fee5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_69fee5 = OpFunction %v4float None %10
@@ -59,24 +61,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_69fee5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_69fee5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_69fee5
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_69fee5
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
index 24bd364..c1f09e5 100644
--- a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6a6871() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
index 24bd364..c1f09e5 100644
--- a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6a6871() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.msl
index 570650c..e8db6fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_6a6871(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.msl
index 1b661b0..973e23d 100644
--- a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6a6871(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.spvasm
index e9e9b6a..b7a0bfd 100644
--- a/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6a6871.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6a6871 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_6a6871
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_6a6871
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_6a6871
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_6a6871
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.glsl
index 5d045a5..676782f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6b77d4() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_6b77d4() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_2), v_4), 0u));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6b77d4() {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uint v_3 = (uvec2(textureSize(arg_0, int(v_2))).x - 1u);
+  ivec2 v_4 = ivec2(uvec2(min(uint(v_1), v_3), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
index bc0f27a..7ff1b15 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6b77d4() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  uint4 res = uint4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6b77d4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
index bc0f27a..7ff1b15 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6b77d4() {
   int arg_1 = int(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  uint4 res = uint4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6b77d4();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.msl
index 2d0963f..8731ab6 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 uint4 textureLoad_6b77d4(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.msl
index 82d1db3..a3747ec 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6b77d4(texture1d<uint, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.spvasm
index 80a1dd9..1c3a20f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6b77d4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6b77d4 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -86,43 +88,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4uint %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4uint %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %uint %27 %32
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %28
+         %37 = OpExtInst %uint %33 UMin %36 %35
+         %38 = OpImageFetch %v4uint %27 %37 Lod %32
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_6b77d4
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_6b77d4
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4uint %textureLoad_6b77d4
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_6b77d4
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %57 = OpFunctionCall %v4uint %textureLoad_6b77d4
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %65 = OpFunctionCall %v4uint %textureLoad_6b77d4
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4uint %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4uint %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
index 919fe19..40eba71 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_6b8ba6() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
index 919fe19..40eba71 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_6b8ba6() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.msl
index ed56bbd..3958143 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_6b8ba6(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.msl
index 76e4e1d..d233395 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_6b8ba6(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.spvasm
index cea9e6f..8fcdf55 100644
--- a/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6b8ba6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6b8ba6 = OpFunction %v4float None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6b8ba6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_6b8ba6
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_6b8ba6
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_6b8ba6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
index dac4f96..4e57b9f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_6ba9ab() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
index dac4f96..4e57b9f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_6ba9ab() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.msl
index 002f85a..0915053 100644
--- a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_6ba9ab(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.msl
index 596e1fb..e4cc6ab 100644
--- a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_6ba9ab(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.spvasm
index 1f94c2c..9d9a7df 100644
--- a/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6ba9ab.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6ba9ab = OpFunction %v4float None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6ba9ab
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_6ba9ab
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_6ba9ab
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_6ba9ab
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
index 4829883..acd3660 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6bf3e2() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
index 4829883..acd3660 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6bf3e2() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.msl
index aba9bcd..8bf033b 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_6bf3e2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.msl
index 9686fa4..8c12bcd 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6bf3e2(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.spvasm
index d799e7e..72e99b6 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6bf3e2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6bf3e2 = OpFunction %v4float None %10
@@ -59,25 +63,33 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-         %29 = OpVectorShuffle %v4float %28 %28 2 1 0 3
-               OpStore %res %29
-         %32 = OpLoad %v4float %res None
-               OpReturnValue %32
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+         %40 = OpVectorShuffle %v4float %39 %39 2 1 0 3
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_6bf3e2
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_6bf3e2
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_6bf3e2
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_6bf3e2
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.glsl
index 03343b7..343fe04 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_6bf4b7() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_6bf4b7() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_6bf4b7() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
index c06e934..e1567a7 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6bf4b7() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6bf4b7();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
index c06e934..e1567a7 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_6bf4b7() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6bf4b7();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.msl
index 8646cf3..23272f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_6bf4b7(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.msl
index 736ad11..29c8a7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_6bf4b7(texture3d<uint, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.spvasm
index bb556e5..74abfc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6bf4b7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %39 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6bf4b7 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v3int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %31 %33
+         %36 = OpImageQuerySizeLod %v3uint %29 %34
+         %38 = OpISub %v3uint %36 %39
+         %40 = OpBitcast %v3uint %30
+         %41 = OpExtInst %v3uint %35 UMin %40 %38
+         %42 = OpImageFetch %v4uint %29 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4uint %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_6bf4b7
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %69 = OpFunctionCall %v4uint %textureLoad_6bf4b7
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4uint %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.glsl
index ef9ac6b..28e52f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_6d1fb4() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_6d1fb4() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
index 3be0e3a..49c342c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_6d1fb4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
index 3be0e3a..49c342c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_6d1fb4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.msl
index a67c82b..8762d2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_6d1fb4(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.msl
index 88b97c7..8088c14 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_6d1fb4(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.spvasm
index 22d9094..d98e572 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6d1fb4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,7 +45,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_6d1fb4 = OpFunction %v4uint None %10
@@ -56,23 +58,31 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2uint %arg_1 None
          %21 = OpLoad %uint %arg_2 None
-         %23 = OpCompositeConstruct %v3uint %20 %21
-         %24 = OpImageRead %v4uint %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %24 = OpCompositeExtract %uint %22 2
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %21 %25
+         %28 = OpImageQuerySize %v3uint %19
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %30 = OpISub %v2uint %29 %15
+         %31 = OpExtInst %v2uint %27 UMin %20 %30
+         %32 = OpCompositeConstruct %v3uint %31 %26
+         %33 = OpImageRead %v4uint %19 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_6d1fb4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_6d1fb4
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_6d1fb4
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_6d1fb4
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.glsl
index af4a898..98a4983 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_6d376a() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_6d376a() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_6d376a() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
index 96451d7..287d0da 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_6d376a() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6d376a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
index 96451d7..287d0da 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_6d376a() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  float4 res = float4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6d376a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.msl
index 1686a6b..a95daec 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_6d376a(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.msl
index be22133..ddeb634 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_6d376a(texture1d<float, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.spvasm
index 39fa810..e8e823b 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6d376a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %54 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6d376a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +82,49 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %uint %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpImageFetch %v4float %22 %23 Lod %24
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %22
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageQuerySizeLod %uint %22 %27
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpExtInst %uint %28 UMin %23 %30
+         %32 = OpImageFetch %v4float %22 %31 Lod %27
+               OpStore %res %32
+         %35 = OpLoad %v4float %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6d376a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_6d376a
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_6d376a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_6d376a
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_6d376a
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %58 = OpFunctionCall %v4float %textureLoad_6d376a
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %38
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4float %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
index 574cb4c..6a99c02 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6d7bb5() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
index 574cb4c..6a99c02 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6d7bb5() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.msl
index 61db903..62baf68 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_6d7bb5(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.msl
index 31bba58..3187b47 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6d7bb5(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.spvasm
index 85a6c7b..4966839 100644
--- a/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6d7bb5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6d7bb5 = OpFunction %v4float None %10
@@ -59,24 +61,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_6d7bb5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_6d7bb5
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_6d7bb5
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_6d7bb5
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
index 0858afc..fbc89a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_6e903f() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
index 0858afc..fbc89a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_6e903f() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.msl
index 6fff8c1..4db23af 100644
--- a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_6e903f(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.msl
index 3d277fc..e3bba0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_6e903f(texture3d<int, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.spvasm
index c6a5f5b..d07df88 100644
--- a/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6e903f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6e903f = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %22 = OpISub %v3uint %19 %23
+         %25 = OpBitcast %v3uint %18
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_6e903f
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_6e903f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_6e903f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_6e903f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.glsl
index 50d6082..a540c9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_6f0370() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_6f0370() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_6f0370() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
index 87b5c06..af54740 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f0370() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f0370();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
index 87b5c06..af54740 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_6f0370() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f0370();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.msl
index 62347c0..f08296c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_6f0370(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.msl
index 0ca5923..0f843c3 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_6f0370(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.spvasm
index faaeea6..58c303b 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6f0370.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6f0370 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_6f0370
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_6f0370
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_6f0370
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_6f0370
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_6f0370
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_6f0370
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
index 7261de9..f8376f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f0ea8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
index 7261de9..f8376f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_6f0ea8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.msl
index 9412058..c3e746b 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_6f0ea8(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.msl
index 98b8659..fddb52c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6f0ea8(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.spvasm
index 12a1078..a98fc69 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6f0ea8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_6f0ea8 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_6f0ea8
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_6f0ea8
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_6f0ea8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_6f0ea8
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.glsl
index cd5e192..552e987 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_6f1750() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_6f1750() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_6f1750() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
index 82814a3..6488bd4 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_6f1750() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f1750();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
index 82814a3..6488bd4 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_6f1750() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_6f1750();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.msl
index cf28f54..8685b13 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_6f1750(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.msl
index 77194a3..1915b18 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_6f1750(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.spvasm
index 1ea73e5..59fa1e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6f1750.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_6f1750 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,44 +86,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_6f1750
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_6f1750
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_6f1750
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_6f1750
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_6f1750
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_6f1750
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
index eef5590..7e17791 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6f8927() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
index eef5590..7e17791 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_6f8927() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.msl
index e4f57a4..cfaac5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_6f8927(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.msl
index f6141b8..4660649 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_6f8927(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.spvasm
index 2ba2586..6a19b43 100644
--- a/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/6f8927.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_6f8927 = OpFunction %v4float None %10
@@ -59,24 +63,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_6f8927
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_6f8927
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_6f8927
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_6f8927
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.glsl
index 13d43c5..21f626a 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_714471() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_714471() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_714471() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
index b34b3bc..4073e7b 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_714471() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_714471();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
index b34b3bc..4073e7b 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_714471() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_714471();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.msl
index f1f657b..b68de88 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_714471(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.msl
index 87a9dcd..e11e057 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_714471(texture2d<int, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.spvasm
index 9d61759..664cd49 100644
--- a/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/714471.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_714471 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -86,43 +88,49 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %31 = OpImageFetch %v4int %28 %29 Lod %30
-               OpStore %res %31
-         %34 = OpLoad %v4int %res None
-               OpReturnValue %34
+         %31 = OpImageQueryLevels %uint %28
+         %32 = OpISub %uint %31 %uint_1
+         %33 = OpExtInst %uint %34 UMin %30 %32
+         %35 = OpImageQuerySizeLod %v2uint %28 %33
+         %36 = OpISub %v2uint %35 %24
+         %37 = OpExtInst %v2uint %34 UMin %29 %36
+         %38 = OpImageFetch %v4int %28 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_714471
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_714471
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_714471
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_714471
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %58 = OpFunctionCall %v4int %textureLoad_714471
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %65 = OpFunctionCall %v4int %textureLoad_714471
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4int %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %44
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4int %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.glsl
index c4c42c8..f1e2c79 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_72bb3c() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_72bb3c() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_72bb3c() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
index a4e577b..a04d390 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_72bb3c() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_72bb3c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
index a4e577b..a04d390 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_72bb3c() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_72bb3c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.msl
index 65f7e86..0d8942d 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_72bb3c(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.msl
index 25f5b34..bbb90b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_72bb3c(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.spvasm
index 80dd09c..6a23728 100644
--- a/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/72bb3c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_72bb3c = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +88,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_72bb3c
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_72bb3c
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_72bb3c
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_72bb3c
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_72bb3c
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_72bb3c
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.glsl
index d8c3e90..e2eaa75 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_72c9c3() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_72c9c3() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
index ac59639..900013dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_72c9c3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
index ac59639..900013dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_72c9c3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.msl
index 4caa4c2..940b02c 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_72c9c3(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.msl
index c2235a4..f2cba3a 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_72c9c3(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.spvasm
index 9e646c8..620da4c 100644
--- a/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/72c9c3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,10 +46,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_72c9c3 = OpFunction %v4float None %10
@@ -60,24 +64,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_72c9c3
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_72c9c3
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_72c9c3
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_72c9c3
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
index fefb04f..7cd516c 100644
--- a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_742f1b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
index fefb04f..7cd516c 100644
--- a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_742f1b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.msl
index 60743fc..9aadded 100644
--- a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_742f1b(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.msl
index 15000ce..0d8b8a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_742f1b(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.spvasm
index c585e82..3cffeb9 100644
--- a/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/742f1b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_742f1b = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_742f1b
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_742f1b
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_742f1b
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_742f1b
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.glsl
index d3076ae..928c011 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_749704() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_749704() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_749704() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
index aa483f4..4591a7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_749704() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_749704();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
index aa483f4..4591a7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_749704() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_749704();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.msl
index d7231dc..23cb7fc 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_749704(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.msl
index 72943fc..8cf87e9 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_749704(texture2d<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.spvasm
index 26544db..bbaa36d 100644
--- a/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/749704.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_749704 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %30 = OpISub %v2uint %28 %31
+         %33 = OpBitcast %v2uint %27
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_749704
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_749704
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_749704
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_749704
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_749704
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_749704
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
index d75fc83..c854c7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_74a387() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
index d75fc83..c854c7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_74a387() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.msl
index 8863c67..3a8b9c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_74a387(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.msl
index 78ebb1a..7157a6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_74a387(texture1d<int, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.spvasm
index 4210a07..64bc04e 100644
--- a/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/74a387.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_74a387 = OpFunction %v4int None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4int %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4int %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4int %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_74a387
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4int %textureLoad_74a387
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_74a387
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_74a387
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.glsl
index 5ef74d4..030c454 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_773c46() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_773c46() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_773c46() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
index ca62c4c..80865a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_773c46() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_773c46();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
index ca62c4c..80865a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_773c46() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_773c46();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.msl
index 7b76c2b..9dd6122 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_773c46(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.msl
index 496ece7..a47a363 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_773c46(texture2d<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.spvasm
index 472a78e..1033242 100644
--- a/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/773c46.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_773c46 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %28 = OpISub %v2uint %27 %23
+         %29 = OpExtInst %v2uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_773c46
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_773c46
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_773c46
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_773c46
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_773c46
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_773c46
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.glsl
index a6eff95..a4b5464 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_789045() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  vec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_789045() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  vec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_789045() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
index 32c8a2e..390fb4a 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_789045();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
index 32c8a2e..390fb4a 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_789045();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.msl
index ec7618b..ddcd94c 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int const v = arg_2;
+  int2 const v = arg_1;
   uint const v_1 = arg_3;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.msl
index ef6428c..ef1b62c 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_789045(texture2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.spvasm
index a1955e7..749f185 100644
--- a/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/789045.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %53 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
-         %59 = OpConstantNull %v4float
+         %73 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_789045 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -90,44 +94,57 @@
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %int %arg_2 None
          %32 = OpLoad %uint %arg_3 None
-         %34 = OpCompositeConstruct %v3int %30 %31
-         %35 = OpImageFetch %v4float %29 %34 Lod %32
-               OpStore %res %35
-         %38 = OpLoad %v4float %res None
-               OpReturnValue %38
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpBitcast %uint %31
+         %39 = OpExtInst %uint %40 UMin %38 %37
+         %41 = OpImageQueryLevels %uint %29
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %32 %42
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %30
+         %50 = OpExtInst %v2uint %40 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %39
+         %52 = OpImageFetch %v4float %29 %51 Lod %43
+               OpStore %res %52
+         %55 = OpLoad %v4float %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_789045
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4float %textureLoad_789045
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4float %textureLoad_789045
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %50 %49 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %59 None
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %61 = OpFunctionCall %v4float %textureLoad_789045
-               OpStore %60 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %58
          %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4float %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+         %65 = OpFunctionCall %v4float %textureLoad_789045
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %66 %65 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %77 = OpFunctionCall %v4float %textureLoad_789045
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %58
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4float %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.glsl
index e401646..e14bc07 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.glsl
@@ -2,20 +2,35 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_79e697() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +38,35 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_79e697() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +76,36 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_79e697() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_1), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +115,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_11 = vertex_main_inner();
+  gl_Position = v_11.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_11.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
index e691981..2dd66d03 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_79e697();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
index e691981..2dd66d03 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_79e697();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.msl
index 6c2c4c7..6066734 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.ir.msl
@@ -20,9 +20,12 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int const v = arg_2;
+  int2 const v = arg_1;
   int const v_1 = arg_3;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_4 = (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_4), v_2, v_3);
   return res;
 }
 
@@ -45,9 +48,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_5 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_5.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_5.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.msl
index b0e28cd..659f6aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_79e697(texture2d_array<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.spvasm
index b018b96..f1a9e19 100644
--- a/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/79e697.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,20 +66,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_79e697 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -92,44 +96,58 @@
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
          %31 = OpLoad %int %arg_3 None
-         %33 = OpCompositeConstruct %v3int %29 %30
-         %34 = OpImageFetch %v4int %28 %33 Lod %31
-               OpStore %res %34
-         %37 = OpLoad %v4int %res None
-               OpReturnValue %37
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %36 = OpCompositeExtract %uint %32 2
+         %37 = OpISub %uint %36 %uint_1
+         %39 = OpBitcast %uint %30
+         %40 = OpExtInst %uint %41 UMin %39 %37
+         %42 = OpImageQueryLevels %uint %28
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %31
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %28 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %29
+         %52 = OpExtInst %v2uint %41 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %40
+         %54 = OpImageFetch %v4int %28 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4int %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_79e697
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4int %textureLoad_79e697
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_79e697
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %63 = OpFunctionCall %v4int %textureLoad_79e697
-               OpStore %61 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %40
+%compute_main = OpFunction %void None %60
          %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %v4int %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+         %67 = OpFunctionCall %v4int %textureLoad_79e697
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %68 %67 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %80 = OpFunctionCall %v4int %textureLoad_79e697
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4int %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.glsl
index 50d0d52..96e9cb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7ab4df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7ab4df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_7ab4df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_4));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
index b51efb8..9aa32f7 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7ab4df();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
index b51efb8..9aa32f7 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7ab4df();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.msl
index 30d4f2b..96aee0f 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint const v = arg_2;
-  int const v_1 = arg_3;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.msl
index 67ca700..6d945de 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_7ab4df(texture2d_array<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.spvasm
index 8a3093b..8fd3458 100644
--- a/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7ab4df.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 73
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %44 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %56 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %60 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %63 = OpConstantNull %v4float
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7ab4df = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -93,45 +97,57 @@
          %32 = OpLoad %v2int %arg_1 None
          %33 = OpLoad %uint %arg_2 None
          %34 = OpLoad %int %arg_3 None
-         %35 = OpBitcast %int %33
-         %37 = OpCompositeConstruct %v3int %32 %35
-         %38 = OpImageFetch %v4uint %31 %37 Lod %34
-               OpStore %res %38
-         %41 = OpLoad %v4uint %res None
-               OpReturnValue %41
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpExtInst %uint %41 UMin %33 %39
+         %42 = OpImageQueryLevels %uint %31
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %34
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %32
+         %52 = OpExtInst %v2uint %41 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %40
+         %54 = OpImageFetch %v4uint %31 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4uint %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_7ab4df
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4uint %textureLoad_7ab4df
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %51 = OpLabel
-         %52 = OpFunctionCall %v4uint %textureLoad_7ab4df
-         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %53 %52 None
+%compute_main = OpFunction %void None %60
+         %66 = OpLabel
+         %67 = OpFunctionCall %v4uint %textureLoad_7ab4df
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %68 %67 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %56
-         %57 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %60
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %61 %63 None
-         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %65 = OpFunctionCall %v4uint %textureLoad_7ab4df
-               OpStore %64 %65 None
-         %66 = OpLoad %VertexOutput %out None
-               OpReturnValue %66
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %80 = OpFunctionCall %v4uint %textureLoad_7ab4df
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
                OpFunctionEnd
-%vertex_main = OpFunction %void None %44
-         %68 = OpLabel
-         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %70 = OpCompositeExtract %v4float %69 0
-               OpStore %vertex_main_position_Output %70 None
-         %71 = OpCompositeExtract %v4uint %69 1
-               OpStore %vertex_main_loc0_Output %71 None
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4uint %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.glsl
index 6f759a8..89d1424 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.glsl
@@ -2,20 +2,32 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_7b63e0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  float res = texelFetch(arg_0, v_8, int(v_6)).x;
   return res;
 }
 void main() {
@@ -23,20 +35,32 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_7b63e0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  float res = texelFetch(arg_0, v_8, int(v_6)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +70,33 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_7b63e0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_6 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_4));
+  float res = texelFetch(arg_0, v_7, int(v_5)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +106,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
index aba891c..2e36ecf 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7b63e0();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
index aba891c..2e36ecf 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7b63e0();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.msl
index 05fc33a..595ef22f 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.msl
index 6b230d4..3132f3b 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.spvasm
index d9c9825..d0d60407 100644
--- a/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7b63e0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 80
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,17 +65,17 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %51 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %67 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %70 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7b63e0 = OpFunction %float None %15
          %16 = OpLabel
@@ -88,45 +90,56 @@
          %27 = OpLoad %v2uint %arg_1 None
          %28 = OpLoad %uint %arg_2 None
          %29 = OpLoad %uint %arg_3 None
-         %31 = OpCompositeConstruct %v3uint %27 %28
-         %32 = OpImageFetch %v4float %26 %31 Lod %29
-         %33 = OpCompositeExtract %float %32 0
-               OpStore %res %33
-         %36 = OpLoad %float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySizeLod %v3uint %26 %uint_0
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %28 %34
+         %37 = OpImageQueryLevels %uint %26
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpExtInst %uint %36 UMin %29 %38
+         %40 = OpImageQuerySizeLod %v3uint %26 %39
+         %41 = OpVectorShuffle %v2uint %40 %40 0 1
+         %42 = OpISub %v2uint %41 %21
+         %43 = OpExtInst %v2uint %36 UMin %27 %42
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageFetch %v4float %26 %44 Lod %39
+         %46 = OpCompositeExtract %float %45 0
+               OpStore %res %46
+         %49 = OpLoad %float %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %float %textureLoad_7b63e0
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %float %textureLoad_7b63e0
+         %55 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %float %textureLoad_7b63e0
-         %48 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %52
+         %58 = OpLabel
+         %59 = OpFunctionCall %float %textureLoad_7b63e0
+         %60 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %60 = OpFunctionCall %float %textureLoad_7b63e0
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %70 None
+         %71 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %72 = OpFunctionCall %float %textureLoad_7b63e0
+               OpStore %71 %72 None
+         %73 = OpLoad %VertexOutput %out None
+               OpReturnValue %73
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %float %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %52
+         %75 = OpLabel
+         %76 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %77 = OpCompositeExtract %v4float %76 0
+               OpStore %vertex_main_position_Output %77 None
+         %78 = OpCompositeExtract %float %76 1
+               OpStore %vertex_main_loc0_Output %78 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.glsl
index 3cf8259..5edfccb 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 ivec4 textureLoad_7bee94() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 ivec4 textureLoad_7bee94() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 ivec4 textureLoad_7bee94() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
index 8b5ec37..bf3b837 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7bee94();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
index 8b5ec37..bf3b837 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7bee94();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.msl
index 4494677..52acd8c 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_7bee94(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  int const v_1 = arg_2;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.msl
index 6760acd..1eb2750 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_7bee94(texture2d_ms<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.spvasm
index eb23722..514a090 100644
--- a/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7bee94.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7bee94 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +89,46 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Sample %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQuerySize %v2uint %29
+         %33 = OpISub %v2uint %32 %24
+         %34 = OpExtInst %v2uint %35 UMin %30 %33
+         %36 = OpImageFetch %v4int %29 %34 Sample %31
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_7bee94
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_7bee94
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_7bee94
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_7bee94
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_7bee94
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_7bee94
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.glsl
index 9303745..0ddb84d 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.glsl
@@ -2,20 +2,35 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7c90e5() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +38,35 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_7c90e5() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +76,36 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_7c90e5() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_1), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +115,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_11 = vertex_main_inner();
+  gl_Position = v_11.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_11.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
index 3e699b4..61d1a16 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7c90e5();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
index 3e699b4..61d1a16 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7c90e5();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.msl
index 3722c91..baa2516 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.ir.msl
@@ -20,9 +20,12 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int const v = arg_2;
+  int2 const v = arg_1;
   int const v_1 = arg_3;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_4 = (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_4), v_2, v_3);
   return res;
 }
 
@@ -45,9 +48,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_5 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_5.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_5.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.msl
index a35909f..c1933b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_7c90e5(texture2d_array<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.spvasm
index e40acd4..bc9b294 100644
--- a/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7c90e5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,19 +67,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7c90e5 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -92,44 +96,58 @@
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %int %arg_2 None
          %32 = OpLoad %int %arg_3 None
-         %34 = OpCompositeConstruct %v3int %30 %31
-         %35 = OpImageFetch %v4uint %29 %34 Lod %32
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %39 = OpBitcast %uint %31
+         %40 = OpExtInst %uint %41 UMin %39 %37
+         %42 = OpImageQueryLevels %uint %29
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %32
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %29 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %30
+         %52 = OpExtInst %v2uint %41 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %40
+         %54 = OpImageFetch %v4uint %29 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4uint %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_7c90e5
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4uint %textureLoad_7c90e5
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_7c90e5
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %63 = OpFunctionCall %v4uint %textureLoad_7c90e5
-               OpStore %61 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %60
          %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %v4uint %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+         %67 = OpFunctionCall %v4uint %textureLoad_7c90e5
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %68 %67 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %80 = OpFunctionCall %v4uint %textureLoad_7c90e5
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4uint %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.glsl
index 82917f5..72ea595 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_7dab57() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_7dab57() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_7dab57() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
index 33b141e..a772338 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_7dab57() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7dab57();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
index 33b141e..a772338 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_7dab57() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7dab57();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.msl
index cf62139..861956b 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_7dab57(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.msl
index 29d4ed6..7549d74 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_7dab57(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.spvasm
index a9f4602..e6c1d4c 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7dab57.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -70,15 +72,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7dab57 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -90,45 +92,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %24
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4int %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_7dab57
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_7dab57
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_7dab57
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_7dab57
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_7dab57
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_7dab57
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.glsl
index c2e6e7c..cd1c5b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_7dd3d5() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_7dd3d5() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
index 639ff19..601c9fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_7dd3d5() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
index 639ff19..601c9fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_7dd3d5() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.msl
index c1c9337..2b0059f8 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_7dd3d5(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.msl
index bed9b13..1519d3b 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_7dd3d5(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.spvasm
index 6fcd7b3..91533e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7dd3d5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,12 +44,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_7dd3d5 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -59,23 +64,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_7dd3d5
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_7dd3d5
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_7dd3d5
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_7dd3d5
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
index 3948f94..f9ec19e 100644
--- a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7e5cbc() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
index 3948f94..f9ec19e 100644
--- a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_7e5cbc() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.msl
index f0571b6..e641ab6 100644
--- a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_7e5cbc(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.msl
index b585a9f..9bec9ea 100644
--- a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_7e5cbc(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.spvasm
index c2418bf..31b44ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7e5cbc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_7e5cbc = OpFunction %v4float None %10
@@ -50,23 +52,26 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-         %19 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+         %23 = OpVectorShuffle %v4float %22 %22 2 1 0 3
+               OpStore %res %23
+         %26 = OpLoad %v4float %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_7e5cbc
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4float %textureLoad_7e5cbc
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_7e5cbc
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_7e5cbc
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.glsl
index 3f21c1c..9501393 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_7fd822() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_5, int(v_4)).x;
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_7fd822() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_5, int(v_4)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_7fd822() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_4, int(v_3)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
index ea718e4..feef875 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float textureLoad_7fd822() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_4, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7fd822();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
index ea718e4..feef875 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float textureLoad_7fd822() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_4, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_7fd822();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.msl
index 248f98f..0374ddb 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float textureLoad_7fd822(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.msl
index 1fb3af8..fb09030 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float textureLoad_7fd822(depth2d<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.spvasm
index d6299fe..37b4d86 100644
--- a/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/7fd822.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %49 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_7fd822 = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +87,51 @@
          %27 = OpLoad %7 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-         %31 = OpCompositeExtract %float %30 0
-               OpStore %res %31
-         %34 = OpLoad %float %res None
-               OpReturnValue %34
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %29
+         %33 = OpExtInst %uint %34 UMin %32 %31
+         %35 = OpImageQuerySizeLod %v2uint %27 %33
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %34 UMin %28 %36
+         %38 = OpImageFetch %v4float %27 %37 Lod %33
+         %39 = OpCompositeExtract %float %38 0
+               OpStore %res %39
+         %42 = OpLoad %float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_7fd822
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %float %textureLoad_7fd822
+         %48 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_7fd822
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %float %textureLoad_7fd822
+         %54 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_7fd822
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %66 = OpFunctionCall %float %textureLoad_7fd822
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %45
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
index 221ee3c..5bc7aa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_80dae1() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
index 221ee3c..5bc7aa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_80dae1() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.msl
index fc5d9af..2d502b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_80dae1(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.msl
index 19d29fb..c0f222a 100644
--- a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_80dae1(texture1d<int, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.spvasm
index bd8f8e5..648016b 100644
--- a/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/80dae1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_80dae1 = OpFunction %v4int None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4int %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4int %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4int %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_80dae1
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4int %textureLoad_80dae1
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_80dae1
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_80dae1
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.glsl
index dbc2ec6..4768578 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_81c381() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_81c381() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  int v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uint v_5 = (uvec2(textureSize(arg_0, int(v_4))).x - 1u);
+  ivec2 v_6 = ivec2(uvec2(min(uint(v_2), v_5), 0u));
+  vec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_81c381() {
   int arg_1 = 1;
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(ivec2(arg_1, 0));
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  int v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uint v_4 = (uvec2(textureSize(arg_0, int(v_3))).x - 1u);
+  ivec2 v_5 = ivec2(uvec2(min(uint(v_1), v_4), 0u));
+  vec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
index c49c058..5561ed1 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_81c381() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  float4 res = float4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_81c381();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
index c49c058..5561ed1 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_81c381() {
   int arg_1 = int(1);
   int arg_2 = int(1);
-  int v = arg_2;
-  int v_1 = int(arg_1);
-  float4 res = float4(arg_0.Load(int2(v_1, int(v))));
+  int v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(uint(arg_2), (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  uint v_4 = (v_3.x - 1u);
+  int v_5 = int(min(uint(v), v_4));
+  float4 res = float4(arg_0.Load(int2(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_81c381();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.msl
index b96e89d..226d7cf 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.ir.msl
@@ -19,7 +19,10 @@
 float4 textureLoad_81c381(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -42,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.msl
index a811696..64f3e86 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_81c381(texture1d<float, access::sample> tint_symbol_1) {
   int arg_1 = 1;
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.spvasm
index 9ce16f8..1b3e26f 100644
--- a/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/81c381.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %58 = OpConstantNull %VertexOutput
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_81c381 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -82,43 +84,51 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %int %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpImageFetch %v4float %22 %23 Lod %24
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQueryLevels %uint %22
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySizeLod %uint %22 %30
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %23
+         %35 = OpExtInst %uint %31 UMin %34 %33
+         %36 = OpImageFetch %v4float %22 %35 Lod %30
+               OpStore %res %36
+         %39 = OpLoad %v4float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_81c381
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4float %textureLoad_81c381
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_81c381
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_81c381
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_81c381
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %60 None
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %62 = OpFunctionCall %v4float %textureLoad_81c381
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %42
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %v4float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.glsl
index 107f73e..17b4c5f 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_83162f() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_83162f() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_83162f() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
index efbae20..27e348b 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_83162f() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83162f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
index efbae20..27e348b 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_83162f() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83162f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.msl
index 84cac06..1092018 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_83162f(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.msl
index aa30773..795515e 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_83162f(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.spvasm
index ef0e643..fd6cc69 100644
--- a/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/83162f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_83162f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_83162f
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_83162f
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_83162f
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_83162f
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_83162f
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_83162f
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.glsl
index 67b50ea..59c77fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_83cea4() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_83cea4() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_83cea4() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
index 4b4c7a9..bb79ebf 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_83cea4() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83cea4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
index 4b4c7a9..bb79ebf 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_83cea4() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_83cea4();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.msl
index ff9d488..4e0d66e 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_83cea4(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.msl
index 0c3e8cb..c04f74d 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_83cea4(texture1d<uint, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.spvasm
index a78398b..10b1ab8 100644
--- a/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/83cea4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,18 +64,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_83cea4 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %int %arg_1 None
-         %26 = OpImageRead %v4uint %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4uint %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %25
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4uint %24 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4uint %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_83cea4
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %32
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4uint %textureLoad_83cea4
          %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_83cea4
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4uint %textureLoad_83cea4
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %59 = OpFunctionCall %v4uint %textureLoad_83cea4
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4uint %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.glsl
index 69b7d13..d9f47f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_83d6e3() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_83d6e3() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
index 147a31d..a4fd04c 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_83d6e3() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
index 147a31d..a4fd04c 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_83d6e3() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.msl
index 76ee269..125fbed 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_83d6e3(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.msl
index f2bd344..c3f323c 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_83d6e3(texture1d<uint, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.spvasm
index 4378506..616a0c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/83d6e3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,9 +40,10 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_83d6e3 = OpFunction %v4uint None %10
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4uint %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %17
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4uint %16 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4uint %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_83d6e3
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4uint %textureLoad_83d6e3
          %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_83d6e3
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
index e4d034f..6eeb155 100644
--- a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_848d85() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
index e4d034f..6eeb155 100644
--- a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_848d85() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.msl
index 8948914..e423e7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_848d85(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.msl
index 8301c07..61ea806 100644
--- a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_848d85(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.spvasm
index 989b7dc..8fa5914 100644
--- a/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/848d85.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_848d85 = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_848d85
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_848d85
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_848d85
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_848d85
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
index 5a78ad7..dfc4196 100644
--- a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_84a438() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
index 5a78ad7..dfc4196 100644
--- a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_84a438() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.msl
index 2a6688e..f4ee0c3 100644
--- a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_84a438(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.msl
index 18072b0..4b1317f 100644
--- a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_84a438(texture2d<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.spvasm
index 750285b..7ae6b01 100644
--- a/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/84a438.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_84a438 = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %19
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_84a438
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_84a438
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_84a438
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_84a438
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.glsl
index d00258c..b3c3919 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_84c728() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_84c728() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_84c728() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
index df2e0bb..52f6b0d 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84c728() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84c728();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
index df2e0bb..52f6b0d 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_84c728() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84c728();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.msl
index cdc66a5..c066383 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_84c728(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.msl
index 8cf51c7..751d2d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_84c728(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.spvasm
index 34a6208..ca247e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/84c728.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_84c728 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_84c728
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_84c728
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_84c728
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_84c728
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_84c728
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_84c728
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.glsl
index ee92d22..0d340e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_84dee1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 vec4 textureLoad_84dee1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_84dee1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
index fee241f..f73c30b 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_84dee1() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84dee1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
index fee241f..f73c30b 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_84dee1() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_84dee1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.msl
index f231c5c..a434807 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_84dee1(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.msl
index 9899f6c..307471e 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_84dee1(texture2d<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.spvasm
index 5044c0f..6d90293 100644
--- a/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/84dee1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %46 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
-         %52 = OpConstantNull %v4float
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_84dee1 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -82,43 +84,49 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpExtInst %uint %31 UMin %27 %29
+         %32 = OpImageQuerySizeLod %v2uint %25 %30
+         %33 = OpISub %v2uint %32 %21
+         %34 = OpExtInst %v2uint %31 UMin %26 %33
+         %35 = OpImageFetch %v4float %25 %34 Lod %30
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_84dee1
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_84dee1
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_84dee1
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_84dee1
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_84dee1
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_84dee1
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.glsl
index ca40b63..ec768d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.glsl
@@ -2,20 +2,32 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_8527b1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +35,32 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_8527b1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +70,33 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_8527b1() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_6 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_4));
+  uvec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +106,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
index bc4699c..7134e4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8527b1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
index bc4699c..7134e4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8527b1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.msl
index 447c36b..9d00256 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.msl
index a59e2b7..387e630 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.spvasm
index cb1b95b..06d3bce 100644
--- a/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8527b1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,17 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %52 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %56 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %59 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8527b1 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -90,44 +92,55 @@
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
          %31 = OpLoad %uint %arg_3 None
-         %33 = OpCompositeConstruct %v3uint %29 %30
-         %34 = OpImageFetch %v4uint %28 %33 Lod %31
-               OpStore %res %34
-         %37 = OpLoad %v4uint %res None
-               OpReturnValue %37
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %35 = OpCompositeExtract %uint %32 2
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpExtInst %uint %38 UMin %30 %36
+         %39 = OpImageQueryLevels %uint %28
+         %40 = OpISub %uint %39 %uint_1
+         %41 = OpExtInst %uint %38 UMin %31 %40
+         %42 = OpImageQuerySizeLod %v3uint %28 %41
+         %43 = OpVectorShuffle %v2uint %42 %42 0 1
+         %44 = OpISub %v2uint %43 %23
+         %45 = OpExtInst %v2uint %38 UMin %29 %44
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageFetch %v4uint %28 %46 Lod %41
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_8527b1
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_8527b1
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
-         %47 = OpLabel
-         %48 = OpFunctionCall %v4uint %textureLoad_8527b1
-         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %49 %48 None
+%compute_main = OpFunction %void None %53
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_8527b1
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %52
-         %53 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %56
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %57 %59 None
-         %60 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %61 = OpFunctionCall %v4uint %textureLoad_8527b1
-               OpStore %60 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+%vertex_main_inner = OpFunction %VertexOutput None %64
+         %65 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_8527b1
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main = OpFunction %void None %53
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.glsl
index 35ba31b..fbe62bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_862833() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_862833() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_862833() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
index 6d6cc3c..0a0e627 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_862833() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_862833();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
index 6d6cc3c..0a0e627 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_862833() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_862833();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.msl
index 0ed19f4..f8aca2d 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_862833(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.msl
index 56605dc..a60bdca 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_862833(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.spvasm
index 93174947..1f355e9 100644
--- a/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/862833.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_862833 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_862833
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_862833
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_862833
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_862833
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_862833
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_862833
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
index fd6375d..f338354 100644
--- a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_878e24() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
index fd6375d..f338354 100644
--- a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_878e24() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.msl
index 38ab18c..a43e040 100644
--- a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_878e24(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.msl
index c81001a..2ab4e60 100644
--- a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_878e24(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.spvasm
index 88f26be..44ca469 100644
--- a/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/878e24.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_878e24 = OpFunction %v4float None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_878e24
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_878e24
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_878e24
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_878e24
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.glsl
index 88bd2e9..4063a66 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.glsl
@@ -2,20 +2,35 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_87be85() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  vec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 void main() {
@@ -23,20 +38,35 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_87be85() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  vec4 res = texelFetch(arg_0, v_11, int(v_8));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +76,36 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_87be85() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_1), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  vec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +115,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_11 = vertex_main_inner();
+  gl_Position = v_11.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_11.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
index 09f560a..f1613bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_87be85();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
index 09f560a..f1613bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  float4 res = float4(arg_0.Load(int4(v_8, v_9, int(v_5))));
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_87be85();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.msl
index 2f9b0b2..9d96f69 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.ir.msl
@@ -20,9 +20,12 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int const v = arg_2;
+  int2 const v = arg_1;
   int const v_1 = arg_3;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_4 = (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_4), v_2, v_3);
   return res;
 }
 
@@ -45,9 +48,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_5 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_5.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_5.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.msl
index d8f922e..9fef1c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_87be85(texture2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.spvasm
index e252d15..7287995 100644
--- a/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/87be85.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %73 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_87be85 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -89,44 +93,58 @@
          %27 = OpLoad %v2int %arg_1 None
          %28 = OpLoad %int %arg_2 None
          %29 = OpLoad %int %arg_3 None
-         %31 = OpCompositeConstruct %v3int %27 %28
-         %32 = OpImageFetch %v4float %26 %31 Lod %29
-               OpStore %res %32
-         %35 = OpLoad %v4float %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySizeLod %v3uint %26 %uint_0
+         %34 = OpCompositeExtract %uint %30 2
+         %35 = OpISub %uint %34 %uint_1
+         %37 = OpBitcast %uint %28
+         %38 = OpExtInst %uint %39 UMin %37 %35
+         %40 = OpImageQueryLevels %uint %26
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %29
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %26 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %27
+         %50 = OpExtInst %v2uint %39 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %38
+         %52 = OpImageFetch %v4float %26 %51 Lod %43
+               OpStore %res %52
+         %55 = OpLoad %v4float %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_87be85
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_87be85
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
          %60 = OpFunctionCall %v4float %textureLoad_87be85
-               OpStore %58 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4float %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%compute_main = OpFunction %void None %58
+         %64 = OpLabel
+         %65 = OpFunctionCall %v4float %textureLoad_87be85
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %66 %65 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %77 = OpFunctionCall %v4float %textureLoad_87be85
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %58
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4float %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
index 07c1590..c494b22 100644
--- a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_87f0a6() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
index 07c1590..c494b22 100644
--- a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_87f0a6() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.msl
index 3313f8d..76072f7 100644
--- a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_87f0a6(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.msl
index d80daae..739f99e 100644
--- a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_87f0a6(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.spvasm
index 8f70257..0735259 100644
--- a/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/87f0a6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,10 +43,13 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_87f0a6 = OpFunction %v4uint None %10
@@ -57,23 +62,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4uint %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %22
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %21
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4uint %20 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_87f0a6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_87f0a6
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_87f0a6
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_87f0a6
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.glsl
index 68c5a59..0ae508c 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_881349() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_881349() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
index 27c0b72..2cf9aa8 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_881349() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
index 27c0b72..2cf9aa8 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_881349() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.msl
index ed37b50..16998f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_881349(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.msl
index af96bd9..7f0aff8 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_881349(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.spvasm
index 3916305..613dc1c 100644
--- a/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/881349.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,12 +44,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_881349 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -59,23 +64,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_881349
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_881349
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_881349
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_881349
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.glsl
index 493fe33..bc22b02 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_89620b() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4))).zyxw;
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_89620b() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_89620b() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v))).zyxw;
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
index 01d14b6..2fd4030 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_89620b() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_89620b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
index 01d14b6..2fd4030 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_89620b() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_89620b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.msl
index b6c0de0..2e315b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_89620b(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.msl
index dd29291..e8197b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_89620b(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.spvasm
index 9b4fa04..617432a 100644
--- a/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/89620b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 80
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %50 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %68 = OpConstantNull %VertexOutput
+         %70 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_89620b = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,55 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
-               OpStore %res %31
-         %34 = OpLoad %v4float %res None
-               OpReturnValue %34
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+         %46 = OpVectorShuffle %v4float %45 %45 2 1 0 3
+               OpStore %res %46
+         %49 = OpLoad %v4float %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_89620b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_89620b
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4float %textureLoad_89620b
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4float %textureLoad_89620b
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_89620b
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %64
+         %65 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %70 None
+         %71 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %72 = OpFunctionCall %v4float %textureLoad_89620b
+               OpStore %71 %72 None
+         %73 = OpLoad %VertexOutput %out None
+               OpReturnValue %73
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %52
+         %75 = OpLabel
+         %76 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %77 = OpCompositeExtract %v4float %76 0
+               OpStore %vertex_main_position_Output %77 None
+         %78 = OpCompositeExtract %v4float %76 1
+               OpStore %vertex_main_loc0_Output %78 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.glsl
index 6cc7f9f..10be986 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_897cf3() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_897cf3() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_897cf3() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
index ffd09b9..a07693f 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_897cf3() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_897cf3();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
index ffd09b9..a07693f 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_897cf3() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_897cf3();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.msl
index c9d9ec8..97b25bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_897cf3(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.msl
index 457faa6..f956000 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_897cf3(texture2d<uint, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.spvasm
index a0fbd71..ebb6501 100644
--- a/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/897cf3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %48 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %55 = OpConstantNull %v4float
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_897cf3 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -85,43 +87,49 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4uint %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4uint %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %v2uint %27 %32
+         %35 = OpISub %v2uint %34 %23
+         %36 = OpExtInst %v2uint %33 UMin %28 %35
+         %37 = OpImageFetch %v4uint %27 %36 Lod %32
+               OpStore %res %37
+         %40 = OpLoad %v4uint %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_897cf3
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_897cf3
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4uint %textureLoad_897cf3
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4uint %textureLoad_897cf3
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %57 = OpFunctionCall %v4uint %textureLoad_897cf3
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %64 = OpFunctionCall %v4uint %textureLoad_897cf3
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4uint %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %43
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4uint %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.glsl
index 57d97bd..f79be41 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_8a291b() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3))).zyxw;
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_8a291b() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_8a291b() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v))).zyxw;
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
index b9fdb82..d86c524 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_8a291b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a291b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
index b9fdb82..d86c524 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_8a291b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a291b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.msl
index 5a153ce..35074f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_8a291b(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.msl
index 3b2fb25..cfa3de9 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_8a291b(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.spvasm
index f3869ec..530d883 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8a291b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %52 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %56 = OpConstantNull %VertexOutput
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8a291b = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,46 +90,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-         %34 = OpVectorShuffle %v4float %33 %33 2 1 0 3
-               OpStore %res %34
-         %37 = OpLoad %v4float %res None
-               OpReturnValue %37
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+         %45 = OpVectorShuffle %v4float %44 %44 2 1 0 3
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_8a291b
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_8a291b
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
-         %47 = OpLabel
-         %48 = OpFunctionCall %v4float %textureLoad_8a291b
-         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %49 %48 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_8a291b
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %52
-         %53 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %56
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %57 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %60 = OpFunctionCall %v4float %textureLoad_8a291b
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_8a291b
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4float %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.glsl
index 41fadce..708a6ce 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_8a9988() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_8a9988() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_8a9988() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
index 11c1605..654f1e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8a9988() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a9988();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
index 11c1605..654f1e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_8a9988() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8a9988();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.msl
index 113a614..a1000c3 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_8a9988(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.msl
index 5622987..184428a 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_8a9988(texture3d<int, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.spvasm
index fe40dcb..8aa7479 100644
--- a/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8a9988.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,15 +68,15 @@
          %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8a9988 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +85,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %29 = OpISub %v3uint %28 %24
+         %30 = OpExtInst %v3uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_8a9988
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_8a9988
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_8a9988
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_8a9988
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_8a9988
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_8a9988
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.glsl
index 65f5e44..2352f55 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.glsl
@@ -107,7 +107,7 @@
 vec4 textureLoad_8acf41() {
   ivec2 arg_1 = ivec2(1);
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, uvec2(arg_1));
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(arg_1), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 void main() {
@@ -220,7 +220,7 @@
 vec4 textureLoad_8acf41() {
   ivec2 arg_1 = ivec2(1);
   tint_ExternalTextureParams v_17 = tint_convert_tint_ExternalTextureParams(v_2.inner);
-  vec4 res = tint_TextureLoadExternal(v_17, uvec2(arg_1));
+  vec4 res = tint_TextureLoadExternal(v_17, min(uvec2(arg_1), ((v_17.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -336,7 +336,7 @@
 vec4 textureLoad_8acf41() {
   ivec2 arg_1 = ivec2(1);
   tint_ExternalTextureParams v_16 = tint_convert_tint_ExternalTextureParams(v_1.inner);
-  vec4 res = tint_TextureLoadExternal(v_16, uvec2(arg_1));
+  vec4 res = tint_TextureLoadExternal(v_16, min(uvec2(arg_1), ((v_16.apparentSize + uvec2(1u)) - uvec2(1u))));
   return res;
 }
 VertexOutput vertex_main_inner() {
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
index 5d9dd32..b054833 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.dxc.hlsl
@@ -60,79 +60,92 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_8acf41() {
   int2 arg_1 = (int(1)).xx;
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, uint2(arg_1));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, uint2(arg_1));
   return res;
 }
 
@@ -149,13 +162,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8acf41();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
index 5d9dd32..b054833 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.fxc.hlsl
@@ -60,79 +60,92 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 float4 textureLoad_8acf41() {
   int2 arg_1 = (int(1)).xx;
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_48, uint2(arg_1));
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = tint_TextureLoadExternal(arg_0_plane0, arg_0_plane1, v_55, uint2(arg_1));
   return res;
 }
 
@@ -149,13 +162,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8acf41();
-  VertexOutput v_49 = tint_symbol;
-  return v_49;
+  VertexOutput v_56 = tint_symbol;
+  return v_56;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_50 = vertex_main_inner();
-  vertex_main_outputs v_51 = {v_50.prevent_dce, v_50.pos};
-  return v_51;
+  VertexOutput v_57 = vertex_main_inner();
+  vertex_main_outputs v_58 = {v_57.prevent_dce, v_57.pos};
+  return v_58;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.msl
index 8c7c61d..2af413e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.ir.msl
@@ -126,7 +126,7 @@
 float4 textureLoad_8acf41(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   tint_ExternalTextureParams const v_19 = tint_load_struct_packed_vec3(tint_module_vars.arg_0_params);
-  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, uint2(arg_1));
+  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_19, min(uint2(arg_1), ((v_19.apparentSize + uint2(1u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.msl
index 16cdc7a..f364599 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.msl
@@ -93,6 +93,10 @@
   return select(uint2(4294967295u), select(uint2(v), uint2(0u), (v < float2(0.0f))), (v <= float2(4294967040.0f)));
 }
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float3 gammaCorrection(float3 v, GammaTransferParams params) {
   bool3 const cond = (fabs(v) < float3(params.D));
   float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F));
@@ -120,7 +124,7 @@
 
 float4 textureLoad_8acf41(texture2d<float, access::sample> tint_symbol_1, texture2d<float, access::sample> tint_symbol_2, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_3) {
   int2 arg_1 = int2(1);
-  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, arg_1, tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
+  float4 res = textureLoadExternal(tint_symbol_1, tint_symbol_2, tint_clamp(arg_1, int2(0), int2((((*(tint_symbol_3)).apparentSize + uint2(1u)) - uint2(1u)))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.spvasm
index 88bdd31..590c558 100644
--- a/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8acf41.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 188
+; Bound: 193
 ; Schema: 0
                OpCapability Shader
-         %88 = OpExtInstImport "GLSL.std.450"
+         %53 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -193,22 +193,23 @@
 %mat3v3float = OpTypeMatrix %v3float 3
 %mat3v2float = OpTypeMatrix %v2float 3
 %tint_ExternalTextureParams = OpTypeStruct %uint %uint %mat3v4float %tint_GammaTransferParams %tint_GammaTransferParams %mat3v3float %mat3v2float %mat3v2float %v2float %v2float %v2float %v2float %v2uint %v2float
+     %uint_1 = OpConstant %uint 1
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %54 = OpTypeFunction %void
+         %61 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %65 = OpTypeFunction %VertexOutput
+         %72 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %69 = OpConstantNull %VertexOutput
-         %71 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
-         %80 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
+         %76 = OpConstantNull %VertexOutput
+         %78 = OpConstantNull %v4float
+         %86 = OpTypeFunction %v4float %8 %8 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
        %bool = OpTypeBool
-        %129 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+        %134 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %162 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %167 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
 %textureLoad_8acf41 = OpFunction %v4float None %26
          %27 = OpLabel
       %arg_1 = OpVariable %_ptr_Function_v2int Function
@@ -220,160 +221,164 @@
          %39 = OpLoad %tint_ExternalTextureParams_std140 %36 None
          %40 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %39
          %45 = OpLoad %v2int %arg_1 None
-         %46 = OpBitcast %v2uint %45
-         %47 = OpFunctionCall %v4float %tint_TextureLoadExternal %34 %35 %40 %46
-               OpStore %res %47
-         %51 = OpLoad %v4float %res None
-               OpReturnValue %51
+         %46 = OpCompositeExtract %v2uint %40 12
+         %47 = OpIAdd %v2uint %46 %48
+         %50 = OpISub %v2uint %47 %48
+         %51 = OpBitcast %v2uint %45
+         %52 = OpExtInst %v2uint %53 UMin %51 %50
+         %54 = OpFunctionCall %v4float %tint_TextureLoadExternal %34 %35 %40 %52
+               OpStore %res %54
+         %58 = OpLoad %v4float %res None
+               OpReturnValue %58
                OpFunctionEnd
-%fragment_main = OpFunction %void None %54
-         %55 = OpLabel
-         %56 = OpFunctionCall %v4float %textureLoad_8acf41
-         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %57 %56 None
+%fragment_main = OpFunction %void None %61
+         %62 = OpLabel
+         %63 = OpFunctionCall %v4float %textureLoad_8acf41
+         %64 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %64 %63 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %54
-         %60 = OpLabel
-         %61 = OpFunctionCall %v4float %textureLoad_8acf41
-         %62 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %62 %61 None
+%compute_main = OpFunction %void None %61
+         %67 = OpLabel
+         %68 = OpFunctionCall %v4float %textureLoad_8acf41
+         %69 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %69 %68 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %65
-         %66 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %69
-         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %70 %71 None
-         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %74 = OpFunctionCall %v4float %textureLoad_8acf41
-               OpStore %72 %74 None
-         %75 = OpLoad %VertexOutput %out None
-               OpReturnValue %75
+%vertex_main_inner = OpFunction %VertexOutput None %72
+         %73 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %76
+         %77 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %77 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %80 = OpFunctionCall %v4float %textureLoad_8acf41
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %80
+%tint_TextureLoadExternal = OpFunction %v4float None %86
     %plane_0 = OpFunctionParameter %8
     %plane_1 = OpFunctionParameter %8
      %params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2uint
-         %81 = OpLabel
-         %82 = OpCompositeExtract %uint %params 1
-         %83 = OpCompositeExtract %mat3v4float %params 2
-         %84 = OpCompositeExtract %mat3v2float %params 7
-         %85 = OpCompositeExtract %v2uint %params 12
-         %86 = OpCompositeExtract %v2float %params 13
-         %87 = OpExtInst %v2uint %88 UMin %coords %85
-         %89 = OpConvertUToF %v2float %87
-         %90 = OpCompositeConstruct %v3float %89 %float_1
-         %92 = OpMatrixTimesVector %v2float %84 %90
-         %93 = OpExtInst %v2float %88 RoundEven %92
-         %94 = OpConvertFToU %v2uint %93
-         %95 = OpCompositeExtract %uint %params 0
-         %96 = OpIEqual %bool %95 %uint_1
-               OpSelectionMerge %98 None
-               OpBranchConditional %96 %99 %100
-         %99 = OpLabel
-        %101 = OpImageFetch %v4float %plane_0 %94 Lod %uint_0
-        %102 = OpVectorShuffle %v3float %101 %101 0 1 2
-        %103 = OpCompositeExtract %float %101 3
-               OpBranch %98
-        %100 = OpLabel
-        %104 = OpImageFetch %v4float %plane_0 %94 Lod %uint_0
-        %105 = OpCompositeExtract %float %104 0
-        %106 = OpFMul %v2float %93 %86
-        %107 = OpConvertFToU %v2uint %106
-        %108 = OpImageFetch %v4float %plane_1 %107 Lod %uint_0
-        %109 = OpVectorShuffle %v2float %108 %108 0 1
-        %110 = OpCompositeConstruct %v4float %105 %109 %float_1
-        %111 = OpVectorTimesMatrix %v3float %110 %83
-               OpBranch %98
-         %98 = OpLabel
-        %112 = OpPhi %v3float %102 %99 %111 %100
-        %113 = OpPhi %float %103 %99 %float_1 %100
-        %114 = OpIEqual %bool %82 %uint_0
-               OpSelectionMerge %115 None
-               OpBranchConditional %114 %116 %117
-        %116 = OpLabel
-        %118 = OpCompositeExtract %tint_GammaTransferParams %params 3
-        %119 = OpCompositeExtract %tint_GammaTransferParams %params 4
-        %120 = OpCompositeExtract %mat3v3float %params 5
-        %121 = OpFunctionCall %v3float %tint_GammaCorrection %112 %118
-        %123 = OpMatrixTimesVector %v3float %120 %121
-        %124 = OpFunctionCall %v3float %tint_GammaCorrection %123 %119
-               OpBranch %115
-        %117 = OpLabel
-               OpBranch %115
-        %115 = OpLabel
-        %125 = OpPhi %v3float %124 %116 %112 %117
-        %126 = OpCompositeConstruct %v4float %125 %113
-               OpReturnValue %126
+         %87 = OpLabel
+         %88 = OpCompositeExtract %uint %params 1
+         %89 = OpCompositeExtract %mat3v4float %params 2
+         %90 = OpCompositeExtract %mat3v2float %params 7
+         %91 = OpCompositeExtract %v2uint %params 12
+         %92 = OpCompositeExtract %v2float %params 13
+         %93 = OpExtInst %v2uint %53 UMin %coords %91
+         %94 = OpConvertUToF %v2float %93
+         %95 = OpCompositeConstruct %v3float %94 %float_1
+         %97 = OpMatrixTimesVector %v2float %90 %95
+         %98 = OpExtInst %v2float %53 RoundEven %97
+         %99 = OpConvertFToU %v2uint %98
+        %100 = OpCompositeExtract %uint %params 0
+        %101 = OpIEqual %bool %100 %uint_1
+               OpSelectionMerge %103 None
+               OpBranchConditional %101 %104 %105
+        %104 = OpLabel
+        %106 = OpImageFetch %v4float %plane_0 %99 Lod %uint_0
+        %107 = OpVectorShuffle %v3float %106 %106 0 1 2
+        %108 = OpCompositeExtract %float %106 3
+               OpBranch %103
+        %105 = OpLabel
+        %109 = OpImageFetch %v4float %plane_0 %99 Lod %uint_0
+        %110 = OpCompositeExtract %float %109 0
+        %111 = OpFMul %v2float %98 %92
+        %112 = OpConvertFToU %v2uint %111
+        %113 = OpImageFetch %v4float %plane_1 %112 Lod %uint_0
+        %114 = OpVectorShuffle %v2float %113 %113 0 1
+        %115 = OpCompositeConstruct %v4float %110 %114 %float_1
+        %116 = OpVectorTimesMatrix %v3float %115 %89
+               OpBranch %103
+        %103 = OpLabel
+        %117 = OpPhi %v3float %107 %104 %116 %105
+        %118 = OpPhi %float %108 %104 %float_1 %105
+        %119 = OpIEqual %bool %88 %uint_0
+               OpSelectionMerge %120 None
+               OpBranchConditional %119 %121 %122
+        %121 = OpLabel
+        %123 = OpCompositeExtract %tint_GammaTransferParams %params 3
+        %124 = OpCompositeExtract %tint_GammaTransferParams %params 4
+        %125 = OpCompositeExtract %mat3v3float %params 5
+        %126 = OpFunctionCall %v3float %tint_GammaCorrection %117 %123
+        %128 = OpMatrixTimesVector %v3float %125 %126
+        %129 = OpFunctionCall %v3float %tint_GammaCorrection %128 %124
+               OpBranch %120
+        %122 = OpLabel
+               OpBranch %120
+        %120 = OpLabel
+        %130 = OpPhi %v3float %129 %121 %117 %122
+        %131 = OpCompositeConstruct %v4float %130 %118
+               OpReturnValue %131
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %129
+%tint_GammaCorrection = OpFunction %v3float None %134
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-        %130 = OpLabel
-        %131 = OpCompositeExtract %float %params_0 0
-        %132 = OpCompositeExtract %float %params_0 1
-        %133 = OpCompositeExtract %float %params_0 2
-        %134 = OpCompositeExtract %float %params_0 3
-        %135 = OpCompositeExtract %float %params_0 4
-        %136 = OpCompositeExtract %float %params_0 5
-        %137 = OpCompositeExtract %float %params_0 6
-        %138 = OpCompositeConstruct %v3float %131 %131 %131
-        %139 = OpCompositeConstruct %v3float %135 %135 %135
-        %140 = OpExtInst %v3float %88 FAbs %v
-        %141 = OpExtInst %v3float %88 FSign %v
-        %142 = OpFOrdLessThan %v3bool %140 %139
-        %144 = OpVectorTimesScalar %v3float %140 %134
-        %145 = OpCompositeConstruct %v3float %137 %137 %137
-        %146 = OpFAdd %v3float %144 %145
-        %147 = OpFMul %v3float %141 %146
-        %148 = OpVectorTimesScalar %v3float %140 %132
-        %149 = OpCompositeConstruct %v3float %133 %133 %133
-        %150 = OpFAdd %v3float %148 %149
-        %151 = OpExtInst %v3float %88 Pow %150 %138
-        %152 = OpCompositeConstruct %v3float %136 %136 %136
-        %153 = OpFAdd %v3float %151 %152
-        %154 = OpFMul %v3float %141 %153
-        %155 = OpSelect %v3float %142 %147 %154
-               OpReturnValue %155
+        %135 = OpLabel
+        %136 = OpCompositeExtract %float %params_0 0
+        %137 = OpCompositeExtract %float %params_0 1
+        %138 = OpCompositeExtract %float %params_0 2
+        %139 = OpCompositeExtract %float %params_0 3
+        %140 = OpCompositeExtract %float %params_0 4
+        %141 = OpCompositeExtract %float %params_0 5
+        %142 = OpCompositeExtract %float %params_0 6
+        %143 = OpCompositeConstruct %v3float %136 %136 %136
+        %144 = OpCompositeConstruct %v3float %140 %140 %140
+        %145 = OpExtInst %v3float %53 FAbs %v
+        %146 = OpExtInst %v3float %53 FSign %v
+        %147 = OpFOrdLessThan %v3bool %145 %144
+        %149 = OpVectorTimesScalar %v3float %145 %139
+        %150 = OpCompositeConstruct %v3float %142 %142 %142
+        %151 = OpFAdd %v3float %149 %150
+        %152 = OpFMul %v3float %146 %151
+        %153 = OpVectorTimesScalar %v3float %145 %137
+        %154 = OpCompositeConstruct %v3float %138 %138 %138
+        %155 = OpFAdd %v3float %153 %154
+        %156 = OpExtInst %v3float %53 Pow %155 %143
+        %157 = OpCompositeConstruct %v3float %141 %141 %141
+        %158 = OpFAdd %v3float %156 %157
+        %159 = OpFMul %v3float %146 %158
+        %160 = OpSelect %v3float %147 %152 %159
+               OpReturnValue %160
                OpFunctionEnd
-%vertex_main = OpFunction %void None %54
-        %157 = OpLabel
-        %158 = OpFunctionCall %VertexOutput %vertex_main_inner
-        %159 = OpCompositeExtract %v4float %158 0
-               OpStore %vertex_main_position_Output %159 None
-        %160 = OpCompositeExtract %v4float %158 1
-               OpStore %vertex_main_loc0_Output %160 None
+%vertex_main = OpFunction %void None %61
+        %162 = OpLabel
+        %163 = OpFunctionCall %VertexOutput %vertex_main_inner
+        %164 = OpCompositeExtract %v4float %163 0
+               OpStore %vertex_main_position_Output %164 None
+        %165 = OpCompositeExtract %v4float %163 1
+               OpStore %vertex_main_loc0_Output %165 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %162
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %167
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %163 = OpLabel
-        %164 = OpCompositeExtract %uint %tint_input 0
-        %165 = OpCompositeExtract %uint %tint_input 1
-        %166 = OpCompositeExtract %mat3v4float %tint_input 2
-        %167 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %168 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %169 = OpCompositeExtract %v3float %tint_input 5
-        %170 = OpCompositeExtract %v3float %tint_input 6
-        %171 = OpCompositeExtract %v3float %tint_input 7
-        %172 = OpCompositeConstruct %mat3v3float %169 %170 %171
-        %173 = OpCompositeExtract %v2float %tint_input 8
-        %174 = OpCompositeExtract %v2float %tint_input 9
-        %175 = OpCompositeExtract %v2float %tint_input 10
-        %176 = OpCompositeConstruct %mat3v2float %173 %174 %175
-        %177 = OpCompositeExtract %v2float %tint_input 11
-        %178 = OpCompositeExtract %v2float %tint_input 12
-        %179 = OpCompositeExtract %v2float %tint_input 13
-        %180 = OpCompositeConstruct %mat3v2float %177 %178 %179
-        %181 = OpCompositeExtract %v2float %tint_input 14
-        %182 = OpCompositeExtract %v2float %tint_input 15
-        %183 = OpCompositeExtract %v2float %tint_input 16
-        %184 = OpCompositeExtract %v2float %tint_input 17
-        %185 = OpCompositeExtract %v2uint %tint_input 18
-        %186 = OpCompositeExtract %v2float %tint_input 19
-        %187 = OpCompositeConstruct %tint_ExternalTextureParams %164 %165 %166 %167 %168 %172 %176 %180 %181 %182 %183 %184 %185 %186
-               OpReturnValue %187
+        %168 = OpLabel
+        %169 = OpCompositeExtract %uint %tint_input 0
+        %170 = OpCompositeExtract %uint %tint_input 1
+        %171 = OpCompositeExtract %mat3v4float %tint_input 2
+        %172 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %173 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %174 = OpCompositeExtract %v3float %tint_input 5
+        %175 = OpCompositeExtract %v3float %tint_input 6
+        %176 = OpCompositeExtract %v3float %tint_input 7
+        %177 = OpCompositeConstruct %mat3v3float %174 %175 %176
+        %178 = OpCompositeExtract %v2float %tint_input 8
+        %179 = OpCompositeExtract %v2float %tint_input 9
+        %180 = OpCompositeExtract %v2float %tint_input 10
+        %181 = OpCompositeConstruct %mat3v2float %178 %179 %180
+        %182 = OpCompositeExtract %v2float %tint_input 11
+        %183 = OpCompositeExtract %v2float %tint_input 12
+        %184 = OpCompositeExtract %v2float %tint_input 13
+        %185 = OpCompositeConstruct %mat3v2float %182 %183 %184
+        %186 = OpCompositeExtract %v2float %tint_input 14
+        %187 = OpCompositeExtract %v2float %tint_input 15
+        %188 = OpCompositeExtract %v2float %tint_input 16
+        %189 = OpCompositeExtract %v2float %tint_input 17
+        %190 = OpCompositeExtract %v2uint %tint_input 18
+        %191 = OpCompositeExtract %v2float %tint_input 19
+        %192 = OpCompositeConstruct %tint_ExternalTextureParams %169 %170 %171 %172 %173 %177 %181 %185 %186 %187 %188 %189 %190 %191
+               OpReturnValue %192
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
index 7d1f0d6..f0ef182 100644
--- a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8b62fb() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
index 7d1f0d6..f0ef182 100644
--- a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8b62fb() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.msl
index bdefeeb..86e37c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_8b62fb(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.msl
index 9444746..1b492b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_8b62fb(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.spvasm
index 9fd31ca..a1490be 100644
--- a/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8b62fb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %27 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_8b62fb = OpFunction %v4float None %10
@@ -51,23 +53,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-         %21 = OpVectorShuffle %v4float %20 %20 2 1 0 3
-               OpStore %res %21
-         %24 = OpLoad %v4float %res None
-               OpReturnValue %24
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+         %25 = OpVectorShuffle %v4float %24 %24 2 1 0 3
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %27
-         %28 = OpLabel
-         %29 = OpFunctionCall %v4float %textureLoad_8b62fb
-         %30 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %30 %29 None
+%fragment_main = OpFunction %void None %31
+         %32 = OpLabel
+         %33 = OpFunctionCall %v4float %textureLoad_8b62fb
+         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %27
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_8b62fb
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_8b62fb
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.glsl
index 475ae0a5..f87e974 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_8bf8c2() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_8bf8c2() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
index 53a1df7..cb9215e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8bf8c2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
index 53a1df7..cb9215e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8bf8c2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.msl
index 41092b0..a79e96b 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_8bf8c2(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.msl
index 0a35641..4e9d490e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_8bf8c2(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.spvasm
index f34bc78..7ce6ff6f 100644
--- a/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8bf8c2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_8bf8c2 = OpFunction %v4float None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_8bf8c2
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_8bf8c2
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_8bf8c2
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_8bf8c2
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.glsl
index 8f47c7e..0ba41e8 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8c6176() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8c6176() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
index e4cf8f0..a49cb74 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8c6176() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
index e4cf8f0..a49cb74 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8c6176() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.msl
index 347cb54..7d90558 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_8c6176(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.msl
index 05598ce..7da7e80 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_8c6176(texture2d<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.spvasm
index 7508ac1..717fe41 100644
--- a/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8c6176.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %15 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_8c6176 = OpFunction %v4uint None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %20 = OpISub %v2uint %19 %15
+         %21 = OpExtInst %v2uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_8c6176
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_8c6176
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_8c6176
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_8c6176
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.glsl
index bba2c2f..8deae70 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_8ccbe3() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_8ccbe3() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  float res = texelFetch(arg_0, v_5, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_8ccbe3() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  float res = texelFetch(arg_0, v_4, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
index e3905bc..5977e96 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float textureLoad_8ccbe3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float res = arg_0.Load(int3(v_5, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ccbe3();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
index e3905bc..5977e96 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float textureLoad_8ccbe3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float res = arg_0.Load(int3(v_5, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ccbe3();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.msl
index 383b2a3..802c2d7 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float textureLoad_8ccbe3(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.msl
index 7d1e0ae..50ecba9 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_8ccbe3(depth2d<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.spvasm
index 97837ed..00ca0c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8ccbe3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,17 +65,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %37 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %49 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8ccbe3 = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +89,51 @@
          %27 = OpLoad %7 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-         %31 = OpCompositeExtract %float %30 0
-               OpStore %res %31
-         %34 = OpLoad %float %res None
-               OpReturnValue %34
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %29 %31
+         %34 = OpImageQuerySizeLod %v2uint %27 %32
+         %36 = OpISub %v2uint %34 %37
+         %38 = OpBitcast %v2uint %28
+         %39 = OpExtInst %v2uint %33 UMin %38 %36
+         %40 = OpImageFetch %v4float %27 %39 Lod %32
+         %41 = OpCompositeExtract %float %40 0
+               OpStore %res %41
+         %44 = OpLoad %float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_8ccbe3
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %float %textureLoad_8ccbe3
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_8ccbe3
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %float %textureLoad_8ccbe3
+         %56 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_8ccbe3
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %68 = OpFunctionCall %float %textureLoad_8ccbe3
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.glsl
index 9746096..4525987 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8d64c3() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_8d64c3() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
index 97ffb1a..dc001a3 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8d64c3() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
index 97ffb1a..dc001a3 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_8d64c3() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.msl
index d57d1b5..dd1aed1 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_8d64c3(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.msl
index 55074cd..4107949 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_8d64c3(texture2d<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.spvasm
index 54b4887..deb709a 100644
--- a/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8d64c3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,9 +42,12 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_8d64c3 = OpFunction %v4uint None %10
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %19
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_8d64c3
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_8d64c3
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_8d64c3
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_8d64c3
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.glsl
index 93b4d2a..45f1adb 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_8db0ce() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_8db0ce() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_8db0ce() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
index ba1cf85..3cb7e0c 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_8db0ce() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8db0ce();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
index ba1cf85..3cb7e0c 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_8db0ce() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8db0ce();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.msl
index 8fa2bba..ee46518 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_8db0ce(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.msl
index cc3725c..9b43c0e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_8db0ce(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.spvasm
index 09f60f0..66cb029 100644
--- a/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8db0ce.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,15 +70,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8db0ce = OpFunction %v4int None %18
          %19 = OpLabel
@@ -88,44 +90,52 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %32 = OpCompositeConstruct %v3uint %29 %30
-         %33 = OpImageRead %v4int %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4int %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %30 %34
+         %37 = OpImageQuerySize %v3uint %28
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %24
+         %40 = OpExtInst %v2uint %36 UMin %29 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4int %28 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_8db0ce
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_8db0ce
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_8db0ce
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_8db0ce
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %60 = OpFunctionCall %v4int %textureLoad_8db0ce
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_8db0ce
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4int %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.glsl
index 08a453d..1f5408e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_8e5032() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_8e5032() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 uvec4 textureLoad_8e5032() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
index 957b16d..5fd01ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_8e5032() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8e5032();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
index 957b16d..5fd01ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_8e5032() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8e5032();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.msl
index 793524a..85e9cf7 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_8e5032(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.msl
index 42dfb39..fa6b715 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_8e5032(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.spvasm
index 12865aa..1765815 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8e5032.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,19 +68,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8e5032 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -90,44 +94,54 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %32 = OpCompositeConstruct %v3int %29 %30
-         %33 = OpImageRead %v4uint %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4uint %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %30
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %28
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %29
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4uint %28 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_8e5032
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_8e5032
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4uint %textureLoad_8e5032
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4uint %textureLoad_8e5032
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %74 = OpFunctionCall %v4uint %textureLoad_8e5032
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4uint %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
index f59b49f..1f2bbdb 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_8e68c9() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
index f59b49f..1f2bbdb 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_8e68c9() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.msl
index 428715b..249441f 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_8e68c9(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.msl
index 5d14b80..8372ef9 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_8e68c9(texture3d<int, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.spvasm
index 9835fe3..1fe7f5e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8e68c9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_8e68c9 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_8e68c9
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_8e68c9
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_8e68c9
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_8e68c9
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
index 6612cc3..a69a807 100644
--- a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8fc29b() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
index 6612cc3..a69a807 100644
--- a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_8fc29b() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.msl
index 673ffd2..528d9e8 100644
--- a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_8fc29b(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.msl
index fdf6296..4e1c8d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_8fc29b(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.spvasm
index 1fe12ae..884f294 100644
--- a/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8fc29b.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_8fc29b = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_8fc29b
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_8fc29b
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_8fc29b
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.glsl
index 787ee43..3acc083 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_8ff033() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_8ff033() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_8ff033() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
index 59e5072..03ba36d 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8ff033() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ff033();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
index 59e5072..03ba36d 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_8ff033() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_8ff033();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.msl
index dda9253..9b21a1e 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_8ff033(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.msl
index d112e16..bf18be7 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_8ff033(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.spvasm
index d450c84..f1a230c 100644
--- a/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/8ff033.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_8ff033 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_8ff033
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_8ff033
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_8ff033
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_8ff033
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_8ff033
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_8ff033
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.glsl
index c2098d4..b77cb96 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_91ede5() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp image3D arg_0;
 vec4 textureLoad_91ede5() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
index 1cf296d..4edc670 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_91ede5() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
index 1cf296d..4edc670 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_91ede5() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.msl
index 9744d23..49c32c3 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_91ede5(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.msl
index ee6fc10..0a53fc6 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_91ede5(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.spvasm
index 7778385..3ceabb9 100644
--- a/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/91ede5.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_91ede5 = OpFunction %v4float None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_91ede5
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_91ede5
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_91ede5
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_91ede5
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
index ae1e6ac..1da6c73 100644
--- a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9242e7() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
index ae1e6ac..1da6c73 100644
--- a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9242e7() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.msl
index ad17728..b14e937 100644
--- a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_9242e7(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.msl
index 0f28056..2276240 100644
--- a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_9242e7(texture2d<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.spvasm
index b38d5c5..8ee2937 100644
--- a/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9242e7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9242e7 = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %20 = OpISub %v2uint %19 %15
+         %21 = OpExtInst %v2uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_9242e7
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_9242e7
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_9242e7
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_9242e7
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.glsl
index 22afac5..702a70f 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_92dd61() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_92dd61() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
index 3a7a10a..50fdb3d 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_92dd61() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
index 3a7a10a..50fdb3d 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_92dd61() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.msl
index 41fdd4e..2cf9d9c 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_92dd61(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.msl
index 8fcefad..d608329 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_92dd61(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.spvasm
index 13264b4..6545dfe 100644
--- a/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/92dd61.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_92dd61 = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_92dd61
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_92dd61
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_92dd61
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_92dd61
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.glsl
index 52e7d09..152a6d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_92eb1f() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_92eb1f() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_92eb1f() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec3 v_4 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
index 88fc052..884b14f 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_92eb1f() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_92eb1f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
index 88fc052..884b14f 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_92eb1f() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_92eb1f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.msl
index 7677249..055f09b 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_92eb1f(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.msl
index af5607b..b8292f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_92eb1f(texture3d<uint, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.spvasm
index 11438d6..c14436b 100644
--- a/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/92eb1f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_92eb1f = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +89,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v3uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %31
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySizeLod %v3uint %29 %35
+         %38 = OpISub %v3uint %37 %23
+         %39 = OpExtInst %v3uint %36 UMin %30 %38
+         %40 = OpImageFetch %v4uint %29 %39 Lod %35
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_92eb1f
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_92eb1f
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_92eb1f
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_92eb1f
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_92eb1f
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_92eb1f
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.glsl
index 8654c6a..d4fee3d 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_936952() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_936952() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_936952() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
index 0c13de0..b92c4e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_936952() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_936952();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
index 0c13de0..b92c4e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_936952() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_936952();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.msl
index 426f6b8..6f34d56 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_936952(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.msl
index ad4e52c..2a942ec 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_936952(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.spvasm
index 4d6a090..07fde04 100644
--- a/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/936952.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_936952 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,44 +90,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_936952
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_936952
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_936952
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_936952
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_936952
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_936952
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.glsl
index 3007d17..456b2c1 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_93f23e() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_93f23e() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
index 6d6bb81..1419826 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_93f23e() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
index 6d6bb81..1419826 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_93f23e() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.msl
index e0e83d3..686784b 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_93f23e(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.msl
index 71de923..81f9b93 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_93f23e(texture2d<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.spvasm
index b86224e..63c2144 100644
--- a/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/93f23e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_93f23e = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %20 = OpISub %v2uint %19 %15
+         %21 = OpExtInst %v2uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_93f23e
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_93f23e
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_93f23e
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_93f23e
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.glsl
index 0b2253e..f025365 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_947107() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_947107() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_947107() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
index 57a7aee..fd046a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_947107() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_947107();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
index 57a7aee..fd046a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_947107() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_947107();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.msl
index 2bec44b..3ee779b 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_947107(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.msl
index 37253c8..a983875 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_947107(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.spvasm
index 30e72ee..c568008 100644
--- a/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/947107.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_947107 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +82,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_947107
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_947107
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_947107
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_947107
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_947107
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.glsl
index e2784fd..b24c38c 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.glsl
@@ -2,20 +2,32 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_96efd5() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  vec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +35,32 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_96efd5() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  vec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +70,33 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_96efd5() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_6 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_4));
+  vec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +106,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
index 5c236db..748f282 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_96efd5();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
index 5c236db..748f282 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_96efd5();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.msl
index 2a22c29..585c62e 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.msl
index ba29c2b..06a622d 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.spvasm
index 969d8a7..e47137e 100644
--- a/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/96efd5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,16 +65,16 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %50 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
-         %56 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_96efd5 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -87,44 +89,55 @@
          %27 = OpLoad %v2uint %arg_1 None
          %28 = OpLoad %uint %arg_2 None
          %29 = OpLoad %uint %arg_3 None
-         %31 = OpCompositeConstruct %v3uint %27 %28
-         %32 = OpImageFetch %v4float %26 %31 Lod %29
-               OpStore %res %32
-         %35 = OpLoad %v4float %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySizeLod %v3uint %26 %uint_0
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %28 %34
+         %37 = OpImageQueryLevels %uint %26
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpExtInst %uint %36 UMin %29 %38
+         %40 = OpImageQuerySizeLod %v3uint %26 %39
+         %41 = OpVectorShuffle %v2uint %40 %40 0 1
+         %42 = OpISub %v2uint %41 %21
+         %43 = OpExtInst %v2uint %36 UMin %27 %42
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageFetch %v4float %26 %44 Lod %39
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_96efd5
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_96efd5
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4float %textureLoad_96efd5
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %47 %46 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+%compute_main = OpFunction %void None %51
+         %57 = OpLabel
          %58 = OpFunctionCall %v4float %textureLoad_96efd5
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_96efd5
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %51
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.glsl
index cba0b22..96149bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_970308() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_970308() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_970308() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
index 096d390..6c2f935 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_970308() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_970308();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
index 096d390..6c2f935 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_970308() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_970308();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.msl
index adba428..89cc3fb 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_970308(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.msl
index e550ce9..549ee4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_970308(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.spvasm
index 2a7c3cd..b1624f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/970308.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_970308 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4uint %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_970308
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_970308
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_970308
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_970308
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_970308
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_970308
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.glsl
index 90752a5..5942104 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.glsl
@@ -2,20 +2,32 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9885b0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +35,32 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9885b0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +70,33 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9885b0() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_6 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u))));
+  ivec3 v_7 = ivec3(v_6, int(v_4));
+  ivec4 res = texelFetch(arg_0, v_7, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +106,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_8 = vertex_main_inner();
+  gl_Position = v_8.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_8.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
index 28a0c50..e094d97 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9885b0();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
index 28a0c50..e094d97 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9885b0();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.msl
index eb13ccf..bf9e0fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.msl
index 7a79412..8e5f63b 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.spvasm
index 3d734d0..cf8a017 100644
--- a/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9885b0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,17 +68,17 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %54 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9885b0 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -91,44 +93,55 @@
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %uint %arg_2 None
          %32 = OpLoad %uint %arg_3 None
-         %34 = OpCompositeConstruct %v3uint %30 %31
-         %35 = OpImageFetch %v4int %29 %34 Lod %32
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpExtInst %uint %39 UMin %31 %37
+         %40 = OpImageQueryLevels %uint %29
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpExtInst %uint %39 UMin %32 %41
+         %43 = OpImageQuerySizeLod %v3uint %29 %42
+         %44 = OpVectorShuffle %v2uint %43 %43 0 1
+         %45 = OpISub %v2uint %44 %24
+         %46 = OpExtInst %v2uint %39 UMin %30 %45
+         %47 = OpCompositeConstruct %v3uint %46 %38
+         %48 = OpImageFetch %v4int %29 %47 Lod %42
+               OpStore %res %48
+         %51 = OpLoad %v4int %res None
+               OpReturnValue %51
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9885b0
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %54
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_9885b0
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_9885b0
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %54
+         %60 = OpLabel
+         %61 = OpFunctionCall %v4int %textureLoad_9885b0
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_9885b0
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_9885b0
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %54
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.glsl
index 5ea7f9b..f0f9842 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_99d8fa() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp image3D arg_0;
 vec4 textureLoad_99d8fa() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
index fc2b994..c0bf179 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_99d8fa() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
index fc2b994..c0bf179 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_99d8fa() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.msl
index 6c13759..a0acaf9 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_99d8fa(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.msl
index 65accce..b5e812f 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_99d8fa(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.spvasm
index 6344903..79b4b12 100644
--- a/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/99d8fa.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,11 +42,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_99d8fa = OpFunction %v4float None %10
          %11 = OpLabel
@@ -53,22 +58,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_99d8fa
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_99d8fa
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_99d8fa
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_99d8fa
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.glsl
index e386af1..73b720e 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_9a7c90() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_9a7c90() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_9a7c90() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
index 5048286..c0edcaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9a7c90() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a7c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
index 5048286..c0edcaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_9a7c90() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a7c90();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.msl
index d04c79a..96e92db 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_9a7c90(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.msl
index dd9d605..2d8104a 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9a7c90(texture3d<uint, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.spvasm
index 5097843..490ed7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9a7c90.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9a7c90 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %30 = OpISub %v3uint %28 %31
+         %33 = OpBitcast %v3uint %27
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_9a7c90
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_9a7c90
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_9a7c90
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_9a7c90
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_9a7c90
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_9a7c90
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.glsl
index c4e88f1..ada001d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_9a8c1e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_9a8c1e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_9a8c1e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
index 43953fc..5db09af 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9a8c1e() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a8c1e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
index 43953fc..5db09af 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9a8c1e() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9a8c1e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.msl
index d5e8a0a..1eac548 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_9a8c1e(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.msl
index a869bbf..4cb9e5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9a8c1e(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.spvasm
index fd6e4ce..9636df3 100644
--- a/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9a8c1e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9a8c1e = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %24
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4int %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4int %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9a8c1e
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_9a8c1e
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_9a8c1e
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4int %textureLoad_9a8c1e
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_9a8c1e
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %71 = OpFunctionCall %v4int %textureLoad_9a8c1e
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4int %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.glsl
index 19bfc39..dae04a1 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_9aa733() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_9aa733() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9aa733() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
index 3df0f40..8a70af8 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9aa733() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9aa733();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
index 3df0f40..8a70af8 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9aa733() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9aa733();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.msl
index 6c897ef..5218631 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_9aa733(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.msl
index 40b3e96..43b1f5d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.msl
@@ -4,7 +4,8 @@
 int4 textureLoad_9aa733(texture2d<int, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.spvasm
index 7197db7..8475b14 100644
--- a/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9aa733.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9aa733 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +89,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %31
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySizeLod %v2uint %29 %35
+         %38 = OpISub %v2uint %37 %24
+         %39 = OpExtInst %v2uint %36 UMin %30 %38
+         %40 = OpImageFetch %v4int %29 %39 Lod %35
+               OpStore %res %40
+         %43 = OpLoad %v4int %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_9aa733
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_9aa733
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_9aa733
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_9aa733
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_9aa733
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %67 = OpFunctionCall %v4int %textureLoad_9aa733
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4int %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.glsl
index e89d087..c2b2fee 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.glsl
@@ -2,20 +2,35 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_9b2667() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  float res = texelFetch(arg_0, v_11, int(v_8)).x;
   return res;
 }
 void main() {
@@ -23,20 +38,35 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_9b2667() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  uvec2 v_9 = (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u));
+  ivec2 v_10 = ivec2(min(uvec2(v_2), v_9));
+  ivec3 v_11 = ivec3(v_10, int(v_6));
+  float res = texelFetch(arg_0, v_11, int(v_8)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +76,36 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_9b2667() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_1), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  float res = texelFetch(arg_0, v_10, int(v_7)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +115,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_11 = vertex_main_inner();
+  gl_Position = v_11.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_11.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
index 4e4d4aa..c830099 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  float res = arg_0.Load(int4(v_8, v_9, int(v_5))).x;
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b2667();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
index 4e4d4aa..c830099 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,20 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  int2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  uint2 v_7 = (v_6.xy - (1u).xx);
+  int2 v_8 = int2(min(uint2(v), v_7));
+  int v_9 = int(v_3);
+  float res = arg_0.Load(int4(v_8, v_9, int(v_5))).x;
   return res;
 }
 
@@ -36,13 +45,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b2667();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_10 = tint_symbol;
+  return v_10;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_11 = vertex_main_inner();
+  vertex_main_outputs v_12 = {v_11.prevent_dce, v_11.pos};
+  return v_12;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.msl
index 13f9ede..03be24a 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.ir.msl
@@ -20,9 +20,12 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  int const v = arg_2;
+  int2 const v = arg_1;
   int const v_1 = arg_3;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_4 = (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_4), v_2, v_3);
   return res;
 }
 
@@ -45,9 +48,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_5 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_5.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_5.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.msl
index 9e25aeb..d7728b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_9b2667(depth2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   int arg_3 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.spvasm
index 062b71a..abba050 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9b2667.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,20 +64,22 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %52 = OpTypeFunction %VertexOutput
+         %70 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %56 = OpConstantNull %VertexOutput
+         %74 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %59 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %77 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9b2667 = OpFunction %float None %15
          %16 = OpLabel
@@ -90,45 +94,59 @@
          %27 = OpLoad %v2int %arg_1 None
          %28 = OpLoad %int %arg_2 None
          %29 = OpLoad %int %arg_3 None
-         %31 = OpCompositeConstruct %v3int %27 %28
-         %32 = OpImageFetch %v4float %26 %31 Lod %29
-         %33 = OpCompositeExtract %float %32 0
-               OpStore %res %33
-         %36 = OpLoad %float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySizeLod %v3uint %26 %uint_0
+         %34 = OpCompositeExtract %uint %30 2
+         %35 = OpISub %uint %34 %uint_1
+         %37 = OpBitcast %uint %28
+         %38 = OpExtInst %uint %39 UMin %37 %35
+         %40 = OpImageQueryLevels %uint %26
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %29
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %26 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %27
+         %50 = OpExtInst %v2uint %39 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %38
+         %52 = OpImageFetch %v4float %26 %51 Lod %43
+         %53 = OpCompositeExtract %float %52 0
+               OpStore %res %53
+         %56 = OpLoad %float %res None
+               OpReturnValue %56
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %float %textureLoad_9b2667
-         %42 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpFunctionCall %float %textureLoad_9b2667
+         %62 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %62 %61 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %47 = OpLabel
-         %48 = OpFunctionCall %float %textureLoad_9b2667
-         %49 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %49 %48 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %52
-         %53 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %56
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %57 %59 None
-         %60 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %62 = OpFunctionCall %float %textureLoad_9b2667
-               OpStore %60 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %39
+%compute_main = OpFunction %void None %59
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %float %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+         %66 = OpFunctionCall %float %textureLoad_9b2667
+         %67 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %67 %66 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %70
+         %71 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %74
+         %75 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %75 %77 None
+         %78 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %79 = OpFunctionCall %float %textureLoad_9b2667
+               OpStore %78 %79 None
+         %80 = OpLoad %VertexOutput %out None
+               OpReturnValue %80
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %59
+         %82 = OpLabel
+         %83 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %84 = OpCompositeExtract %v4float %83 0
+               OpStore %vertex_main_position_Output %84 None
+         %85 = OpCompositeExtract %float %83 1
+               OpStore %vertex_main_loc0_Output %85 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.glsl
index da2f051..f06c67f 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_9b5343() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_9b5343() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_9b5343() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
index 2619217..9e71eea 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_9b5343() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b5343();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
index 2619217..9e71eea 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_9b5343() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9b5343();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.msl
index af8be03..deb2c85 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_9b5343(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.msl
index 4f5c26f..55d638a 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9b5343(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.spvasm
index c6c9512..cd17253 100644
--- a/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9b5343.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9b5343 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %23
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4uint %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_9b5343
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_9b5343
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_9b5343
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_9b5343
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_9b5343
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_9b5343
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.glsl
index d0698ac..c5260b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_9c2376() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_9c2376() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_9c2376() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
index b45a5ab..12daade 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_9c2376() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2376();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
index b45a5ab..12daade 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_9c2376() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2376();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.msl
index 827be21..db5cbe7 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_9c2376(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.msl
index b0fa764..2c26c72 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9c2376(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.spvasm
index 842f032..170a1b6 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9c2376.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9c2376 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_9c2376
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_9c2376
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_9c2376
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_9c2376
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_9c2376
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_9c2376
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.glsl
index f5e85cc..a4f3ed8 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_9c2a14() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_9c2a14() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_9c2a14() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
index ec21abd..99ff10d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2a14() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2a14();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
index ec21abd..99ff10d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_9c2a14() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9c2a14();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.msl
index c15e3e3..d0a453d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_9c2a14(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.msl
index 5f19496..50bc940 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9c2a14(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.spvasm
index 9e8480c..ffddabf 100644
--- a/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9c2a14.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9c2a14 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -81,43 +85,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_9c2a14
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_9c2a14
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_9c2a14
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_9c2a14
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_9c2a14
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_9c2a14
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.glsl
index 0e0bce5..b2cdda1 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_9cf7df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_9cf7df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_9cf7df() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
index 0e4e16b..65c44fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9cf7df() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9cf7df();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
index 0e4e16b..65c44fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_9cf7df() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9cf7df();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.msl
index 58a77b6..176d2b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_9cf7df(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.msl
index c0dd6b7..9310fbe 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9cf7df(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.spvasm
index 75d02f5..b9f17bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9cf7df.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9cf7df = OpFunction %v4int None %18
          %19 = OpLabel
@@ -90,45 +94,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4int %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_9cf7df
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_9cf7df
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_9cf7df
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_9cf7df
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_9cf7df
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %73 = OpFunctionCall %v4int %textureLoad_9cf7df
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4int %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.glsl
index 49f3ef4..669494d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9d70e9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9d70e9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9d70e9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
index 19efd83..ac8074c 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9d70e9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
index 19efd83..ac8074c 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9d70e9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.msl
index 4c6811c..c9b9b1f 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int const v = arg_2;
+  int2 const v = arg_1;
   uint const v_1 = arg_3;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.msl
index b4c260e..3bde11a 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9d70e9(texture2d_array<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.spvasm
index 64cca85..98ba87f 100644
--- a/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9d70e9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %55 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9d70e9 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -93,44 +97,57 @@
          %32 = OpLoad %v2int %arg_1 None
          %33 = OpLoad %int %arg_2 None
          %34 = OpLoad %uint %arg_3 None
-         %36 = OpCompositeConstruct %v3int %32 %33
-         %37 = OpImageFetch %v4int %31 %36 Lod %34
-               OpStore %res %37
-         %40 = OpLoad %v4int %res None
-               OpReturnValue %40
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpBitcast %uint %33
+         %41 = OpExtInst %uint %42 UMin %40 %39
+         %43 = OpImageQueryLevels %uint %31
+         %44 = OpISub %uint %43 %uint_1
+         %45 = OpExtInst %uint %42 UMin %34 %44
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %32
+         %52 = OpExtInst %v2uint %42 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %41
+         %54 = OpImageFetch %v4int %31 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4int %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_9d70e9
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4int %textureLoad_9d70e9
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4int %textureLoad_9d70e9
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %60
+         %66 = OpLabel
+         %67 = OpFunctionCall %v4int %textureLoad_9d70e9
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %68 %67 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %64 = OpFunctionCall %v4int %textureLoad_9d70e9
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %80 = OpFunctionCall %v4int %textureLoad_9d70e9
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4int %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4int %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.glsl
index 1a8f510..53a2a44 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_9de6f5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_9de6f5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_9de6f5() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
index 073625b..9e701f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_9de6f5() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9de6f5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
index 073625b..9e701f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_9de6f5() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9de6f5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.msl
index d03d8c8..68d8b58 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_9de6f5(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.msl
index c7ce604..fb5bdc2 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_9de6f5(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.spvasm
index f73f5f7..6fce779 100644
--- a/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9de6f5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9de6f5 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_9de6f5
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_9de6f5
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_9de6f5
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_9de6f5
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_9de6f5
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_9de6f5
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.glsl
index 89234e3..c2f0cd5 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_9ed19e() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_4, int(v_3)).x;
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2D arg_0;
 float textureLoad_9ed19e() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_4, int(v_3)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_9ed19e() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
index b0db87a..1935334 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float textureLoad_9ed19e() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_4, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9ed19e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
index b0db87a..1935334 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float textureLoad_9ed19e() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(int3(v_1, int(v))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float res = arg_0.Load(int3(v_4, int(v_2))).x;
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9ed19e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.msl
index fac1549..95d03f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float textureLoad_9ed19e(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.msl
index 54f36f0..67e41b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float textureLoad_9ed19e(depth2d<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.spvasm
index 335cf69..2f6b5a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9ed19e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %35 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %47 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9ed19e = OpFunction %float None %15
          %16 = OpLabel
@@ -83,44 +85,50 @@
          %25 = OpLoad %7 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Lod %27
-         %29 = OpCompositeExtract %float %28 0
-               OpStore %res %29
-         %32 = OpLoad %float %res None
-               OpReturnValue %32
+         %28 = OpImageQueryLevels %uint %25
+         %29 = OpISub %uint %28 %uint_1
+         %30 = OpExtInst %uint %31 UMin %27 %29
+         %32 = OpImageQuerySizeLod %v2uint %25 %30
+         %33 = OpISub %v2uint %32 %21
+         %34 = OpExtInst %v2uint %31 UMin %26 %33
+         %35 = OpImageFetch %v4float %25 %34 Lod %30
+         %36 = OpCompositeExtract %float %35 0
+               OpStore %res %36
+         %39 = OpLoad %float %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %35
-         %36 = OpLabel
-         %37 = OpFunctionCall %float %textureLoad_9ed19e
-         %38 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %38 %37 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %float %textureLoad_9ed19e
+         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %35
-         %42 = OpLabel
-         %43 = OpFunctionCall %float %textureLoad_9ed19e
-         %44 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %float %textureLoad_9ed19e
+         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %54 None
-         %55 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %56 = OpFunctionCall %float %textureLoad_9ed19e
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %63 = OpFunctionCall %float %textureLoad_9ed19e
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %35
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %float %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
index 80e5d07..548a203 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fa9fd() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
index 80e5d07..548a203 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_9fa9fd() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.msl
index bdcfd6d..30b5689 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_9fa9fd(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.msl
index fc1879f..2dd934b 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_9fa9fd(texture3d<uint, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol.read(uint3(arg_1));
+  uint4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.spvasm
index 9c70e9a..262024d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9fa9fd.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9fa9fd = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %20 = OpISub %v3uint %19 %15
+         %21 = OpExtInst %v3uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_9fa9fd
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_9fa9fd
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_9fa9fd
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_9fa9fd
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.glsl
index 46fc95a..895142e 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9fbfd9() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_9fbfd9() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_2), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_9fbfd9() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_6 = (uvec2(textureSize(arg_0, int(v_5)).xy) - uvec2(1u));
+  ivec2 v_7 = ivec2(min(uvec2(v_1), v_6));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  ivec4 res = texelFetch(arg_0, v_8, int(v_5));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
index da52ae5..dd65305 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9fbfd9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
index da52ae5..dd65305 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint v = arg_2;
-  uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(arg_3, (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_9fbfd9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.msl
index 918358a..5e6fcdc 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  uint const v = arg_2;
-  uint const v_1 = arg_3;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(arg_3, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.msl
index d099961..2142997 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_9fbfd9(texture2d_array<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   uint arg_3 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.spvasm
index b49c164..6ae607f 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9fbfd9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 86
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %58 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %55 = OpTypeFunction %VertexOutput
+         %69 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %73 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %76 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_9fbfd9 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -92,45 +96,56 @@
          %31 = OpLoad %v2int %arg_1 None
          %32 = OpLoad %uint %arg_2 None
          %33 = OpLoad %uint %arg_3 None
-         %34 = OpBitcast %int %32
-         %36 = OpCompositeConstruct %v3int %31 %34
-         %37 = OpImageFetch %v4int %30 %36 Lod %33
-               OpStore %res %37
-         %40 = OpLoad %v4int %res None
-               OpReturnValue %40
+         %34 = OpImageQuerySizeLod %v3uint %30 %uint_0
+         %37 = OpCompositeExtract %uint %34 2
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpExtInst %uint %40 UMin %32 %38
+         %41 = OpImageQueryLevels %uint %30
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %33 %42
+         %44 = OpImageQuerySizeLod %v3uint %30 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %31
+         %50 = OpExtInst %v2uint %40 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %39
+         %52 = OpImageFetch %v4int %30 %51 Lod %43
+               OpStore %res %52
+         %55 = OpLoad %v4int %res None
+               OpReturnValue %55
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_9fbfd9
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %58
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_9fbfd9
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %v4int %textureLoad_9fbfd9
-         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %58
+         %64 = OpLabel
+         %65 = OpFunctionCall %v4int %textureLoad_9fbfd9
+         %66 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %66 %65 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %64 = OpFunctionCall %v4int %textureLoad_9fbfd9
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %69
+         %70 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %73
+         %74 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %74 %76 None
+         %77 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %78 = OpFunctionCall %v4int %textureLoad_9fbfd9
+               OpStore %77 %78 None
+         %79 = OpLoad %VertexOutput %out None
+               OpReturnValue %79
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %v4int %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %58
+         %81 = OpLabel
+         %82 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %83 = OpCompositeExtract %v4float %82 0
+               OpStore %vertex_main_position_Output %83 None
+         %84 = OpCompositeExtract %v4int %82 1
+               OpStore %vertex_main_loc0_Output %84 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
index 098951f..0349e6d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_9fd7be() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
index 098951f..0349e6d 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 uint4 textureLoad_9fd7be() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.msl
index 1a62467..d7d1544 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_9fd7be(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.msl
index 0afc621..8d41be9 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_9fd7be(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.spvasm
index e3f3c22..1b414fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/9fd7be.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,10 +43,13 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_9fd7be = OpFunction %v4uint None %10
@@ -57,23 +62,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4uint %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %22
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %20
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %21
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4uint %20 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_9fd7be
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_9fd7be
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_9fd7be
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_9fd7be
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.glsl
index a43601b..6b93117 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_a03af1() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_a03af1() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_a03af1() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
index 7c1ac8e..8c09a80 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_a03af1() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a03af1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
index 7c1ac8e..8c09a80 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_a03af1() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a03af1();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.msl
index 6beaee4..e5896a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_a03af1(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.msl
index 2e1fce0d..8750438 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a03af1(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.spvasm
index a5ca136..0d06f95 100644
--- a/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a03af1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,17 +66,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a03af1 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +90,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpBitcast %int %29
-         %32 = OpCompositeConstruct %v3int %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %35 UMin %41 %39
+         %43 = OpCompositeConstruct %v3uint %42 %34
+         %44 = OpImageRead %v4float %27 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4float %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_a03af1
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_a03af1
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_a03af1
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4float %textureLoad_a03af1
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_a03af1
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %70 = OpFunctionCall %v4float %textureLoad_a03af1
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %50
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4float %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.glsl
index 56ce371..f51db84 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_a24be1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2DArray arg_0;
 uvec4 textureLoad_a24be1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_6));
+  uvec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2DArray arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_a24be1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_5));
+  uvec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
index 6105d8f..7fbe6cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a24be1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
index 6105d8f..7fbe6cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  uint2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  uint4 res = uint4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_3);
+  uint4 res = uint4(arg_0.Load(int4(v_6, v_7, int(min(v_1, (v_4.w - 1u))))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a24be1();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.msl
index 23994d1..fee2748 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u))), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.msl
index 2b9ca96..bbb805e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a24be1(texture2d_array<uint, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.spvasm
index fa941f2..02b7d94 100644
--- a/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a24be1.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 73
+; Bound: 85
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,17 +70,17 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %44 = OpTypeFunction %void
+         %57 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %56 = OpTypeFunction %VertexOutput
+         %68 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %60 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %63 = OpConstantNull %v4float
+         %75 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a24be1 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -93,45 +95,56 @@
          %32 = OpLoad %v2uint %arg_1 None
          %33 = OpLoad %int %arg_2 None
          %34 = OpLoad %uint %arg_3 None
-         %35 = OpBitcast %uint %33
-         %37 = OpCompositeConstruct %v3uint %32 %35
-         %38 = OpImageFetch %v4uint %31 %37 Lod %34
-               OpStore %res %38
-         %41 = OpLoad %v4uint %res None
-               OpReturnValue %41
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpBitcast %uint %33
+         %41 = OpExtInst %uint %42 UMin %40 %39
+         %43 = OpImageQueryLevels %uint %31
+         %44 = OpISub %uint %43 %uint_1
+         %45 = OpExtInst %uint %42 UMin %34 %44
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %48 = OpISub %v2uint %47 %23
+         %49 = OpExtInst %v2uint %42 UMin %32 %48
+         %50 = OpCompositeConstruct %v3uint %49 %41
+         %51 = OpImageFetch %v4uint %31 %50 Lod %45
+               OpStore %res %51
+         %54 = OpLoad %v4uint %res None
+               OpReturnValue %54
                OpFunctionEnd
-%fragment_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_a24be1
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%fragment_main = OpFunction %void None %57
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4uint %textureLoad_a24be1
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %51 = OpLabel
-         %52 = OpFunctionCall %v4uint %textureLoad_a24be1
-         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %53 %52 None
+%compute_main = OpFunction %void None %57
+         %63 = OpLabel
+         %64 = OpFunctionCall %v4uint %textureLoad_a24be1
+         %65 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %65 %64 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %56
-         %57 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %60
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %61 %63 None
-         %64 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %65 = OpFunctionCall %v4uint %textureLoad_a24be1
-               OpStore %64 %65 None
-         %66 = OpLoad %VertexOutput %out None
-               OpReturnValue %66
+%vertex_main_inner = OpFunction %VertexOutput None %68
+         %69 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %72
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %73 %75 None
+         %76 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %77 = OpFunctionCall %v4uint %textureLoad_a24be1
+               OpStore %76 %77 None
+         %78 = OpLoad %VertexOutput %out None
+               OpReturnValue %78
                OpFunctionEnd
-%vertex_main = OpFunction %void None %44
-         %68 = OpLabel
-         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %70 = OpCompositeExtract %v4float %69 0
-               OpStore %vertex_main_position_Output %70 None
-         %71 = OpCompositeExtract %v4uint %69 1
-               OpStore %vertex_main_loc0_Output %71 None
+%vertex_main = OpFunction %void None %57
+         %80 = OpLabel
+         %81 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %82 = OpCompositeExtract %v4float %81 0
+               OpStore %vertex_main_position_Output %82 None
+         %83 = OpCompositeExtract %v4uint %81 1
+               OpStore %vertex_main_loc0_Output %83 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
index 1b36f0b..355e63e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_a2b3f4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
index 1b36f0b..355e63e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_a2b3f4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.msl
index f3b550c..3128870 100644
--- a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_a2b3f4(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.msl
index 3e418da..691edaf 100644
--- a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_a2b3f4(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.spvasm
index 6342b52..b637920 100644
--- a/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a2b3f4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,7 +45,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a2b3f4 = OpFunction %v4uint None %10
@@ -56,23 +58,31 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2uint %arg_1 None
          %21 = OpLoad %uint %arg_2 None
-         %23 = OpCompositeConstruct %v3uint %20 %21
-         %24 = OpImageRead %v4uint %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %24 = OpCompositeExtract %uint %22 2
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %21 %25
+         %28 = OpImageQuerySize %v3uint %19
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %30 = OpISub %v2uint %29 %15
+         %31 = OpExtInst %v2uint %27 UMin %20 %30
+         %32 = OpCompositeConstruct %v3uint %31 %26
+         %33 = OpImageRead %v4uint %19 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_a2b3f4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_a2b3f4
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_a2b3f4
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_a2b3f4
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
index 979ea15..b39a4f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3733f() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
index 979ea15..b39a4f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a3733f() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.msl
index a05eda5..ac2ee71 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_a3733f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.msl
index 48bd892..6571af85c 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a3733f(texture2d<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.spvasm
index 99b6e7e..042eea8 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a3733f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,12 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a3733f = OpFunction %v4uint None %10
@@ -51,22 +56,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4uint %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4uint %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %22 = OpISub %v2uint %20 %23
+         %25 = OpBitcast %v2uint %19
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4uint %18 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4uint %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4uint %textureLoad_a3733f
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4uint %textureLoad_a3733f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4uint %textureLoad_a3733f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_a3733f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
index 5b9a2a7..783a0d0 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_a3f122() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
index 5b9a2a7..783a0d0 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 uint4 textureLoad_a3f122() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.msl
index e97dd0a..6ac92b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_a3f122(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.msl
index 4926ccd..9cdbd2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_a3f122(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.spvasm
index e079c25..e0a391b 100644
--- a/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a3f122.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 49
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,7 +45,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %39 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a3f122 = OpFunction %v4uint None %10
@@ -56,23 +58,31 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2uint %arg_1 None
          %21 = OpLoad %uint %arg_2 None
-         %23 = OpCompositeConstruct %v3uint %20 %21
-         %24 = OpImageRead %v4uint %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4uint %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %24 = OpCompositeExtract %uint %22 2
+         %25 = OpISub %uint %24 %uint_1
+         %26 = OpExtInst %uint %27 UMin %21 %25
+         %28 = OpImageQuerySize %v3uint %19
+         %29 = OpVectorShuffle %v2uint %28 %28 0 1
+         %30 = OpISub %v2uint %29 %15
+         %31 = OpExtInst %v2uint %27 UMin %20 %30
+         %32 = OpCompositeConstruct %v3uint %31 %26
+         %33 = OpImageRead %v4uint %19 %32 None
+               OpStore %res %33
+         %36 = OpLoad %v4uint %res None
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4uint %textureLoad_a3f122
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %39
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4uint %textureLoad_a3f122
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4uint %textureLoad_a3f122
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %39
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_a3f122
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
index 89cf5ce..4dcb118 100644
--- a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a548a8() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
index 89cf5ce..4dcb118 100644
--- a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a548a8() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.msl
index c8a9393..8a00483 100644
--- a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_a548a8(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.msl
index 65570e3..bda669e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a548a8(texture1d<uint, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.spvasm
index 163fffa..e872ce1 100644
--- a/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a548a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,9 +40,10 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a548a8 = OpFunction %v4uint None %10
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4uint %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %17
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4uint %16 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4uint %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_a548a8
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4uint %textureLoad_a548a8
          %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_a548a8
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
index c164c75..aaf5d06 100644
--- a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_a54e11() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
index c164c75..aaf5d06 100644
--- a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_a54e11() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.msl
index 5ece5de..b0ade54 100644
--- a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_a54e11(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.msl
index 7c0456d..01f6a5a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a54e11(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.spvasm
index 02e94e3..0bf054c 100644
--- a/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a54e11.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_a54e11 = OpFunction %v4int None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4int %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_a54e11
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_a54e11
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_a54e11
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_a54e11
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.glsl
index 379d917..70270b1 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_a583c9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_a583c9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_a583c9() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  vec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
index 80c7f3a..d5d7f8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float4 res = float4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a583c9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
index 80c7f3a..d5d7f8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float4 res = float4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a583c9();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.msl
index aa8da33..335d668 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_a583c9(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  int const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.msl
index 140641a..60f29320 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a583c9(texture2d_ms<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.spvasm
index 74a5ea9..9b9e904 100644
--- a/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a583c9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %32 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %47 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %51 = OpConstantNull %VertexOutput
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %59 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a583c9 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,47 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %28 = OpImageFetch %v4float %25 %26 Sample %27
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %25
+         %31 = OpISub %v2uint %28 %32
+         %34 = OpBitcast %v2uint %26
+         %35 = OpExtInst %v2uint %36 UMin %34 %31
+         %37 = OpImageFetch %v4float %25 %35 Sample %27
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_a583c9
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_a583c9
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_a583c9
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_a583c9
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %47
-         %48 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %51
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %52 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_a583c9
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %63 = OpFunctionCall %v4float %textureLoad_a583c9
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %43
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4float %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.glsl
index 689a50f..9b34082 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_a5c4e2() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_a5c4e2() {
   int arg_1 = 1;
-  uvec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
index 950564a..6e29d58 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a5c4e2() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
index 950564a..6e29d58 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_a5c4e2() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.msl
index 7dbb7ed..c78520e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_a5c4e2(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.msl
index 1d75879..275d3cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a5c4e2(texture1d<uint, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.spvasm
index 84163ff..7c80d2a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a5c4e2.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,9 +41,10 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_a5c4e2 = OpFunction %v4uint None %10
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4uint %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %17
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4uint %16 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4uint %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_a5c4e2
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4uint %textureLoad_a5c4e2
          %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_a5c4e2
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.glsl
index a21cf41..fb343b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_a5e0a5() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_a5e0a5() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
index 520a845..8a4b260 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a5e0a5() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
index 520a845..8a4b260 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a5e0a5() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.msl
index f3e88d4..d55910c 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_a5e0a5(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.msl
index 3632a64..0cfc178 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_a5e0a5(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.spvasm
index 2cec72d..26ef543 100644
--- a/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a5e0a5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a5e0a5 = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_a5e0a5
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_a5e0a5
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_a5e0a5
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_a5e0a5
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
index 5dd2ea2..7388ee8 100644
--- a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a64b1d() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
index 5dd2ea2..7388ee8 100644
--- a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a64b1d() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.msl
index a714d4d..3822501 100644
--- a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_a64b1d(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.msl
index 1e78bd2..db212fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_a64b1d(texture3d<float, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.spvasm
index 3a58f7d..796e9f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a64b1d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a64b1d = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_a64b1d
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_a64b1d
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_a64b1d
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_a64b1d
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.glsl
index aafe9f0..9f5de36 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a6a85a() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a6a85a() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a6a85a() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
index a0c3379..43c4754 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a6a85a() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6a85a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
index a0c3379..43c4754 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a6a85a() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6a85a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.msl
index ed4c227..50b57c0 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_a6a85a(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.msl
index b24a8e3..c867b26 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a6a85a(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.spvasm
index ce473f3..2c0630a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a6a85a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a6a85a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_a6a85a
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_a6a85a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_a6a85a
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_a6a85a
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_a6a85a
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_a6a85a
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.glsl
index 204a192..286eb2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_a6b61d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_a6b61d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 ivec4 textureLoad_a6b61d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
index e24a69a..298a5ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_a6b61d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6b61d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
index e24a69a..298a5ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_a6b61d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a6b61d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.msl
index 33e7629..58d8f76 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_a6b61d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.msl
index 93b6ff4..8dde3cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a6b61d(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.spvasm
index 1ceeb00..0f0bdf5 100644
--- a/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a6b61d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,20 +66,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a6b61d = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %31 = OpCompositeConstruct %v3int %28 %29
-         %32 = OpImageRead %v4int %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %29
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %27
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %28
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4int %27 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4int %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_a6b61d
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_a6b61d
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_a6b61d
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4int %textureLoad_a6b61d
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4int %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_a6b61d
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.glsl
index 2c78be2..f78d1d6 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_a7444c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_a7444c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_a7444c() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
index d2f30fe..4ff10d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_a7444c() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7444c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
index d2f30fe..4ff10d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_a7444c() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7444c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.msl
index 7136bfff..3966547 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_a7444c(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.msl
index 44198af..e481638 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_a7444c(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.spvasm
index afb8462..5235520 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a7444c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a7444c = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,44 +89,52 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %31 = OpCompositeConstruct %v3uint %28 %29
-         %32 = OpImageRead %v4uint %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %35 UMin %28 %38
+         %40 = OpCompositeConstruct %v3uint %39 %34
+         %41 = OpImageRead %v4uint %27 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_a7444c
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_a7444c
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_a7444c
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_a7444c
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_a7444c
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_a7444c
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.glsl
index 154b098..68eb9ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_a7a3c3() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_a7a3c3() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_a7a3c3() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
index 02ec661..b4d5133 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a7a3c3() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7a3c3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
index 02ec661..b4d5133 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_a7a3c3() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a7a3c3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.msl
index 248b541..59f19d0 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_a7a3c3(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.msl
index ecb0670..37556f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_a7a3c3(texture3d<int, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.spvasm
index 5b8554d..f8dae3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a7a3c3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a7a3c3 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %30 = OpISub %v3uint %27 %31
+         %33 = OpBitcast %v3uint %26
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_a7a3c3
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_a7a3c3
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_a7a3c3
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_a7a3c3
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_a7a3c3
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_a7a3c3
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
index 2a38c67..0899aa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a7bcb4() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
index 2a38c67..0899aa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_a7bcb4() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.msl
index b1ac145..4e6fb36 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_a7bcb4(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.msl
index c123829..8a868ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_a7bcb4(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.spvasm
index 9810ba6..cec7fae 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a7bcb4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a7bcb4 = OpFunction %v4float None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_a7bcb4
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_a7bcb4
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_a7bcb4
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_a7bcb4
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
index 024b65d..2f2b899 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a7c171() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
index 024b65d..2f2b899 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_a7c171() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.msl
index b575dd7..a07d486 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_a7c171(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.msl
index 0b72763..def108e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_a7c171(texture2d<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.spvasm
index 4af9fbc..258ace2 100644
--- a/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a7c171.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_a7c171 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_a7c171
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_a7c171
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_a7c171
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_a7c171
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.glsl
index 84e0d77..6e2e2fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a8549b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_a8549b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_a8549b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
index 31deb5f..1431ddb 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a8549b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a8549b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
index 31deb5f..1431ddb 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_a8549b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a8549b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.msl
index 0231372..8e0e745 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_a8549b(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.msl
index f33e1b3..714ca61 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_a8549b(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.spvasm
index f61e4e3..e998f96 100644
--- a/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a8549b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a8549b = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_a8549b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_a8549b
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_a8549b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_a8549b
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_a8549b
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_a8549b
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
index a8f886a..689c01d 100644
--- a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_a92b18() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
index a8f886a..689c01d 100644
--- a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_a92b18() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.msl
index 3820acc..9b3cf52 100644
--- a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_a92b18(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.msl
index 4ed66aa..30bef71 100644
--- a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_a92b18(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.spvasm
index be96952..824449e 100644
--- a/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a92b18.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_a92b18 = OpFunction %v4float None %10
@@ -59,24 +61,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_a92b18
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_a92b18
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_a92b18
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_a92b18
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.glsl
index 42fe690..62716b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_a9a9f5() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler3D arg_0;
 uvec4 textureLoad_a9a9f5() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec3 v_5 = (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u));
+  ivec3 v_6 = ivec3(min(uvec3(v_2), v_5));
+  uvec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler3D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_a9a9f5() {
   ivec3 arg_1 = ivec3(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_1), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
index 6565621..ba6de2a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_a9a9f5() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a9a9f5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
index 6565621..ba6de2a 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_a9a9f5() {
   int3 arg_1 = (int(1)).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_a9a9f5();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.msl
index 7135e21..5b5ec41 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_a9a9f5(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.msl
index 43047f7..a2442ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_a9a9f5(texture3d<uint, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.spvasm
index d989e75..5783d87 100644
--- a/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/a9a9f5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+     %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %40 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %49 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_a9a9f5 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,51 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v3int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %31 = OpImageFetch %v4uint %28 %29 Lod %30
-               OpStore %res %31
-         %34 = OpLoad %v4uint %res None
-               OpReturnValue %34
+         %31 = OpImageQueryLevels %uint %28
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %30
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySizeLod %v3uint %28 %35
+         %39 = OpISub %v3uint %37 %40
+         %41 = OpBitcast %v3uint %29
+         %42 = OpExtInst %v3uint %36 UMin %41 %39
+         %43 = OpImageFetch %v4uint %28 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4uint %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
+%fragment_main = OpFunction %void None %49
          %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_a9a9f5
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+         %51 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
+%compute_main = OpFunction %void None %49
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %58 %57 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %61
          %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %70 = OpFunctionCall %v4uint %textureLoad_a9a9f5
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4uint %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
index 14065ec..52fd539 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_aa2579() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
index 14065ec..52fd539 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_aa2579() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.msl
index 6b8b0eb..09f4837 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_aa2579(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.msl
index e5e8672..f9ab7f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_aa2579(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.spvasm
index 57160b0..4c5862d 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aa2579.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_aa2579 = OpFunction %v4uint None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %15
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4uint %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_aa2579
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_aa2579
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_aa2579
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_aa2579
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.glsl
index 04a3014..65859fe 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_aa6130() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_aa6130() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
index 38fb4c0..b77a789 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_aa6130() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
index 38fb4c0..b77a789 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_aa6130() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.msl
index 48c8c4d..f0c4389 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_aa6130(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.msl
index b560fc6..c4bb18a 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_aa6130(texture2d<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.spvasm
index a3e2063..ea34763 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aa6130.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_aa6130 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %22 = OpISub %v2uint %19 %23
+         %25 = OpBitcast %v2uint %18
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_aa6130
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_aa6130
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_aa6130
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_aa6130
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.glsl
index 99f3804..9de0c25 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aa8a0d() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aa8a0d() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_aa8a0d() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
index 841a870..8e5fb74 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aa8a0d() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aa8a0d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
index 841a870..8e5fb74 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aa8a0d() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aa8a0d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.msl
index 8a54ce5..a6bfa1e 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_aa8a0d(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.msl
index 5d859ce..b708eb1 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_aa8a0d(texture2d<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.spvasm
index 2f16807..a9d88ff 100644
--- a/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aa8a0d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aa8a0d = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %28 = OpISub %v2uint %27 %23
+         %29 = OpExtInst %v2uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_aa8a0d
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_aa8a0d
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.glsl
index a795ce0..e19b57c 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_aae7f6() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_aae7f6() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 ivec4 textureLoad_aae7f6() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
index 821503b..0ab77d6 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_aae7f6() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aae7f6();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
index 821503b..0ab77d6 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 int4 textureLoad_aae7f6() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aae7f6();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.msl
index 267fd88..d24978f 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_aae7f6(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.msl
index 220c0ec..71c4b08 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_aae7f6(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.spvasm
index 9b1b600..ed9a6ea 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aae7f6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aae7f6 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4int %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4int %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4int %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4int %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4int %textureLoad_aae7f6
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4int %textureLoad_aae7f6
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4int %textureLoad_aae7f6
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4int %textureLoad_aae7f6
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %62 = OpFunctionCall %v4int %textureLoad_aae7f6
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4int %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %73 = OpFunctionCall %v4int %textureLoad_aae7f6
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4int %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
index 7acd249..49aab3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_aae9c3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
index 7acd249..49aab3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_aae9c3() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.msl
index a5eefb2..972986b 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_aae9c3(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.msl
index a208a1c..2fe9df4 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_aae9c3(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.spvasm
index d05c44e..5ce300a 100644
--- a/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aae9c3.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_aae9c3 = OpFunction %v4float None %10
@@ -59,24 +63,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_aae9c3
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_aae9c3
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_aae9c3
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_aae9c3
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.glsl
index 9706fc6..ec9dcc9 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_ac64f7() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3))).zyxw;
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_ac64f7() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_ac64f7() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v))).zyxw;
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
index 9b67a13..419b38b 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_ac64f7() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ac64f7();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
index 9b67a13..419b38b 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_ac64f7() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ac64f7();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.msl
index 92daef6..d73eb87 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_ac64f7(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.msl
index 655c024..663e7c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_ac64f7(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.spvasm
index 74d14df..33e0a7e 100644
--- a/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ac64f7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 65
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
+         %62 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ac64f7 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,45 +86,53 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
-               OpStore %res %31
-         %34 = OpLoad %v4float %res None
-               OpReturnValue %34
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+         %40 = OpVectorShuffle %v4float %39 %39 2 1 0 3
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_ac64f7
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_ac64f7
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_ac64f7
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_ac64f7
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %57 = OpFunctionCall %v4float %textureLoad_ac64f7
-               OpStore %56 %57 None
-         %58 = OpLoad %VertexOutput %out None
-               OpReturnValue %58
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %66 = OpFunctionCall %v4float %textureLoad_ac64f7
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %60 = OpLabel
-         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %62 = OpCompositeExtract %v4float %61 0
-               OpStore %vertex_main_position_Output %62 None
-         %63 = OpCompositeExtract %v4float %61 1
-               OpStore %vertex_main_loc0_Output %63 None
+%vertex_main = OpFunction %void None %46
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4float %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
index 9e14856..ef57ad6 100644
--- a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_acf22f() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
index 9e14856..ef57ad6 100644
--- a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_acf22f() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.msl
index 8142039..cecdc4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_acf22f(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.msl
index dd3a114..1e700f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_acf22f(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.spvasm
index a6e6d32..f24aa20 100644
--- a/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/acf22f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_acf22f = OpFunction %v4float None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_acf22f
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_acf22f
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_acf22f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_acf22f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.glsl
index 7907079..71ce30f 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_ad551e() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_ad551e() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
index 9608382..beb1304 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_ad551e() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
index 9608382..beb1304 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_ad551e() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.msl
index 7b0cffe..de673a0 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_ad551e(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.msl
index 04310b6..ebb9a8b 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_ad551e(texture1d<uint, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.spvasm
index 85cbc28..cd4029f 100644
--- a/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ad551e.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,7 +41,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_ad551e = OpFunction %v4uint None %10
@@ -49,22 +51,25 @@
                OpStore %arg_1 %uint_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %uint %arg_1 None
-         %17 = OpImageRead %v4uint %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %18 = OpISub %uint %17 %uint_1
+         %19 = OpExtInst %uint %20 UMin %16 %18
+         %21 = OpImageRead %v4uint %15 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_ad551e
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4uint %textureLoad_ad551e
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_ad551e
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_ad551e
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.glsl
index b7fb0ab..32a2f78 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_aeae73() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_aeae73() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_aeae73() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
index 34fc66c..d2aef33 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_aeae73() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aeae73();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
index 34fc66c..d2aef33 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_aeae73() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aeae73();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.msl
index d77c7f2..1b57d38 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_aeae73(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.msl
index da120c5..92baff7 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_aeae73(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.spvasm
index fcb3f85..203c240 100644
--- a/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aeae73.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aeae73 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %23
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4uint %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_aeae73
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_aeae73
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_aeae73
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_aeae73
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_aeae73
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_aeae73
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.glsl
index 0bfe381..f98ea8c 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aebc09() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_aebc09() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_aebc09() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
index 0b5453e..bcd34c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aebc09() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aebc09();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
index 0b5453e..bcd34c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_aebc09() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_aebc09();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.msl
index e82f3b0..b41bd9f 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_aebc09(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.msl
index 6c2c42f..c41707c 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_aebc09(texture1d<uint, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.spvasm
index 3ab9983..391bb3c 100644
--- a/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/aebc09.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %50 = OpConstantNull %v4float
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_aebc09 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -80,43 +82,46 @@
                OpStore %arg_1 %uint_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %uint %arg_1 None
-         %25 = OpImageRead %v4uint %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4uint %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %24 %26
+         %29 = OpImageRead %v4uint %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4uint %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_aebc09
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_aebc09
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_aebc09
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4uint %textureLoad_aebc09
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %52 = OpFunctionCall %v4uint %textureLoad_aebc09
-               OpStore %51 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %56 = OpFunctionCall %v4uint %textureLoad_aebc09
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4uint %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main = OpFunction %void None %35
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4uint %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.glsl
index c90686e..a0ab889 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_af0507() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_af0507() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
index a2f4cfc..84862aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_af0507() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
index a2f4cfc..84862aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_af0507() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.msl
index f048b67..2508ffa 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_af0507(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.msl
index afc0568..4f9215c 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_af0507(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.spvasm
index 724959f..490016e 100644
--- a/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/af0507.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,10 +46,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_af0507 = OpFunction %v4float None %10
@@ -60,24 +64,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_af0507
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_af0507
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_af0507
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_af0507
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.glsl
index 849b482..7d00d45 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_b1bf79() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_b1bf79() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b1bf79() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
index 3cfad07..7807d3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b1bf79() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b1bf79();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
index 3cfad07..7807d3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b1bf79() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b1bf79();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.msl
index 95aedf7..ff537af 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_b1bf79(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.msl
index e19908b..cd1189b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b1bf79(texture3d<int, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.spvasm
index 5d0db3d..52d6f69 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b1bf79.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b1bf79 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %30 = OpISub %v3uint %27 %31
+         %33 = OpBitcast %v3uint %26
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_b1bf79
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_b1bf79
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_b1bf79
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_b1bf79
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_b1bf79
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_b1bf79
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.glsl
index 98ca1ff..05e9617 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_b1ca35() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_b1ca35() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
index fc7626b..d4d80ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_b1ca35() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
index fc7626b..d4d80ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_b1ca35() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.msl
index 3af29b1..59476ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_b1ca35(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.msl
index 72e0c4d..440a6d4 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_b1ca35(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.spvasm
index 620b9d3..c1a6ead 100644
--- a/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b1ca35.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_b1ca35 = OpFunction %v4int None %10
@@ -58,23 +60,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4int %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4int %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_b1ca35
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_b1ca35
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_b1ca35
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_b1ca35
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.glsl
index 1ef641e..19987e92 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_b24d27() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_b24d27() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b24d27() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
index d55589d..2215812 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b24d27() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b24d27();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
index d55589d..2215812 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_b24d27() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b24d27();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.msl
index 30ce081..011ac21 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_b24d27(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.msl
index b609fb8..af8ce9d 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_b24d27(texture2d<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.spvasm
index 8bc411b..081962e 100644
--- a/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b24d27.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b24d27 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %29 = OpISub %v2uint %28 %24
+         %30 = OpExtInst %v2uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_b24d27
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_b24d27
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_b24d27
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_b24d27
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_b24d27
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_b24d27
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.glsl
index 69f3a3c..29b38ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_b25644() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_b25644() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
index 81c88c8..7fc7f65 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_b25644() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
index 81c88c8..7fc7f65 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_b25644() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.msl
index e20d14e..7198130 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_b25644(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.msl
index e28ec29..7496aa1 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b25644(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.spvasm
index 1c3147f..8e1bcee 100644
--- a/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b25644.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_b25644 = OpFunction %v4uint None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4uint %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_b25644
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_b25644
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_b25644
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_b25644
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.glsl
index 42bd3fb..4f996c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_b27c33() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_b27c33() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
index 46b0a52..8c85350 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b27c33() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
index 46b0a52..8c85350 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b27c33() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.msl
index 88791b7..53c7cf9 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_b27c33(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.msl
index fd7ed0d..d23fbd7 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b27c33(texture3d<int, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.spvasm
index b0052f7..98f5e50 100644
--- a/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b27c33.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_b27c33 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %22 = OpISub %v3uint %19 %23
+         %25 = OpBitcast %v3uint %18
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_b27c33
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_b27c33
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_b27c33
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_b27c33
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.glsl
index cc70000..021b297 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_b29f71() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2DArray arg_0;
 ivec4 textureLoad_b29f71() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  ivec4 res = texelFetch(arg_0, v_10, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2DArray arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_b29f71() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_4));
+  ivec4 res = texelFetch(arg_0, v_9, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
index 998610b..6df27f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b29f71();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
index 998610b..6df27f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  int4 res = int4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  int4 res = int4(arg_0.Load(int4(v_7, v_8, int(v_4))));
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b29f71();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.msl
index 03a9536..147a793 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint const v = arg_2;
-  int const v_1 = arg_3;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.msl
index e82abe3..6d6bc1b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_b29f71(texture2d_array<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.spvasm
index 239ba4d..17f7a07 100644
--- a/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b29f71.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 73
+; Bound: 88
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %41 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %50 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %44 = OpTypeFunction %void
+         %60 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %56 = OpTypeFunction %VertexOutput
+         %71 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %60 = OpConstantNull %VertexOutput
+         %75 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %63 = OpConstantNull %v4float
+         %78 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b29f71 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -93,45 +97,57 @@
          %32 = OpLoad %v2int %arg_1 None
          %33 = OpLoad %uint %arg_2 None
          %34 = OpLoad %int %arg_3 None
-         %35 = OpBitcast %int %33
-         %37 = OpCompositeConstruct %v3int %32 %35
-         %38 = OpImageFetch %v4int %31 %37 Lod %34
-               OpStore %res %38
-         %41 = OpLoad %v4int %res None
-               OpReturnValue %41
+         %35 = OpImageQuerySizeLod %v3uint %31 %uint_0
+         %38 = OpCompositeExtract %uint %35 2
+         %39 = OpISub %uint %38 %uint_1
+         %40 = OpExtInst %uint %41 UMin %33 %39
+         %42 = OpImageQueryLevels %uint %31
+         %43 = OpISub %uint %42 %uint_1
+         %44 = OpBitcast %uint %34
+         %45 = OpExtInst %uint %41 UMin %44 %43
+         %46 = OpImageQuerySizeLod %v3uint %31 %45
+         %47 = OpVectorShuffle %v2uint %46 %46 0 1
+         %49 = OpISub %v2uint %47 %50
+         %51 = OpBitcast %v2uint %32
+         %52 = OpExtInst %v2uint %41 UMin %51 %49
+         %53 = OpCompositeConstruct %v3uint %52 %40
+         %54 = OpImageFetch %v4int %31 %53 Lod %45
+               OpStore %res %54
+         %57 = OpLoad %v4int %res None
+               OpReturnValue %57
                OpFunctionEnd
-%fragment_main = OpFunction %void None %44
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_b29f71
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%fragment_main = OpFunction %void None %60
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4int %textureLoad_b29f71
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %44
-         %51 = OpLabel
-         %52 = OpFunctionCall %v4int %textureLoad_b29f71
-         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %53 %52 None
+%compute_main = OpFunction %void None %60
+         %66 = OpLabel
+         %67 = OpFunctionCall %v4int %textureLoad_b29f71
+         %68 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %68 %67 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %56
-         %57 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %60
-         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %61 %63 None
-         %64 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %65 = OpFunctionCall %v4int %textureLoad_b29f71
-               OpStore %64 %65 None
-         %66 = OpLoad %VertexOutput %out None
-               OpReturnValue %66
+%vertex_main_inner = OpFunction %VertexOutput None %71
+         %72 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %75
+         %76 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %76 %78 None
+         %79 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %80 = OpFunctionCall %v4int %textureLoad_b29f71
+               OpStore %79 %80 None
+         %81 = OpLoad %VertexOutput %out None
+               OpReturnValue %81
                OpFunctionEnd
-%vertex_main = OpFunction %void None %44
-         %68 = OpLabel
-         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %70 = OpCompositeExtract %v4float %69 0
-               OpStore %vertex_main_position_Output %70 None
-         %71 = OpCompositeExtract %v4int %69 1
-               OpStore %vertex_main_loc0_Output %71 None
+%vertex_main = OpFunction %void None %60
+         %83 = OpLabel
+         %84 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %85 = OpCompositeExtract %v4float %84 0
+               OpStore %vertex_main_position_Output %85 None
+         %86 = OpCompositeExtract %v4int %84 1
+               OpStore %vertex_main_loc0_Output %86 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.glsl
index 76eacee..6d64c5f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_b4d6c4() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_b4d6c4() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
index 4c86687..e03951e 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b4d6c4() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
index 4c86687..e03951e 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_b4d6c4() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.msl
index 7a47868..d9eca45 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_b4d6c4(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.msl
index 555e92b..356d99d 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_b4d6c4(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.spvasm
index 31f324c..0bf545f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b4d6c4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_b4d6c4 = OpFunction %v4float None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_b4d6c4
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_b4d6c4
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_b4d6c4
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_b4d6c4
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.glsl
index d20924c..f19cc9b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_b58c6d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_b58c6d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_b58c6d() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
index bcc193f..a312469 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_b58c6d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b58c6d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
index bcc193f..a312469 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_b58c6d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b58c6d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.msl
index 6040717..af54b2f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_b58c6d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.msl
index facdd6c..fa2e1dc 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b58c6d(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.spvasm
index 6daeaca..4abf47b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b58c6d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b58c6d = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,44 +90,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_b58c6d
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_b58c6d
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_b58c6d
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_b58c6d
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_b58c6d
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_b58c6d
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
index 4855e8a..188b035 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b60a86() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
index 4855e8a..188b035 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_b60a86() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.msl
index 020fc8e..6230c9d 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_b60a86(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.msl
index 913d935..0e76703 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b60a86(texture1d<uint, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.spvasm
index 887630e..0790902 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b60a86.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,9 +40,10 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_b60a86 = OpFunction %v4uint None %10
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4uint %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %17
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4uint %16 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4uint %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_b60a86
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4uint %textureLoad_b60a86
          %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_b60a86
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
index f75f0d0..1cbf88c 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_b60db7() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
index f75f0d0..1cbf88c 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_b60db7() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.msl
index af89607..2cbcc6b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_b60db7(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.msl
index 876acd8..61018c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_b60db7(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.spvasm
index d7816b1..2f26e18 100644
--- a/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b60db7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_b60db7 = OpFunction %v4float None %10
@@ -57,24 +59,32 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+         %35 = OpVectorShuffle %v4float %34 %34 2 1 0 3
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_b60db7
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_b60db7
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_b60db7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_b60db7
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.glsl
index dc77d89..0528a5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_b6ba5d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  float res = texelFetch(arg_0, v_10, int(v_8)).x;
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_b6ba5d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_8 = min(uint(v_4), v_7);
+  ivec2 v_9 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_8)).xy) - uvec2(1u))));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  float res = texelFetch(arg_0, v_10, int(v_8)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_b6ba5d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  int v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_3), v_6);
+  ivec2 v_8 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_7)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
index 2088346..a3fc7c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_5))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6ba5d();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
index 2088346..a3fc7c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int arg_3 = int(1);
-  int v = arg_2;
+  uint2 v = arg_1;
   int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint v_5 = min(uint(v_1), (v_4.w - 1u));
+  uint4 v_6 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_5), v_6.x, v_6.y, v_6.z, v_6.w);
+  int2 v_7 = int2(min(v, (v_6.xy - (1u).xx)));
+  int v_8 = int(v_3);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_5))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6ba5d();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.msl
index 9880103..9e805a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.ir.msl
@@ -20,7 +20,11 @@
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  int const v_1 = arg_3;
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_3 = min(uint(v_1), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_3), tint_module_vars.arg_0.get_height(v_3)) - uint2(1u))), v_2, v_3);
   return res;
 }
 
@@ -43,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.msl
index 18e5dfc..118ef4f 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_b6ba5d(depth2d_array<float, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
   int arg_3 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.spvasm
index 4b03c8e..d46365d 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b6ba5d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %56 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %54 = OpTypeFunction %VertexOutput
+         %67 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
+         %71 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %61 = OpConstantNull %v4float
+         %74 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b6ba5d = OpFunction %float None %15
          %16 = OpLabel
@@ -90,46 +92,58 @@
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %int %arg_2 None
          %31 = OpLoad %int %arg_3 None
-         %32 = OpBitcast %uint %30
-         %34 = OpCompositeConstruct %v3uint %29 %32
-         %35 = OpImageFetch %v4float %28 %34 Lod %31
-         %36 = OpCompositeExtract %float %35 0
-               OpStore %res %36
-         %39 = OpLoad %float %res None
-               OpReturnValue %39
+         %32 = OpImageQuerySizeLod %v3uint %28 %uint_0
+         %35 = OpCompositeExtract %uint %32 2
+         %36 = OpISub %uint %35 %uint_1
+         %37 = OpBitcast %uint %30
+         %38 = OpExtInst %uint %39 UMin %37 %36
+         %40 = OpImageQueryLevels %uint %28
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %31
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %28 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %39 UMin %29 %46
+         %48 = OpCompositeConstruct %v3uint %47 %38
+         %49 = OpImageFetch %v4float %28 %48 Lod %43
+         %50 = OpCompositeExtract %float %49 0
+               OpStore %res %50
+         %53 = OpLoad %float %res None
+               OpReturnValue %53
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_b6ba5d
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %56
+         %57 = OpLabel
+         %58 = OpFunctionCall %float %textureLoad_b6ba5d
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %float %textureLoad_b6ba5d
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %51 %50 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %61 None
-         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
+%compute_main = OpFunction %void None %56
+         %62 = OpLabel
          %63 = OpFunctionCall %float %textureLoad_b6ba5d
-               OpStore %62 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %64 %63 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %float %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+%vertex_main_inner = OpFunction %VertexOutput None %67
+         %68 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %71
+         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %76 = OpFunctionCall %float %textureLoad_b6ba5d
+               OpStore %75 %76 None
+         %77 = OpLoad %VertexOutput %out None
+               OpReturnValue %77
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %56
+         %79 = OpLabel
+         %80 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %81 = OpCompositeExtract %v4float %80 0
+               OpStore %vertex_main_position_Output %81 None
+         %82 = OpCompositeExtract %float %80 1
+               OpStore %vertex_main_loc0_Output %82 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.glsl
index f44fe16..470fab4 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_b6c458() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_b6c458() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_b6c458() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
index 3b0d060..0a6c7d1 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b6c458() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6c458();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
index 3b0d060..0a6c7d1 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_b6c458() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b6c458();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.msl
index 9f73528..7d82f71 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_b6c458(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.msl
index 442638e..77e2485 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b6c458(texture2d<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.spvasm
index d4a0844..6cc808b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b6c458.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b6c458 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %30 = OpISub %v2uint %28 %31
+         %33 = OpBitcast %v2uint %27
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_b6c458
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_b6c458
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_b6c458
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_b6c458
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_b6c458
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_b6c458
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.glsl
index 0f2fd95..ed9e500 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_b73f6b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_b73f6b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec2 v_5 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_b73f6b() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
index 35251e3..c59fde7 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_b73f6b() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b73f6b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
index 35251e3..c59fde7 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_b73f6b() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int3(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b73f6b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.msl
index ac91e9a..d67185d 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_b73f6b(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.msl
index 28dd257..2192d4b 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_b73f6b(texture2d<uint, access::sample> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.spvasm
index 0cb901e..88d73cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b73f6b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %58 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %65 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b73f6b = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +89,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %31
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySizeLod %v2uint %29 %35
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %36 UMin %30 %38
+         %40 = OpImageFetch %v4uint %29 %39 Lod %35
+               OpStore %res %40
+         %43 = OpLoad %v4uint %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_b73f6b
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_b73f6b
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_b73f6b
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_b73f6b
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_b73f6b
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %58
+         %59 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %62
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %63 %65 None
+         %66 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %67 = OpFunctionCall %v4uint %textureLoad_b73f6b
+               OpStore %66 %67 None
+         %68 = OpLoad %VertexOutput %out None
+               OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %46
+         %70 = OpLabel
+         %71 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %72 = OpCompositeExtract %v4float %71 0
+               OpStore %vertex_main_position_Output %72 None
+         %73 = OpCompositeExtract %v4uint %71 1
+               OpStore %vertex_main_loc0_Output %73 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.glsl
index 1678154..4701749 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_b75c8f() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_b75c8f() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
index c82d46b..24f41cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b75c8f() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
index c82d46b..24f41cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_b75c8f() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.msl
index 1389fa0..3f400bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_b75c8f(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.msl
index 4fcd2fd..1a30cf8 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_b75c8f(texture2d<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.spvasm
index c1f71d8..35f6155 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b75c8f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_b75c8f = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_b75c8f
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_b75c8f
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_b75c8f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_b75c8f
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.glsl
index 31d5684..1dbb8ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_b75d4a() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_b75d4a() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  vec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_b75d4a() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  vec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
index e0ff605..b86e045 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float4 res = float4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b75d4a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
index e0ff605..b86e045 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  float4 res = float4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b75d4a();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.msl
index 731a679..9e5b08a 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_b75d4a(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.msl
index 3f530a6..46b75c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b75d4a(texture2d_ms<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.spvasm
index 6f939cf..6a41ef0 100644
--- a/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b75d4a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,16 +65,18 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %33 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %59 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b75d4a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +88,47 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Sample %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQuerySize %v2uint %27
+         %32 = OpISub %v2uint %30 %33
+         %34 = OpBitcast %v2uint %28
+         %35 = OpExtInst %v2uint %36 UMin %34 %32
+         %37 = OpImageFetch %v4float %27 %35 Sample %29
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_b75d4a
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_b75d4a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_b75d4a
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_b75d4a
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_b75d4a
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %55
+         %56 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %59
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %60 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %63 = OpFunctionCall %v4float %textureLoad_b75d4a
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %43
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4float %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.glsl
index fc56c46..9ec195c 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_b7f74f() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u))).zyxw;
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_b7f74f() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u))).zyxw;
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_b7f74f() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u))).zyxw;
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
index 35d8cd0..8135457 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b7f74f() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b7f74f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
index 35d8cd0..8135457 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_b7f74f() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b7f74f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.msl
index ae2dd4a..21c1b89 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_b7f74f(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.msl
index d22095e..624a9f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_b7f74f(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.spvasm
index 58dfc3c..a3a40f0 100644
--- a/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b7f74f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 58
+; Bound: 62
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %46 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
+         %50 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b7f74f = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,44 +79,47 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-         %24 = OpVectorShuffle %v4float %23 %23 2 1 0 3
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+         %28 = OpVectorShuffle %v4float %27 %27 2 1 0 3
+               OpStore %res %28
+         %31 = OpLoad %v4float %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_b7f74f
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_b7f74f
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_b7f74f
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_b7f74f
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
-         %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %50 = OpFunctionCall %v4float %textureLoad_b7f74f
-               OpStore %49 %50 None
-         %51 = OpLoad %VertexOutput %out None
-               OpReturnValue %51
+%vertex_main_inner = OpFunction %VertexOutput None %46
+         %47 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %50
+         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %51 %52 None
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %54 = OpFunctionCall %v4float %textureLoad_b7f74f
+               OpStore %53 %54 None
+         %55 = OpLoad %VertexOutput %out None
+               OpReturnValue %55
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %53 = OpLabel
-         %54 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %55 = OpCompositeExtract %v4float %54 0
-               OpStore %vertex_main_position_Output %55 None
-         %56 = OpCompositeExtract %v4float %54 1
-               OpStore %vertex_main_loc0_Output %56 None
+%vertex_main = OpFunction %void None %34
+         %57 = OpLabel
+         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %59 = OpCompositeExtract %v4float %58 0
+               OpStore %vertex_main_position_Output %59 None
+         %60 = OpCompositeExtract %v4float %58 1
+               OpStore %vertex_main_loc0_Output %60 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.glsl
index d66db64..4029766 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_b80e7e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_b80e7e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_b80e7e() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
index fb34465..01736e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_b80e7e() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b80e7e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
index fb34465..01736e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_b80e7e() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b80e7e();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.msl
index 7388660..ac75010 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_b80e7e(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.msl
index d37bdd8..49d83e6 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_b80e7e(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.spvasm
index ed99e58..b065cd5 100644
--- a/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b80e7e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b80e7e = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,45 +88,53 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4float %res None
-               OpReturnValue %36
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4float %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_b80e7e
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4float %textureLoad_b80e7e
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4float %textureLoad_b80e7e
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %textureLoad_b80e7e
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %59 = OpFunctionCall %v4float %textureLoad_b80e7e
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %68 = OpFunctionCall %v4float %textureLoad_b80e7e
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4float %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4float %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.glsl
index c2bcf25..704d268 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_b94d15() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_b94d15() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_b94d15() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
index f293d86..b3a5689 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_b94d15() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b94d15();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
index f293d86..b3a5689 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_b94d15() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_b94d15();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.msl
index d0a4c94..ef66261 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_b94d15(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.msl
index c304087..7e2547a 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_b94d15(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.spvasm
index d63d7fa..1f2a1f0 100644
--- a/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/b94d15.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_b94d15 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4uint %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_b94d15
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_b94d15
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_b94d15
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_b94d15
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_b94d15
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_b94d15
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.glsl
index 52c933e..3c5c45c 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_ba023a() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_ba023a() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
index c394a80..0b6aeb9 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_ba023a() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
index c394a80..0b6aeb9 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_ba023a() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.msl
index acb1fee..a21c9f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_ba023a(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.msl
index da7658d..2451f65 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ba023a(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.spvasm
index dd61a19..b6baa97 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ba023a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,12 +42,15 @@
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_ba023a = OpFunction %v4int None %10
          %11 = OpLabel
@@ -57,23 +62,33 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2int %arg_1 None
          %21 = OpLoad %int %arg_2 None
-         %23 = OpCompositeConstruct %v3int %20 %21
-         %24 = OpImageRead %v4int %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %25 = OpCompositeExtract %uint %22 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %21
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %19
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %20
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4int %19 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_ba023a
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_ba023a
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_ba023a
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_ba023a
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
index 8fe2fcb..2d6ebab 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_ba74b2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
index 8fe2fcb..2d6ebab 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_ba74b2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.msl
index db6a87e..8e78b7b 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_ba74b2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.msl
index b2ef1bf..7fbdb7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ba74b2(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.spvasm
index 7a35935..51b2f39 100644
--- a/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ba74b2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,12 +42,15 @@
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_ba74b2 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -57,23 +62,33 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2int %arg_1 None
          %21 = OpLoad %int %arg_2 None
-         %23 = OpCompositeConstruct %v3int %20 %21
-         %24 = OpImageRead %v4int %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %25 = OpCompositeExtract %uint %22 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %21
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %19
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %20
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4int %19 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_ba74b2
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_ba74b2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_ba74b2
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_ba74b2
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
index 66baba2..8f5aacf 100644
--- a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_babdf3() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
index 66baba2..8f5aacf 100644
--- a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_babdf3() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.msl
index 1fa62d0..7a9a20b 100644
--- a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_babdf3(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.msl
index 9397b9f..4decd45 100644
--- a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_babdf3(texture1d<uint, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.spvasm
index 81aac50..3b2ab18 100644
--- a/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/babdf3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,7 +41,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_babdf3 = OpFunction %v4uint None %10
@@ -49,22 +51,25 @@
                OpStore %arg_1 %uint_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %uint %arg_1 None
-         %17 = OpImageRead %v4uint %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %18 = OpISub %uint %17 %uint_1
+         %19 = OpExtInst %uint %20 UMin %16 %18
+         %21 = OpImageRead %v4uint %15 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_babdf3
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4uint %textureLoad_babdf3
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_babdf3
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_babdf3
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.glsl
index 6bf1b39..1194230 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_bba04a() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp uimage2D arg_0;
 uvec4 textureLoad_bba04a() {
   uint arg_1 = 1u;
-  uvec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
index 003cce3..ac30d20 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bba04a() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
index 003cce3..ac30d20 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_bba04a() {
   uint arg_1 = 1u;
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint4 res = uint4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.msl
index bb2e554..5e4c8b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_bba04a(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.msl
index a4a7ad6..389dbba 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_bba04a(texture1d<uint, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.spvasm
index 501831f..0199914 100644
--- a/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bba04a.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 37
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %27 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_bba04a = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %uint %arg_1 None
-         %17 = OpImageRead %v4uint %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4uint %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %18 = OpISub %uint %17 %uint_1
+         %19 = OpExtInst %uint %20 UMin %16 %18
+         %21 = OpImageRead %v4uint %15 %19 None
+               OpStore %res %21
+         %24 = OpLoad %v4uint %res None
+               OpReturnValue %24
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4uint %textureLoad_bba04a
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %26 %25 None
+%fragment_main = OpFunction %void None %27
+         %28 = OpLabel
+         %29 = OpFunctionCall %v4uint %textureLoad_bba04a
+         %30 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %30 %29 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %23
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4uint %textureLoad_bba04a
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %32 %31 None
+%compute_main = OpFunction %void None %27
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4uint %textureLoad_bba04a
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
index c511aa0..5d09f98 100644
--- a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_bbb762() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
index c511aa0..5d09f98 100644
--- a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_bbb762() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.msl
index ef2c492..b066808 100644
--- a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_bbb762(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.msl
index f864ebc..26a8f8d 100644
--- a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_bbb762(texture2d<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.spvasm
index 42821f2..1a6c971 100644
--- a/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bbb762.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_bbb762 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_bbb762
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_bbb762
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_bbb762
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_bbb762
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.glsl
index 20ccd35..0e0e2eb 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.glsl
@@ -2,17 +2,27 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_bc3201() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +30,27 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_bc3201() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uint v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_4 = ivec2(uvec2(min(v_2, (uvec2(textureSize(arg_0, int(v_3))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +60,28 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_bc3201() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(uvec2(arg_1, 0u));
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uint v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  ivec2 v_3 = ivec2(uvec2(min(v_1, (uvec2(textureSize(arg_0, int(v_2))).x - 1u)), 0u));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +91,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
index 6f7b74e..ebb527d 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_bc3201() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bc3201();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
index 6f7b74e..ebb527d 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_bc3201() {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int v_1 = int(arg_1);
-  uint4 res = uint4(arg_0.Load(int2(v_1, int(v))));
+  uint v = arg_1;
+  uint2 v_1 = (0u).xx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y);
+  uint v_2 = min(arg_2, (v_1.y - 1u));
+  uint2 v_3 = (0u).xx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y);
+  int v_4 = int(min(v, (v_3.x - 1u)));
+  uint4 res = uint4(arg_0.Load(int2(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bc3201();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.msl
index be3a8aa..35fe7c8 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_bc3201(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.msl
index a1016d2..c260f81 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.msl
@@ -4,7 +4,8 @@
 uint4 textureLoad_bc3201(texture1d<uint, access::sample> tint_symbol_1) {
   uint arg_1 = 1u;
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint(arg_1), 0);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))), 0);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.spvasm
index c1abaf8..fe7f07f 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bc3201.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,15 +65,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %56 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bc3201 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +85,49 @@
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
          %26 = OpLoad %uint %arg_2 None
-         %27 = OpImageFetch %v4uint %24 %25 Lod %26
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQueryLevels %uint %24
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %26 %28
+         %31 = OpImageQuerySizeLod %uint %24 %29
+         %32 = OpISub %uint %31 %uint_1
+         %33 = OpExtInst %uint %30 UMin %25 %32
+         %34 = OpImageFetch %v4uint %24 %33 Lod %29
+               OpStore %res %34
+         %37 = OpLoad %v4uint %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_bc3201
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4uint %textureLoad_bc3201
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_bc3201
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4uint %textureLoad_bc3201
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_bc3201
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %61 = OpFunctionCall %v4uint %textureLoad_bc3201
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %40
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4uint %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.glsl
index 3315249..1ea0e80 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_bc882d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_bc882d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
index ce66644..a65657a 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_bc882d() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
index ce66644..a65657a 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_bc882d() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.msl
index e9724b1..1ef8b25 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_bc882d(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.msl
index bf6fe99..cd0db0b 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_bc882d(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.spvasm
index 3e00ee5..6e60265 100644
--- a/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bc882d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -47,7 +49,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_bc882d = OpFunction %v4float None %10
@@ -60,24 +62,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_bc882d
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_bc882d
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_bc882d
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_bc882d
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.glsl
index 9170778..c780807 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_bcbb3c() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler3D arg_0;
 vec4 textureLoad_bcbb3c() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec3 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  ivec3 v_5 = ivec3(min(v_2, (uvec3(textureSize(arg_0, int(v_4))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_5, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_bcbb3c() {
   uvec3 arg_1 = uvec3(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec3 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  ivec3 v_4 = ivec3(min(v_1, (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u))));
+  vec4 res = texelFetch(arg_0, v_4, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
index 6d726fc..486fb4d 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_bcbb3c() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bcbb3c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
index 6d726fc..486fb4d 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_bcbb3c() {
   uint3 arg_1 = (1u).xxx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int3 v_1 = int3(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v))));
+  uint3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(uint(arg_2), (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  int3 v_4 = int3(min(v, (v_3.xyz - (1u).xxx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bcbb3c();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.msl
index 084325f..42a85b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_bcbb3c(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint3 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.msl
index abdb6ed..1745312 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.msl
@@ -4,7 +4,8 @@
 float4 textureLoad_bcbb3c(texture3d<float, access::sample> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u)))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.spvasm
index d94032a..e99d9bc 100644
--- a/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bcbb3c.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 72
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %60 = OpConstantNull %VertexOutput
+         %62 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bcbb3c = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +86,50 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v3uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %29
+         %33 = OpExtInst %uint %34 UMin %32 %31
+         %35 = OpImageQuerySizeLod %v3uint %27 %33
+         %36 = OpISub %v3uint %35 %21
+         %37 = OpExtInst %v3uint %34 UMin %28 %36
+         %38 = OpImageFetch %v4float %27 %37 Lod %33
+               OpStore %res %38
+         %41 = OpLoad %v4float %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_bcbb3c
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4float %textureLoad_bcbb3c
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_bcbb3c
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4float %textureLoad_bcbb3c
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_bcbb3c
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %56
+         %57 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %60
+         %61 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %61 %62 None
+         %63 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %64 = OpFunctionCall %v4float %textureLoad_bcbb3c
+               OpStore %63 %64 None
+         %65 = OpLoad %VertexOutput %out None
+               OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %44
+         %67 = OpLabel
+         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %69 = OpCompositeExtract %v4float %68 0
+               OpStore %vertex_main_position_Output %69 None
+         %70 = OpCompositeExtract %v4float %68 1
+               OpStore %vertex_main_loc0_Output %70 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
index b9b7648..9654b96 100644
--- a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_bd990a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
index b9b7648..9654b96 100644
--- a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_bd990a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.msl
index 4a387e1..9ca5d5b 100644
--- a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_bd990a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.msl
index 774f4d6..7f6c816 100644
--- a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_bd990a(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.spvasm
index 1ad18c5..0317718 100644
--- a/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bd990a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_bd990a = OpFunction %v4uint None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %15
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4uint %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_bd990a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_bd990a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_bd990a
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_bd990a
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.glsl
index 1d97234..1f11321 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_bdc67a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_bdc67a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
index 88ff6f8..6667889 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_bdc67a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
index 88ff6f8..6667889 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_bdc67a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.msl
index 6eed91c..ad31074 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_bdc67a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.msl
index ae9b0e1..f137f3b 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_bdc67a(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.spvasm
index a5d9474..22f9820 100644
--- a/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bdc67a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -47,7 +49,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_bdc67a = OpFunction %v4float None %10
@@ -60,24 +62,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_bdc67a
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_bdc67a
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_bdc67a
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_bdc67a
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.glsl
index 527cf9c..91aa430 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_bfd154() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_bfd154() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_bfd154() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
index b29c351..ad29ca6 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bfd154() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bfd154();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
index b29c351..ad29ca6 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_bfd154() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_bfd154();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.msl
index 4a34bc0..bb82ea7 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_bfd154(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.msl
index f14fb48..3888380 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_bfd154(texture3d<uint, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.spvasm
index a956507..3404c7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/bfd154.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_bfd154 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %30 = OpISub %v3uint %28 %31
+         %33 = OpBitcast %v3uint %27
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_bfd154
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_bfd154
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_bfd154
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_bfd154
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_bfd154
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_bfd154
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.glsl
index 39f4fee..7278c36 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c02b74() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c02b74() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c02b74() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
index 39f7587..e282e48 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c02b74() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c02b74();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
index 39f7587..e282e48 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c02b74() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c02b74();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.msl
index bf05941..138b25c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_c02b74(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.msl
index d0cd166..d078945 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c02b74(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.spvasm
index 1e2c78f..e9433c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c02b74.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c02b74 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_c02b74
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_c02b74
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_c02b74
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_c02b74
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_c02b74
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.glsl
index 1ae0ec1..8903ced 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c07013() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c07013() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c07013() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
index 460bfef..6f6ee7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c07013() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c07013();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
index 460bfef..6f6ee7c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c07013() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c07013();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.msl
index 481167d..7671b10 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_c07013(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.msl
index 7b46d9a..d320420 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c07013(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.spvasm
index bab53b9..5c7180a 100644
--- a/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c07013.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c07013 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_c07013
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_c07013
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_c07013
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_c07013
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_c07013
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_c07013
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.glsl
index 154a2e0..98ba347 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_c16e00() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  float res = texelFetch(arg_0, v_10, int(v_7)).x;
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_c16e00() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_5));
+  float res = texelFetch(arg_0, v_10, int(v_7)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_c16e00() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_4));
+  float res = texelFetch(arg_0, v_9, int(v_6)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
index 27a2cd0..01e26b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c16e00();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
index 27a2cd0..01e26b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_2);
+  float res = arg_0.Load(int4(v_7, v_8, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c16e00();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.msl
index 7e8f2b4..d162344 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint const v = arg_2;
-  int const v_1 = arg_3;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_1, v_2);
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.msl
index f9d3258..daf3fed 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_c16e00(depth2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.spvasm
index 1645e82..6a2094c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c16e00.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 72
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,18 +67,20 @@
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %55 = OpTypeFunction %VertexOutput
+         %70 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %59 = OpConstantNull %VertexOutput
+         %74 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %62 = OpConstantNull %v4float
+         %77 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c16e00 = OpFunction %float None %15
          %16 = OpLabel
@@ -91,46 +95,58 @@
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
          %32 = OpLoad %int %arg_3 None
-         %33 = OpBitcast %int %31
-         %35 = OpCompositeConstruct %v3int %30 %33
-         %36 = OpImageFetch %v4float %29 %35 Lod %32
-         %37 = OpCompositeExtract %float %36 0
-               OpStore %res %37
-         %40 = OpLoad %float %res None
-               OpReturnValue %40
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpExtInst %uint %39 UMin %31 %37
+         %40 = OpImageQueryLevels %uint %29
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %32
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %30
+         %50 = OpExtInst %v2uint %39 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %38
+         %52 = OpImageFetch %v4float %29 %51 Lod %43
+         %53 = OpCompositeExtract %float %52 0
+               OpStore %res %53
+         %56 = OpLoad %float %res None
+               OpReturnValue %56
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_c16e00
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpFunctionCall %float %textureLoad_c16e00
+         %62 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %62 %61 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
-         %50 = OpLabel
-         %51 = OpFunctionCall %float %textureLoad_c16e00
-         %52 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %52 %51 None
+%compute_main = OpFunction %void None %59
+         %65 = OpLabel
+         %66 = OpFunctionCall %float %textureLoad_c16e00
+         %67 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %67 %66 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %55
-         %56 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %59
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %60 %62 None
-         %63 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %64 = OpFunctionCall %float %textureLoad_c16e00
-               OpStore %63 %64 None
-         %65 = OpLoad %VertexOutput %out None
-               OpReturnValue %65
+%vertex_main_inner = OpFunction %VertexOutput None %70
+         %71 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %74
+         %75 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %75 %77 None
+         %78 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %79 = OpFunctionCall %float %textureLoad_c16e00
+               OpStore %78 %79 None
+         %80 = OpLoad %VertexOutput %out None
+               OpReturnValue %80
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
-         %67 = OpLabel
-         %68 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %69 = OpCompositeExtract %v4float %68 0
-               OpStore %vertex_main_position_Output %69 None
-         %70 = OpCompositeExtract %float %68 1
-               OpStore %vertex_main_loc0_Output %70 None
+%vertex_main = OpFunction %void None %59
+         %82 = OpLabel
+         %83 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %84 = OpCompositeExtract %v4float %83 0
+               OpStore %vertex_main_position_Output %84 None
+         %85 = OpCompositeExtract %float %83 1
+               OpStore %vertex_main_loc0_Output %85 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.glsl
index ae6eb06..7443c90 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_c21b33() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_c21b33() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_c21b33() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
index 6397ae1..c5dc875 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_c21b33() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c21b33();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
index 6397ae1..c5dc875 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_c21b33() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c21b33();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.msl
index b12e296..18a4da1 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_c21b33(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.msl
index 5736f9b..e23cc93 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c21b33(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.spvasm
index e7cad6e..c95f8a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c21b33.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -69,15 +71,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %50 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %62 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %66 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c21b33 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +91,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpBitcast %uint %31
-         %34 = OpCompositeConstruct %v3uint %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpBitcast %uint %31
+         %37 = OpExtInst %uint %38 UMin %36 %35
+         %39 = OpImageQuerySize %v3uint %29
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %41 = OpISub %v2uint %40 %23
+         %42 = OpExtInst %v2uint %38 UMin %30 %41
+         %43 = OpCompositeConstruct %v3uint %42 %37
+         %44 = OpImageRead %v4uint %29 %43 None
+               OpStore %res %44
+         %47 = OpLoad %v4uint %res None
+               OpReturnValue %47
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_c21b33
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %50
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_c21b33
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_c21b33
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %50
+         %57 = OpLabel
+         %58 = OpFunctionCall %v4uint %textureLoad_c21b33
+         %59 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_c21b33
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
+%vertex_main_inner = OpFunction %VertexOutput None %62
+         %63 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %66
+         %67 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %67 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %71 = OpFunctionCall %v4uint %textureLoad_c21b33
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+%vertex_main = OpFunction %void None %50
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4uint %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.glsl
index 97ce9c7..8f517c1 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.glsl
@@ -2,17 +2,29 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_c2a480() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 void main() {
@@ -20,17 +32,29 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_c2a480() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_4 = min(uint(arg_2), v_3);
+  uvec2 v_5 = (uvec2(textureSize(arg_0, int(v_4))) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_2), v_5));
+  ivec4 res = texelFetch(arg_0, v_6, int(v_4));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +64,30 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c2a480() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_3 = min(uint(arg_2), v_2);
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +97,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
index 5dda965..a469d5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_c2a480() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c2a480();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
index 5dda965..a469d5c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_c2a480() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c2a480();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.msl
index a3d7501..987f915 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_c2a480(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.msl
index 6c61826..94bbb85 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c2a480(texture2d<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.spvasm
index 7883643..2b844ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c2a480.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 78
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %40 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %65 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %68 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c2a480 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,51 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4int %27 %28 Lod %29
-               OpStore %res %30
-         %33 = OpLoad %v4int %res None
-               OpReturnValue %33
+         %30 = OpImageQueryLevels %uint %27
+         %32 = OpISub %uint %30 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySizeLod %v2uint %27 %35
+         %39 = OpISub %v2uint %37 %40
+         %41 = OpBitcast %v2uint %28
+         %42 = OpExtInst %v2uint %36 UMin %41 %39
+         %43 = OpImageFetch %v4int %27 %42 Lod %35
+               OpStore %res %43
+         %46 = OpLoad %v4int %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_c2a480
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_c2a480
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
+%fragment_main = OpFunction %void None %49
          %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_c2a480
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+         %51 = OpFunctionCall %v4int %textureLoad_c2a480
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %52 %51 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
+%compute_main = OpFunction %void None %49
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4int %textureLoad_c2a480
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %58 %57 None
+               OpReturn
+               OpFunctionEnd
+%vertex_main_inner = OpFunction %VertexOutput None %61
          %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %68 None
+         %69 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %70 = OpFunctionCall %v4int %textureLoad_c2a480
+               OpStore %69 %70 None
+         %71 = OpLoad %VertexOutput %out None
+               OpReturnValue %71
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %49
+         %73 = OpLabel
+         %74 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %75 = OpCompositeExtract %v4float %74 0
+               OpStore %vertex_main_position_Output %75 None
+         %76 = OpCompositeExtract %v4int %74 1
+               OpStore %vertex_main_loc0_Output %76 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.glsl
index 22e4752..9e9d8fd 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_c2d09a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_c2d09a() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
index d1d142c..7b68f75 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_c2d09a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
index d1d142c..7b68f75 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_c2d09a() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.msl
index 0204d30..8a303f9 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_c2d09a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.msl
index b5a7fcb..425c3ac 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c2d09a(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.spvasm
index 4be85f3..a5d2c25 100644
--- a/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c2d09a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_c2d09a = OpFunction %v4uint None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %15
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4uint %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_c2d09a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_c2d09a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_c2d09a
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_c2d09a
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.glsl
index eed507d..6f9a043 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_c378ee() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_c378ee() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_c378ee() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
index 4b99764..62c482d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  uint4 res = uint4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c378ee();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
index 4b99764..62c482d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  uint4 res = uint4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c378ee();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.msl
index b694603..644ed1a 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_c378ee(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  int const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.msl
index 7adcb18..34a6860 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c378ee(texture2d_ms<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.spvasm
index 6cd2730..b447d6f 100644
--- a/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c378ee.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %49 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c378ee = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,47 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %31 = OpImageFetch %v4uint %28 %29 Sample %30
-               OpStore %res %31
-         %34 = OpLoad %v4uint %res None
-               OpReturnValue %34
+         %31 = OpImageQuerySize %v2uint %28
+         %33 = OpISub %v2uint %31 %34
+         %36 = OpBitcast %v2uint %29
+         %37 = OpExtInst %v2uint %38 UMin %36 %33
+         %39 = OpImageFetch %v4uint %28 %37 Sample %30
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4uint %textureLoad_c378ee
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_c378ee
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4uint %textureLoad_c378ee
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_c378ee
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_c378ee
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %66 = OpFunctionCall %v4uint %textureLoad_c378ee
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %45
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4uint %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.glsl
index eadc5d7..046326d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_c40dcb() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_c40dcb() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 uvec4 textureLoad_c40dcb() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
index bd89e66..4e0c1cf 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_c40dcb() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c40dcb();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
index bd89e66..4e0c1cf 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_c40dcb() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c40dcb();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.msl
index d97b9f0..b700f51 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_c40dcb(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.msl
index 0fbfd6d..9f41cb0 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_c40dcb(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.spvasm
index efb890c..6689b02 100644
--- a/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c40dcb.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,19 +67,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c40dcb = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %32 = OpCompositeConstruct %v3int %29 %30
-         %33 = OpImageRead %v4uint %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4uint %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %30
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %28
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %29
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4uint %28 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_c40dcb
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_c40dcb
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4uint %textureLoad_c40dcb
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4uint %textureLoad_c40dcb
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %74 = OpFunctionCall %v4uint %textureLoad_c40dcb
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4uint %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.glsl
index 3684f5a6..f5c1fb2 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_c456bc() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_c456bc() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c456bc() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
index e925dc0..cc0270d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c456bc() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c456bc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
index e925dc0..cc0270d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c456bc() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c456bc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.msl
index 7796ca6..56b962d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_c456bc(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.msl
index efc6e2f..37fe28d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c456bc(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.spvasm
index 9412974..e6401b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c456bc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c456bc = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_c456bc
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_c456bc
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_c456bc
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_c456bc
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_c456bc
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_c456bc
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.glsl
index ba258ae..137176b 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c5791b() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c5791b() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c5791b() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
index 460626e..c83f723 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c5791b() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c5791b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
index 460626e..c83f723 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c5791b() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c5791b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.msl
index 95dd532..6a789a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_c5791b(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.msl
index 9dd9b44..f0b81d4 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_c5791b(texture2d<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.spvasm
index b18f5ee..ebb3ab4 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c5791b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c5791b = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %29 = OpISub %v2uint %28 %24
+         %30 = OpExtInst %v2uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_c5791b
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_c5791b
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_c5791b
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_c5791b
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_c5791b
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_c5791b
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
index eca19a8..32c4c8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_c5c86d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
index eca19a8..32c4c8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_c5c86d() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.msl
index 6d74016..f106814 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_c5c86d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.msl
index 781cfa1..972cdbb 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c5c86d(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.spvasm
index 5ddc2bd..98dcb5a 100644
--- a/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c5c86d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,12 +42,15 @@
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c5c86d = OpFunction %v4int None %10
          %11 = OpLabel
@@ -57,23 +62,33 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2int %arg_1 None
          %21 = OpLoad %int %arg_2 None
-         %23 = OpCompositeConstruct %v3int %20 %21
-         %24 = OpImageRead %v4int %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %25 = OpCompositeExtract %uint %22 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %21
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %19
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %20
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4int %19 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_c5c86d
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_c5c86d
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_c5c86d
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_c5c86d
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.glsl
index 2027b97..0656515 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c66b20() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c66b20() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c66b20() {
   uvec2 arg_1 = uvec2(1u);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
index 5ec9bd5..92f4b89 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c66b20() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c66b20();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
index 5ec9bd5..92f4b89 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c66b20() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c66b20();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.msl
index daae673..a241a06 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_c66b20(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.msl
index 08fd9b4..59ff131 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_c66b20(texture2d<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.spvasm
index 1bdd046..b9e179c 100644
--- a/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c66b20.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c66b20 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %29 = OpISub %v2uint %28 %24
+         %30 = OpExtInst %v2uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_c66b20
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_c66b20
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_c66b20
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_c66b20
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_c66b20
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_c66b20
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.glsl
index 60df491..00712cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c7cbed() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_c7cbed() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_c7cbed() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
index 831876f..5bc0f84 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c7cbed() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c7cbed();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
index 831876f..5bc0f84 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_c7cbed() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c7cbed();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.msl
index 65c303f..992d11e 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_c7cbed(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.msl
index 55dad2b..0276884 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c7cbed(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.spvasm
index 4a11330..c089eb9 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c7cbed.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c7cbed = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_c7cbed
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_c7cbed
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_c7cbed
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_c7cbed
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_c7cbed
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
index c8e7e30..c2f8612 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c7e313() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
index c8e7e30..c2f8612 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_c7e313() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.msl
index b214067..0ce16fc 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 uint4 textureLoad_c7e313(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.msl
index c43c819..6e8b078 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_c7e313(texture2d<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol.read(uint2(arg_1));
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.spvasm
index ac995c2..ddc132f 100644
--- a/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c7e313.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
          %15 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_c7e313 = OpFunction %v4uint None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2uint %arg_1 None
-         %19 = OpImageRead %v4uint %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4uint %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %20 = OpISub %v2uint %19 %15
+         %21 = OpExtInst %v2uint %22 UMin %18 %20
+         %23 = OpImageRead %v4uint %17 %21 None
+               OpStore %res %23
+         %26 = OpLoad %v4uint %res None
+               OpReturnValue %26
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4uint %textureLoad_c7e313
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %29
+         %30 = OpLabel
+         %31 = OpFunctionCall %v4uint %textureLoad_c7e313
+         %32 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %32 %31 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4uint %textureLoad_c7e313
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %34 %33 None
+%compute_main = OpFunction %void None %29
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4uint %textureLoad_c7e313
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.glsl
index ec700d2..8424a93 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c80691() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c80691() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
index 84efd04..cbcffea 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c80691() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
index 84efd04..cbcffea 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c80691() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.msl
index e13c6fd..703df5e 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_c80691(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.msl
index 3c6b299..2a5b006 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_c80691(texture1d<int, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.spvasm
index 8844d3b..9c5f0f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c80691.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_c80691 = OpFunction %v4int None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4int %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4int %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4int %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_c80691
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4int %textureLoad_c80691
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_c80691
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_c80691
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.glsl
index aa11e89..1215768 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_c8ed19() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_c8ed19() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_c8ed19() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
index ff7f186..95690dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_c8ed19() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c8ed19();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
index ff7f186..95690dd 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 uint4 textureLoad_c8ed19() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c8ed19();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.msl
index fd6a79d..f4efa5b 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_c8ed19(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.msl
index 92b9071..a0d90e9 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_c8ed19(texture2d_array<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.spvasm
index 3ee13a8..1ce3471 100644
--- a/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c8ed19.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 76
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,15 +70,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %59 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %66 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c8ed19 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -88,44 +90,52 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %uint %arg_2 None
-         %31 = OpCompositeConstruct %v3uint %28 %29
-         %32 = OpImageRead %v4uint %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %29 %33
+         %36 = OpImageQuerySize %v3uint %27
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+         %38 = OpISub %v2uint %37 %23
+         %39 = OpExtInst %v2uint %35 UMin %28 %38
+         %40 = OpCompositeConstruct %v3uint %39 %34
+         %41 = OpImageRead %v4uint %27 %40 None
+               OpStore %res %41
+         %44 = OpLoad %v4uint %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_c8ed19
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4uint %textureLoad_c8ed19
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_c8ed19
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_c8ed19
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_c8ed19
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %59
+         %60 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %63
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %64 %66 None
+         %67 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %68 = OpFunctionCall %v4uint %textureLoad_c8ed19
+               OpStore %67 %68 None
+         %69 = OpLoad %VertexOutput %out None
+               OpReturnValue %69
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %47
+         %71 = OpLabel
+         %72 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %73 = OpCompositeExtract %v4float %72 0
+               OpStore %vertex_main_position_Output %73 None
+         %74 = OpCompositeExtract %v4uint %72 1
+               OpStore %vertex_main_loc0_Output %74 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
index beb46cc..393d32d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_c98bf4() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
index beb46cc..393d32d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_c98bf4() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.msl
index 299542f..bc1d2fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_c98bf4(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.msl
index 06b6b9e..666c20b 100644
--- a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_c98bf4(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.spvasm
index c94d6df..8021629 100644
--- a/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c98bf4.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c98bf4 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_c98bf4
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_c98bf4
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_c98bf4
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_c98bf4
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
index e11fab8..c3e2b02 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_c9b083() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
index e11fab8..c3e2b02 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_c9b083() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.msl
index 7c45955..6fa567e 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_c9b083(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.msl
index dc1e2de..e1a4438 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9b083(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.spvasm
index 2854d62..9a0dbcc 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c9b083.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_c9b083 = OpFunction %v4int None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4int %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_c9b083
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_c9b083
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_c9b083
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_c9b083
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.glsl
index e0ccd0e..18331a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c9cc40() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_c9cc40() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_c9cc40() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
index 36810a3..f5b4bdc 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c9cc40() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c9cc40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
index 36810a3..f5b4bdc 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_c9cc40() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_c9cc40();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.msl
index 7c10912..49bdcd4 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_c9cc40(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.msl
index dc22ab1..13eb322 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9cc40(texture1d<int, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.spvasm
index 892ec31..8f69faa 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c9cc40.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_c9cc40 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageRead %v4int %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4int %23 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_c9cc40
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4int %textureLoad_c9cc40
          %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_c9cc40
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4int %textureLoad_c9cc40
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_c9cc40
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.glsl
index 027ddb3..1d4c33d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c9f310() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_c9f310() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
index 49bdc48..571dd1d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9f310() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
index 49bdc48..571dd1d 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_c9f310() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.msl
index ca43d16..017cdf8 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_c9f310(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.msl
index e4ce4b7..23fe4f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_c9f310(texture1d<int, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.spvasm
index b3376b1..bedcbd6 100644
--- a/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/c9f310.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,11 +39,12 @@
          %10 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_c9f310 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %int %arg_1 None
-         %17 = OpImageRead %v4int %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %19 = OpISub %uint %17 %uint_1
+         %21 = OpBitcast %uint %16
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4int %15 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_c9f310
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %23
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4int %textureLoad_c9f310
          %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_c9f310
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
index 0f53fcd..f4f0ee9 100644
--- a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cac876() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
index 0f53fcd..f4f0ee9 100644
--- a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cac876() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.msl
index fe1c6fc..2bf5fa9 100644
--- a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_cac876(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.msl
index d2bed09..b4c05ca 100644
--- a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_cac876(texture1d<int, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.spvasm
index 20b2ed8..7c14e1ed 100644
--- a/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cac876.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_cac876 = OpFunction %v4int None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4int %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4int %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4int %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_cac876
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4int %textureLoad_cac876
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_cac876
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_cac876
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.glsl
index 69db232..6e07c83 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 uvec4 textureLoad_cad5f2() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 uvec4 textureLoad_cad5f2() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 uvec4 textureLoad_cad5f2() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
index 5ab8712..8e72905 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  uint4 res = uint4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cad5f2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
index 5ab8712..8e72905 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
   uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  uint4 res = uint4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cad5f2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.msl
index d83a8b9..93b73ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_cad5f2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.msl
index 70c904b6..eea5fcf 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cad5f2(texture2d_ms<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.spvasm
index cf37c99..227f60b 100644
--- a/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cad5f2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cad5f2 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,47 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Sample %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQuerySize %v2uint %29
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %30
+         %37 = OpExtInst %v2uint %38 UMin %36 %34
+         %39 = OpImageFetch %v4uint %29 %37 Sample %31
+               OpStore %res %39
+         %42 = OpLoad %v4uint %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_cad5f2
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4uint %textureLoad_cad5f2
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_cad5f2
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4uint %textureLoad_cad5f2
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_cad5f2
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %66 = OpFunctionCall %v4uint %textureLoad_cad5f2
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %45
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4uint %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.glsl
index 1a0d8e7..dfa372c 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_cb57c2() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_7)).x;
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_cb57c2() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_7)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_cb57c2() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  float res = texelFetch(arg_0, v_8, int(v_6)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
index b615e09..e43ebeb 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cb57c2();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
index b615e09..e43ebeb 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float res = arg_0.Load(int4(v_6, v_7, int(v_4))).x;
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cb57c2();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.msl
index c55b238..37f949d 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.msl
index 761a620..41c46b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.spvasm
index b9c1209..54750f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cb57c2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 84
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,17 +68,17 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %56 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %54 = OpTypeFunction %VertexOutput
+         %67 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
+         %71 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %61 = OpConstantNull %v4float
+         %74 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cb57c2 = OpFunction %float None %15
          %16 = OpLabel
@@ -91,45 +93,57 @@
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %uint %arg_2 None
          %32 = OpLoad %int %arg_3 None
-         %34 = OpCompositeConstruct %v3uint %30 %31
-         %35 = OpImageFetch %v4float %29 %34 Lod %32
-         %36 = OpCompositeExtract %float %35 0
-               OpStore %res %36
-         %39 = OpLoad %float %res None
-               OpReturnValue %39
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpExtInst %uint %39 UMin %31 %37
+         %40 = OpImageQueryLevels %uint %29
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %32
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %39 UMin %30 %46
+         %48 = OpCompositeConstruct %v3uint %47 %38
+         %49 = OpImageFetch %v4float %29 %48 Lod %43
+         %50 = OpCompositeExtract %float %49 0
+               OpStore %res %50
+         %53 = OpLoad %float %res None
+               OpReturnValue %53
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_cb57c2
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %56
+         %57 = OpLabel
+         %58 = OpFunctionCall %float %textureLoad_cb57c2
+         %59 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %59 %58 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %float %textureLoad_cb57c2
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %51 %50 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %61 None
-         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
+%compute_main = OpFunction %void None %56
+         %62 = OpLabel
          %63 = OpFunctionCall %float %textureLoad_cb57c2
-               OpStore %62 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
+         %64 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %64 %63 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %float %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+%vertex_main_inner = OpFunction %VertexOutput None %67
+         %68 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %71
+         %72 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %72 %74 None
+         %75 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %76 = OpFunctionCall %float %textureLoad_cb57c2
+               OpStore %75 %76 None
+         %77 = OpLoad %VertexOutput %out None
+               OpReturnValue %77
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %56
+         %79 = OpLabel
+         %80 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %81 = OpCompositeExtract %v4float %80 0
+               OpStore %vertex_main_position_Output %81 None
+         %82 = OpCompositeExtract %float %80 1
+               OpStore %vertex_main_loc0_Output %82 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
index 7fdc053..ebb2fff 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_cdbcf6() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
index 7fdc053..ebb2fff 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_cdbcf6() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.msl
index 1814b5f..5084b2f 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_cdbcf6(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.msl
index daecc50..853e53c 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_cdbcf6(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.spvasm
index b42980b..023e1b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cdbcf6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_cdbcf6 = OpFunction %v4float None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_cdbcf6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_cdbcf6
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_cdbcf6
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_cdbcf6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.glsl
index 7c9b699..3bc3dc7 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_cdccd2() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_cdccd2() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
index fcef76d..7f0b511 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_cdccd2() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
index fcef76d..7f0b511 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_cdccd2() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.msl
index b7bf995..6fc29ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_cdccd2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.msl
index 28d6a4b..e4b4a5b 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cdccd2(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.spvasm
index 4770f12..f60e375 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cdccd2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_cdccd2 = OpFunction %v4uint None %10
@@ -59,24 +63,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4uint %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_cdccd2
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_cdccd2
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_cdccd2
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_cdccd2
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.glsl
index bb3c05e..55ff7a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_cdd343() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_cdd343() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_cdd343() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
index f30d226..f4bc067 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_cdd343() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cdd343();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
index f30d226..f4bc067 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_cdd343() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cdd343();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.msl
index 6de543f..26ff463 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_cdd343(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.msl
index c0d456c..545a9cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_cdd343(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.spvasm
index 5b77c53..439c414 100644
--- a/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cdd343.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,18 +68,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cdd343 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,45 +93,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4uint %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_cdd343
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_cdd343
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_cdd343
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_cdd343
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_cdd343
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_cdd343
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
index 443eac0..e83fd64 100644
--- a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cddf6b() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
index 443eac0..e83fd64 100644
--- a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_cddf6b() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.msl
index 6b55db1..60f9023 100644
--- a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_cddf6b(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.msl
index 1402c70..82b5e1b 100644
--- a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_cddf6b(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.spvasm
index 9685bca..020a457 100644
--- a/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cddf6b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_cddf6b = OpFunction %v4float None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_cddf6b
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_cddf6b
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_cddf6b
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_cddf6b
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.glsl
index 51a23ff..43acb91 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_cec477() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_cec477() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
index de61a2a..fdc86b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cec477() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
index de61a2a..fdc86b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_cec477() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.msl
index 296c0d9..83063b2 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_cec477(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.msl
index 78a5515..b38872c 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_cec477(texture3d<int, access::read_write> tint_symbol) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(min(arg_1, (uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.spvasm
index 0be8275..ab03928 100644
--- a/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cec477.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_cec477 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %21 = OpISub %v3uint %20 %16
+         %22 = OpExtInst %v3uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_cec477
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_cec477
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_cec477
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_cec477
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.glsl
index d7f9f8b..8a9b8fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_cece6c() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_cece6c() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_cece6c() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
index 3b2bafe..d6b63f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_cece6c() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cece6c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
index 3b2bafe..d6b63f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_cece6c() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_cece6c();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.msl
index 6691f43..f8b4d1e 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_cece6c(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.msl
index 8da2f48..4a90dfd 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_cece6c(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.spvasm
index 47470a3..6675236 100644
--- a/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/cece6c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_cece6c = OpFunction %v4float None %15
          %16 = OpLabel
@@ -81,43 +85,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_cece6c
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_cece6c
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_cece6c
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_cece6c
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_cece6c
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_cece6c
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.glsl
index 9c0f2aa..60e3f8f 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_d02afc() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_d02afc() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_d02afc() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
index d7fd14c..35afa20 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d02afc() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d02afc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
index d7fd14c..35afa20 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_d02afc() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d02afc();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.msl
index 3359ef2..2183f76 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_d02afc(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.msl
index 82045c1..6c1fe00 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_d02afc(texture3d<int, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.spvasm
index 492c0e1..71bba47 100644
--- a/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d02afc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d02afc = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %29 = OpISub %v3uint %28 %24
+         %30 = OpExtInst %v3uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_d02afc
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_d02afc
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_d02afc
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_d02afc
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_d02afc
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_d02afc
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.glsl
index 6c119b4..48395a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_d0e351() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_d0e351() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
index fb0a813..9f41140 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_d0e351() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
index fb0a813..9f41140 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_d0e351() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.msl
index 3dc1e81..1510cc1 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_d0e351(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.msl
index 3d7960b..90568d1 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d0e351(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.spvasm
index 268235c..d647dd1 100644
--- a/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d0e351.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d0e351 = OpFunction %v4uint None %10
@@ -59,24 +61,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %15
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4uint %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d0e351
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_d0e351
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_d0e351
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_d0e351
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.glsl
index 40f5ec0..83f8237 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d357bb() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0))).zyxw;
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d357bb() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0))).zyxw;
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d357bb() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0))).zyxw;
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
index 737ac0e..7007e90 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d357bb() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d357bb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
index 737ac0e..7007e90 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d357bb() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d357bb();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.msl
index 402e8ee..11d915d 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_d357bb(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.msl
index 916d152..645e7f3 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d357bb(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.spvasm
index 05e1b66..fdf6508 100644
--- a/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d357bb.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 60
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %53 = OpConstantNull %VertexOutput
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d357bb = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,44 +81,48 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-         %24 = OpVectorShuffle %v4float %23 %23 2 1 0 3
-               OpStore %res %24
-         %27 = OpLoad %v4float %res None
-               OpReturnValue %27
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+         %31 = OpVectorShuffle %v4float %30 %30 2 1 0 3
+               OpStore %res %31
+         %34 = OpLoad %v4float %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_d357bb
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %30
+%fragment_main = OpFunction %void None %37
          %38 = OpLabel
          %39 = OpFunctionCall %v4float %textureLoad_d357bb
          %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
+%compute_main = OpFunction %void None %37
          %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %52 = OpFunctionCall %v4float %textureLoad_d357bb
-               OpStore %50 %52 None
-         %53 = OpLoad %VertexOutput %out None
-               OpReturnValue %53
+         %45 = OpFunctionCall %v4float %textureLoad_d357bb
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %30
-         %55 = OpLabel
-         %56 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %57 = OpCompositeExtract %v4float %56 0
-               OpStore %vertex_main_position_Output %57 None
-         %58 = OpCompositeExtract %v4float %56 1
-               OpStore %vertex_main_loc0_Output %58 None
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %57 = OpFunctionCall %v4float %textureLoad_d357bb
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %37
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4float %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
index ca8b41a..7ff77c7 100644
--- a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_d37a08() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
index ca8b41a..7ff77c7 100644
--- a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_d37a08() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.msl
index 0e5ac39..15c150f 100644
--- a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_d37a08(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.msl
index 374bc48..9b849bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d37a08(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.spvasm
index 66b34fa..9b8e26b 100644
--- a/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d37a08.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d37a08 = OpFunction %v4uint None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4uint %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d37a08
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_d37a08
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_d37a08
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_d37a08
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
index cb8e565..bd5b76c 100644
--- a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_d3d8fc() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
index cb8e565..bd5b76c 100644
--- a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_d3d8fc() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.msl
index e04f173..52c7dcc 100644
--- a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_d3d8fc(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.msl
index 614ec8e..ee7b518 100644
--- a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d3d8fc(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.spvasm
index 593faa9..4f45d6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d3d8fc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_d3d8fc = OpFunction %v4int None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %16
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4int %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_d3d8fc
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_d3d8fc
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_d3d8fc
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_d3d8fc
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.glsl
index e411d37..b4c9b98 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_d41c72() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp iimage3D arg_0;
 ivec4 textureLoad_d41c72() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
index fc52443..9688c3e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d41c72() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
index fc52443..9688c3e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d41c72() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.msl
index 27e9968..a293612 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_d41c72(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.msl
index f62476b..f9329f7 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d41c72(texture3d<int, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.spvasm
index 76ec273..4949fdd 100644
--- a/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d41c72.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d41c72 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %22 = OpISub %v3uint %19 %23
+         %25 = OpBitcast %v3uint %18
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_d41c72
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_d41c72
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_d41c72
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_d41c72
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.glsl
index 82e216b..9df78f2 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d4df19() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d4df19() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_d4df19() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
index dcc063c..6710b9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d4df19() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d4df19();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
index dcc063c..6710b9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d4df19() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d4df19();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.msl
index 44e2506..38a3138 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_d4df19(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.msl
index f3d96bc..faf9132 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_d4df19(texture2d<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.spvasm
index 85c6b4a..1b4a8d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d4df19.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d4df19 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %28 = OpISub %v2uint %27 %23
+         %29 = OpExtInst %v2uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d4df19
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_d4df19
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_d4df19
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_d4df19
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_d4df19
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_d4df19
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.glsl
index 1d02570..ba8fd09 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d5c48d() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d5c48d() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d5c48d() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
index d502540..77d6493 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d5c48d() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d5c48d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
index d502540..77d6493 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d5c48d() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d5c48d();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.msl
index c24ba86..7227145 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_d5c48d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.msl
index 2075864..6d48bf7 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d5c48d(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.spvasm
index 2134ebb..9d445d8 100644
--- a/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d5c48d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d5c48d = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_d5c48d
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_d5c48d
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_d5c48d
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_d5c48d
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_d5c48d
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_d5c48d
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
index 5ffcdf9..6fc118c 100644
--- a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d72de9() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
index 5ffcdf9..6fc118c 100644
--- a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d72de9() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.msl
index a184ae7..810a87f 100644
--- a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_d72de9(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.msl
index e00f459..f8d5699 100644
--- a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d72de9(texture2d<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.spvasm
index 9ab4213..dae93a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d72de9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d72de9 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %22 = OpISub %v2uint %19 %23
+         %25 = OpBitcast %v2uint %18
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_d72de9
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_d72de9
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_d72de9
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_d72de9
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
index 240dc23..574e03e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d7996a() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
index 240dc23..574e03e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d7996a() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.msl
index 24b13a4..ed0459c 100644
--- a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_d7996a(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.msl
index 2b348dd..d0f29fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d7996a(texture3d<int, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol.read(uint3(arg_1));
+  int4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.spvasm
index 6ec0eb0..3f04089 100644
--- a/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d7996a.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d7996a = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v3int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v3uint %17
+         %22 = OpISub %v3uint %19 %23
+         %25 = OpBitcast %v3uint %18
+         %26 = OpExtInst %v3uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_d7996a
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_d7996a
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_d7996a
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_d7996a
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
index fc561d0..d9e4bc8 100644
--- a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d79c5c() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
index fc561d0..d9e4bc8 100644
--- a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<uint4> arg_0 : register(u0, space1);
 uint4 textureLoad_d79c5c() {
   int arg_1 = int(1);
-  uint4 res = uint4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  uint4 res = uint4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.msl
index 4841a19..fe52e47 100644
--- a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 uint4 textureLoad_d79c5c(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  uint4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  uint4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.msl
index b4efae9..ae3024d 100644
--- a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_d79c5c(texture1d<uint, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  uint4 res = tint_symbol.read(uint(arg_1));
+  uint4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.spvasm
index 22d3d80..2469563 100644
--- a/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d79c5c.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,9 +40,10 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_d79c5c = OpFunction %v4uint None %10
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4uint %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4uint %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %17
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4uint %16 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4uint %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4uint %textureLoad_d79c5c
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4uint %textureLoad_d79c5c
          %33 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4uint %textureLoad_d79c5c
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
index 3296435..9f98510 100644
--- a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d80ff3() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
index 3296435..9f98510 100644
--- a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_d80ff3() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.msl
index 65ee524..e92fe77 100644
--- a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_d80ff3(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.msl
index 1e303bc..9b44dfe 100644
--- a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d80ff3(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.spvasm
index 5e3d90c..1eb1198 100644
--- a/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d80ff3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %32 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d80ff3 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,23 +54,27 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-         %19 = OpVectorShuffle %v4float %18 %18 2 1 0 3
-               OpStore %res %19
-         %22 = OpLoad %v4float %res None
-               OpReturnValue %22
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
+               OpStore %res %26
+         %29 = OpLoad %v4float %res None
+               OpReturnValue %29
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4float %textureLoad_d80ff3
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %28 %27 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %25
+%fragment_main = OpFunction %void None %32
          %33 = OpLabel
          %34 = OpFunctionCall %v4float %textureLoad_d80ff3
          %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %35 %34 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %32
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4float %textureLoad_d80ff3
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %41 %40 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.glsl
index e680de9..8f8f2c0 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d81c57() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_d81c57() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_d81c57() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
index dcc1f03..21b65bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d81c57() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d81c57();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
index dcc1f03..21b65bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_d81c57() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d81c57();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.msl
index a4a59b2..57fdd88 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_d81c57(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.msl
index 5caa9ef..e334d1d 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d81c57(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.spvasm
index b9481c0..fb604a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d81c57.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d81c57 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +82,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_d81c57
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_d81c57
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_d81c57
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_d81c57
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_d81c57
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.glsl
index dae4daf..289f199 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d85d61() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_d85d61() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_d85d61() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
index 4a593fa..fe5b77f 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d85d61() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d85d61();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
index 4a593fa..fe5b77f 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_d85d61() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d85d61();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.msl
index 03d5a4a..b17ed9b 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_d85d61(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.msl
index 79f1ee5..e064bf5 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_d85d61(texture2d<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.spvasm
index acd5d8c..0583aaa 100644
--- a/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d85d61.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d85d61 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %28 = OpISub %v2uint %27 %23
+         %29 = OpExtInst %v2uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_d85d61
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_d85d61
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_d85d61
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_d85d61
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_d85d61
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_d85d61
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.glsl
index a9273d8..2038615 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_d8617f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_d8617f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 ivec4 textureLoad_d8617f() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
index f6d716a..e8028f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_d8617f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d8617f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
index f6d716a..e8028f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_d8617f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_d8617f();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.msl
index 3dab0f6..efad0ae 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_d8617f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.msl
index 69aa5c3..238fb88 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d8617f(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.spvasm
index e53b928..3e1b128 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d8617f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,20 +67,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_d8617f = OpFunction %v4int None %18
          %19 = OpLabel
@@ -90,44 +94,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %31 = OpCompositeConstruct %v3int %28 %29
-         %32 = OpImageRead %v4int %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %29
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %27
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %28
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4int %27 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4int %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_d8617f
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_d8617f
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_d8617f
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4int %textureLoad_d8617f
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4int %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_d8617f
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
index e601e48..524d063 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d8be5a() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
index e601e48..524d063 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_d8be5a() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.msl
index d46e1cc..b5de2cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_d8be5a(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.msl
index 311e4fb..3f07d38 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_d8be5a(texture1d<int, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.spvasm
index d70ce42..36636bf 100644
--- a/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d8be5a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -37,11 +39,12 @@
          %10 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_d8be5a = OpFunction %v4int None %10
          %11 = OpLabel
@@ -50,22 +53,26 @@
                OpStore %arg_1 %int_1
          %15 = OpLoad %8 %arg_0 None
          %16 = OpLoad %int %arg_1 None
-         %17 = OpImageRead %v4int %15 %16 None
-               OpStore %res %17
-         %20 = OpLoad %v4int %res None
-               OpReturnValue %20
+         %17 = OpImageQuerySize %uint %15
+         %19 = OpISub %uint %17 %uint_1
+         %21 = OpBitcast %uint %16
+         %22 = OpExtInst %uint %23 UMin %21 %19
+         %24 = OpImageRead %v4int %15 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %23
-         %24 = OpLabel
-         %25 = OpFunctionCall %v4int %textureLoad_d8be5a
-         %26 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %26 %25 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %23
+%fragment_main = OpFunction %void None %30
          %31 = OpLabel
          %32 = OpFunctionCall %v4int %textureLoad_d8be5a
          %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_d8be5a
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
index dafaa85..3a46139 100644
--- a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_d91f37() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
index dafaa85..3a46139 100644
--- a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_d91f37() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.msl
index d2db707..6acb388 100644
--- a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_d91f37(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.msl
index 6d1ced9..89f5e6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_d91f37(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.spvasm
index 1fca744..8cc4f29 100644
--- a/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/d91f37.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_d91f37 = OpFunction %v4float None %10
@@ -59,24 +63,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2int %arg_1 None
          %24 = OpLoad %uint %arg_2 None
-         %25 = OpBitcast %int %24
-         %27 = OpCompositeConstruct %v3int %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpExtInst %uint %30 UMin %24 %28
+         %31 = OpImageQuerySize %v3uint %22
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %23
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4float %22 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_d91f37
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_d91f37
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_d91f37
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_d91f37
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
index e4998cd..e8ee75e 100644
--- a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_dab04f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
index e4998cd..e8ee75e 100644
--- a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_dab04f() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.msl
index e8afeae..4a906d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_dab04f(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.msl
index e6428c6..47ce2db 100644
--- a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_dab04f(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.spvasm
index e1c4e2f..a105949 100644
--- a/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dab04f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 57
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %47 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_dab04f = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,24 +63,34 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+         %41 = OpVectorShuffle %v4float %40 %40 2 1 0 3
+               OpStore %res %41
+         %44 = OpLoad %v4float %res None
+               OpReturnValue %44
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_dab04f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %47
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_dab04f
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_dab04f
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %47
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4float %textureLoad_dab04f
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.glsl
index 38279e7..62c5b01 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dbd554() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dbd554() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_dbd554() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
index 1d24ab6..2344ef5 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dbd554() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dbd554();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
index 1d24ab6..2344ef5 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dbd554() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dbd554();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.msl
index 619b558..74ab217 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_dbd554(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.msl
index e47fd4c..9fcd2ec 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_dbd554(texture2d<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.spvasm
index 2da1cd9..9dfb963 100644
--- a/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dbd554.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dbd554 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %30 = OpISub %v2uint %27 %31
+         %33 = OpBitcast %v2uint %26
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_dbd554
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_dbd554
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_dbd554
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_dbd554
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_dbd554
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_dbd554
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
index 6f8e25c..df8b8df 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_dd5859() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
index 6f8e25c..df8b8df 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_dd5859() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.msl
index 86101f0..6746b8d 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_dd5859(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.msl
index 12dc8a4..f2c92a8 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_dd5859(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.spvasm
index 947c9a0..90d2d4c 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dd5859.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_dd5859 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_dd5859
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_dd5859
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_dd5859
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_dd5859
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.glsl
index 9bc66b7..ace7e6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_dd8776() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_dd8776() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_dd8776() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
index 48df390..49ceee5 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_dd8776() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dd8776();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
index 48df390..49ceee5 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_dd8776() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dd8776();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.msl
index f913d9b..837179e 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_dd8776(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.msl
index 07b954a..10a797d 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_dd8776(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.spvasm
index 0e976ec..58feb72 100644
--- a/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dd8776.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,14 +68,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dd8776 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -85,44 +87,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_dd8776
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_dd8776
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_dd8776
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_dd8776
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_dd8776
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_dd8776
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.glsl
index 81632c0..2a13af6 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_ddeed3() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_ddeed3() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_ddeed3() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
index 95afd91..2429294 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ddeed3() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ddeed3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
index 95afd91..2429294 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ddeed3() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ddeed3();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.msl
index af9541e..575fd05 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_ddeed3(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.msl
index ce96426..f6b76aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ddeed3(texture1d<int, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.spvasm
index 3a8ff29..a1dbac6 100644
--- a/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ddeed3.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ddeed3 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageRead %v4int %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4int %23 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_ddeed3
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4int %textureLoad_ddeed3
          %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_ddeed3
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4int %textureLoad_ddeed3
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_ddeed3
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
index 592a366..dd32ec1 100644
--- a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_de5a0e() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
index 592a366..dd32ec1 100644
--- a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 int4 textureLoad_de5a0e() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.msl
index 9811039..4998da6 100644
--- a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_de5a0e(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.msl
index c608cef..7e0ddae 100644
--- a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_de5a0e(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.spvasm
index 05ef2c4..a4b8528 100644
--- a/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/de5a0e.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -44,7 +46,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_de5a0e = OpFunction %v4int None %10
@@ -57,23 +59,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4int %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4int %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4int %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_de5a0e
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_de5a0e
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_de5a0e
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4int %textureLoad_de5a0e
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.glsl
index 5270f3a..eb8e2bb 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dee8e7() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_dee8e7() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_dee8e7() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
index f3171b3..303ffcf 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dee8e7() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dee8e7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
index f3171b3..303ffcf 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_dee8e7() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dee8e7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.msl
index 7e1734c..b401f3f 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_dee8e7(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.msl
index 4f8e239..e568b05 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_dee8e7(texture2d<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.spvasm
index 369cb6a..94c2077 100644
--- a/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dee8e7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dee8e7 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %30 = OpISub %v2uint %27 %31
+         %33 = OpBitcast %v2uint %26
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_dee8e7
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_dee8e7
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_dee8e7
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_dee8e7
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_dee8e7
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_dee8e7
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.glsl
index 6899be0c..6ca5437 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_defd9a() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp image2D arg_0;
 vec4 textureLoad_defd9a() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
index 9af1ab1..824af30 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_defd9a() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
index 9af1ab1..824af30 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_defd9a() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.msl
index 151d995..c601a5e 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_defd9a(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.msl
index 7c24f0d..470daec 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_defd9a(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.spvasm
index 8c18229..af899e4 100644
--- a/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/defd9a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,11 +42,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_defd9a = OpFunction %v4float None %10
          %11 = OpLabel
@@ -53,22 +58,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_defd9a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_defd9a
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_defd9a
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_defd9a
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.glsl
index 0555dd0..4e1d516 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_dfdf3b() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_dfdf3b() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_dfdf3b() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
index 3454a29..13c325d 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_dfdf3b() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dfdf3b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
index 3454a29..13c325d 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 int4 textureLoad_dfdf3b() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_dfdf3b();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.msl
index 9e81776..116be09 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 int4 textureLoad_dfdf3b(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.msl
index 0ed75f7..aa22964 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.msl
@@ -4,7 +4,7 @@
 int4 textureLoad_dfdf3b(texture2d_array<int, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.spvasm
index 04d86d0..3d407f6 100644
--- a/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/dfdf3b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -68,15 +70,15 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_dfdf3b = OpFunction %v4int None %18
          %19 = OpLabel
@@ -88,44 +90,52 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2uint %arg_1 None
          %30 = OpLoad %uint %arg_2 None
-         %32 = OpCompositeConstruct %v3uint %29 %30
-         %33 = OpImageRead %v4int %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4int %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %35 = OpExtInst %uint %36 UMin %30 %34
+         %37 = OpImageQuerySize %v3uint %28
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %24
+         %40 = OpExtInst %v2uint %36 UMin %29 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4int %28 %41 None
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_dfdf3b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_dfdf3b
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_dfdf3b
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_dfdf3b
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %60 = OpFunctionCall %v4int %textureLoad_dfdf3b
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_dfdf3b
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4int %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
index 7e6d71f..de53d3d 100644
--- a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e1c3cf() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
index 7e6d71f..de53d3d 100644
--- a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e1c3cf() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.msl
index b5acd67..040f428 100644
--- a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_e1c3cf(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.msl
index f655980..b1a4152 100644
--- a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e1c3cf(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.spvasm
index 41f3ca6..0b2edd3 100644
--- a/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e1c3cf.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_e1c3cf = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_e1c3cf
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_e1c3cf
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_e1c3cf
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_e1c3cf
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.glsl
index b94650e..9be9b00 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_e2292f() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_e2292f() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e2292f() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
index 52307d2..dd93feb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e2292f() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e2292f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
index 52307d2..dd93feb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e2292f() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e2292f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.msl
index a629533..13f72a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_e2292f(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.msl
index abb2025..78795e7 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_e2292f(texture1d<int, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.spvasm
index 12239d6..e981ccb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e2292f.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e2292f = OpFunction %v4int None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageRead %v4int %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageRead %v4int %24 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_e2292f
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_e2292f
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_e2292f
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_e2292f
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_e2292f
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_e2292f
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.glsl
index cf9dd16..de6d5ba 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_e2b3a1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_e2b3a1() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
index a5d8068..e6ae98e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_e2b3a1() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
index a5d8068..e6ae98e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_e2b3a1() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.msl
index ea1e823..45b7b58 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 int4 textureLoad_e2b3a1(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.msl
index 3b7104d..67eb66b 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e2b3a1(texture2d_array<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.spvasm
index c30b5b9..c44b0c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e2b3a1.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_e2b3a1 = OpFunction %v4int None %10
@@ -59,24 +61,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %16
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4int %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_e2b3a1
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_e2b3a1
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_e2b3a1
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_e2b3a1
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
index 2da0136..3fb33ba 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_e2d7da() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
index 2da0136..3fb33ba 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_e2d7da() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.msl
index 5779c20..33a0fcb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_e2d7da(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.msl
index 51f3b23..17e40f8 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e2d7da(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.spvasm
index ee9d5bb..41908ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e2d7da.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_e2d7da = OpFunction %v4float None %10
@@ -59,24 +61,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_e2d7da
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_e2d7da
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_e2d7da
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_e2d7da
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
index 0aa71dc..0b378a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e33285() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
index 0aa71dc..0b378a4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_e33285() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.msl
index d6c07bd..6baaab7 100644
--- a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 int4 textureLoad_e33285(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.msl
index d0c5f32..126717b 100644
--- a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e33285(texture2d<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.spvasm
index 3795760..fdb2247 100644
--- a/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e33285.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_e33285 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -51,22 +56,26 @@
                OpStore %arg_1 %15
          %17 = OpLoad %8 %arg_0 None
          %18 = OpLoad %v2int %arg_1 None
-         %19 = OpImageRead %v4int %17 %18 None
-               OpStore %res %19
-         %22 = OpLoad %v4int %res None
-               OpReturnValue %22
+         %19 = OpImageQuerySize %v2uint %17
+         %22 = OpISub %v2uint %19 %23
+         %25 = OpBitcast %v2uint %18
+         %26 = OpExtInst %v2uint %27 UMin %25 %22
+         %28 = OpImageRead %v4int %17 %26 None
+               OpStore %res %28
+         %31 = OpLoad %v4int %res None
+               OpReturnValue %31
                OpFunctionEnd
-%fragment_main = OpFunction %void None %25
-         %26 = OpLabel
-         %27 = OpFunctionCall %v4int %textureLoad_e33285
-         %28 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %28 %27 None
+%fragment_main = OpFunction %void None %34
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_e33285
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %25
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_e33285
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %34
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4int %textureLoad_e33285
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.glsl
index bf14c5a..7d60782 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_e35f72() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler3D arg_0;
 ivec4 textureLoad_e35f72() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec3 v_2 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec3 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_4 = (uvec3(textureSize(arg_0, int(v_3))) - uvec3(1u));
+  ivec3 v_5 = ivec3(min(uvec3(v_2), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler3D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e35f72() {
   ivec3 arg_1 = ivec3(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec3 v_1 = ivec3(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec3 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec3 v_3 = (uvec3(textureSize(arg_0, int(v_2))) - uvec3(1u));
+  ivec3 v_4 = ivec3(min(uvec3(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
index 11d9a43..e545797 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_e35f72() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e35f72();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
index 11d9a43..e545797 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_e35f72() {
   int3 arg_1 = (int(1)).xxx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int3 v_1 = int3(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v))));
+  int3 v = arg_1;
+  uint4 v_1 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z, v_1.w);
+  uint v_2 = min(arg_2, (v_1.w - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 v_4 = (v_3.xyz - (1u).xxx);
+  int3 v_5 = int3(min(uint3(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e35f72();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.msl
index ea45999..6fe378b 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_e35f72(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1), v);
+  int3 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint3 const v_2 = (uint3(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1), tint_module_vars.arg_0.get_depth(v_1)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.msl
index 6cf6f13..5f0aea9 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e35f72(texture3d<int, access::sample> tint_symbol_1) {
   int3 arg_1 = int3(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint3(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx)) - uint3(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.spvasm
index 6dafea0..6cc3d1b 100644
--- a/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e35f72.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v3uint = OpTypeVector %uint 3
+         %39 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e35f72 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v3int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %31 %33
+         %36 = OpImageQuerySizeLod %v3uint %29 %34
+         %38 = OpISub %v3uint %36 %39
+         %40 = OpBitcast %v3uint %30
+         %41 = OpExtInst %v3uint %35 UMin %40 %38
+         %42 = OpImageFetch %v4int %29 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_e35f72
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_e35f72
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_e35f72
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_e35f72
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_e35f72
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_e35f72
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.glsl
index 3d359f4..13976f0 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_e3b08b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_e3b08b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e3b08b() {
   uvec3 arg_1 = uvec3(1u);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
index 21775a6..13ccd10 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e3b08b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3b08b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
index 21775a6..13ccd10 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e3b08b() {
   uint3 arg_1 = (1u).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  float4 res = float4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3b08b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.msl
index 2a13f82..d57b019 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_e3b08b(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.msl
index 7030148..ba137b9 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_e3b08b(texture3d<float, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.spvasm
index 313761d..03ccdc5 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e3b08b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e3b08b = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %26 = OpISub %v3uint %25 %21
+         %27 = OpExtInst %v3uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_e3b08b
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_e3b08b
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_e3b08b
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_e3b08b
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_e3b08b
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_e3b08b
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.glsl
index e43ee83..4aaf5a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 ivec4 textureLoad_e3d2cc() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 ivec4 textureLoad_e3d2cc() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uvec2 v_3 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 ivec4 textureLoad_e3d2cc() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uvec2 v_2 = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(v), v_2));
+  ivec4 res = texelFetch(arg_0, v_3, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
index b2c9440..e4602b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  int4 res = int4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3d2cc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
index b2c9440..e4602b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,11 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint2 v_2 = (v_1.xy - (1u).xx);
+  int2 v_3 = int2(min(uint2(arg_1), v_2));
+  int4 res = int4(arg_0.Load(v_3, int(v)));
   return res;
 }
 
@@ -33,13 +36,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e3d2cc();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.msl
index 1a5e758..bb19c7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_e3d2cc(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  int const v_1 = arg_2;
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.msl
index bcef40a..ad6f948 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e3d2cc(texture2d_ms<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.spvasm
index efd695e..510cf35 100644
--- a/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e3d2cc.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %49 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %61 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %64 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e3d2cc = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,47 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4int %27 %28 Sample %29
-               OpStore %res %30
-         %33 = OpLoad %v4int %res None
-               OpReturnValue %33
+         %30 = OpImageQuerySize %v2uint %27
+         %33 = OpISub %v2uint %30 %34
+         %36 = OpBitcast %v2uint %28
+         %37 = OpExtInst %v2uint %38 UMin %36 %33
+         %39 = OpImageFetch %v4int %27 %37 Sample %29
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4int %textureLoad_e3d2cc
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_e3d2cc
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4int %textureLoad_e3d2cc
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_e3d2cc
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_e3d2cc
-               OpStore %57 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %64 None
+         %65 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %66 = OpFunctionCall %v4int %textureLoad_e3d2cc
+               OpStore %65 %66 None
+         %67 = OpLoad %VertexOutput %out None
+               OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %45
+         %69 = OpLabel
+         %70 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %71 = OpCompositeExtract %v4float %70 0
+               OpStore %vertex_main_position_Output %71 None
+         %72 = OpCompositeExtract %v4int %70 1
+               OpStore %vertex_main_loc0_Output %72 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.glsl
index 8dc4594..71f2d66 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_e4051a() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp image2D arg_0;
 vec4 textureLoad_e4051a() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
index c528091..ce5223d 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e4051a() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
index c528091..ce5223d 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_e4051a() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.msl
index a79adde..8c332e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_e4051a(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.msl
index c664656..414460f 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_e4051a(texture2d<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.spvasm
index 92ed53d..831640e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e4051a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,7 +44,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_e4051a = OpFunction %v4float None %10
@@ -52,22 +54,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4float %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4float %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_e4051a
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4float %textureLoad_e4051a
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_e4051a
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4float %textureLoad_e4051a
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.glsl
index 43da60b..e2c854a 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 vec4 textureLoad_e57e92() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4))).zyxw;
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 vec4 textureLoad_e57e92() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1))).zyxw;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  ivec2 v_5 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_4))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 vec4 textureLoad_e57e92() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v))).zyxw;
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  ivec2 v_4 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
index f5f9dbb..41cf8f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_e57e92() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e57e92();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
index f5f9dbb..41cf8f4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 float4 textureLoad_e57e92() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e57e92();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.msl
index 4b5a2b8..8f88556 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_e57e92(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.msl
index 3c70342..197db1c 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e57e92(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.spvasm
index 36f183e..ab99ab3 100644
--- a/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e57e92.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,14 +69,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %49 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %52 = OpTypeFunction %VertexOutput
+         %61 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %56 = OpConstantNull %VertexOutput
-         %58 = OpConstantNull %v4float
+         %65 = OpConstantNull %VertexOutput
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e57e92 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,46 +88,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpBitcast %uint %29
-         %32 = OpCompositeConstruct %v3uint %28 %30
-         %33 = OpImageRead %v4float %27 %32 None
-         %34 = OpVectorShuffle %v4float %33 %33 2 1 0 3
-               OpStore %res %34
-         %37 = OpLoad %v4float %res None
-               OpReturnValue %37
+         %30 = OpImageQuerySize %v3uint %27
+         %32 = OpCompositeExtract %uint %30 2
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %29
+         %35 = OpExtInst %uint %36 UMin %34 %33
+         %37 = OpImageQuerySize %v3uint %27
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %39 = OpISub %v2uint %38 %21
+         %40 = OpExtInst %v2uint %36 UMin %28 %39
+         %41 = OpCompositeConstruct %v3uint %40 %35
+         %42 = OpImageRead %v4float %27 %41 None
+         %43 = OpVectorShuffle %v4float %42 %42 2 1 0 3
+               OpStore %res %43
+         %46 = OpLoad %v4float %res None
+               OpReturnValue %46
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_e57e92
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %49
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_e57e92
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
-         %47 = OpLabel
-         %48 = OpFunctionCall %v4float %textureLoad_e57e92
-         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %49 %48 None
+%compute_main = OpFunction %void None %49
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4float %textureLoad_e57e92
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %52
-         %53 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %56
-         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %57 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %60 = OpFunctionCall %v4float %textureLoad_e57e92
-               OpStore %59 %60 None
-         %61 = OpLoad %VertexOutput %out None
-               OpReturnValue %61
+%vertex_main_inner = OpFunction %VertexOutput None %61
+         %62 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %65
+         %66 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %66 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %69 = OpFunctionCall %v4float %textureLoad_e57e92
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
-         %63 = OpLabel
-         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %65 = OpCompositeExtract %v4float %64 0
-               OpStore %vertex_main_position_Output %65 None
-         %66 = OpCompositeExtract %v4float %64 1
-               OpStore %vertex_main_loc0_Output %66 None
+%vertex_main = OpFunction %void None %49
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4float %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.glsl
index e28d716..b6e9aae 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_e59fdf() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_e59fdf() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_e59fdf() {
   uvec3 arg_1 = uvec3(1u);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
index b1a4220..4f356d7 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_e59fdf() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e59fdf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
index b1a4220..4f356d7 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_e59fdf() {
   uint3 arg_1 = (1u).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e59fdf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.msl
index abec8db..1d0aa9a 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_e59fdf(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.msl
index 39c5160..f28ec0c 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_e59fdf(texture3d<uint, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.spvasm
index defca33..c8f43bd 100644
--- a/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e59fdf.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %23 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e59fdf = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %28 = OpISub %v3uint %27 %23
+         %29 = OpExtInst %v3uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_e59fdf
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_e59fdf
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_e59fdf
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_e59fdf
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_e59fdf
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_e59fdf
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.glsl
index d12569b..0006cc9 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_e65916() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_e65916() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_e65916() {
   ivec3 arg_1 = ivec3(1);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  ivec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
index 8dacb5c..95b91bb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e65916() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e65916();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
index 8dacb5c..95b91bb 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_e65916() {
   int3 arg_1 = (int(1)).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  int4 res = int4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e65916();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.msl
index b5a3a55..616cb7e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_e65916(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  int4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.msl
index ea1e385..a919f37 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_e65916(texture3d<int, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.spvasm
index 09e4abc5..7b79c8a 100644
--- a/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e65916.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,19 +65,21 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e65916 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -84,43 +88,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v3int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v3uint %25
+         %30 = OpISub %v3uint %27 %31
+         %33 = OpBitcast %v3uint %26
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_e65916
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_e65916
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_e65916
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_e65916
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_e65916
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_e65916
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.glsl
index 2459e6a..6065cd4 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e893d7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e893d7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e893d7() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
index eeed6f8..bbbfb66 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e893d7() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e893d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
index eeed6f8..bbbfb66 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e893d7() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e893d7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.msl
index 7222b68..2ac8768 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_e893d7(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.msl
index bb9e7e5..653d6df 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_e893d7(texture2d<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.spvasm
index 7ddc7b4..0771355 100644
--- a/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e893d7.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e893d7 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %28 = OpISub %v2uint %25 %29
+         %31 = OpBitcast %v2uint %24
+         %32 = OpExtInst %v2uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_e893d7
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_e893d7
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_e893d7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_e893d7
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_e893d7
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_e893d7
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.glsl
index 4458065..b2564e0 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e92dd0() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_e92dd0() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_e92dd0() {
   uint arg_1 = 1u;
-  vec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
index a74e736..81eb62e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e92dd0() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e92dd0();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
index a74e736..81eb62e 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_e92dd0() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_e92dd0();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.msl
index b75ec09..d621112 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_e92dd0(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.msl
index af7a9e1..46d716c 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_e92dd0(texture1d<float, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.spvasm
index ef28038..d8f7fb1 100644
--- a/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e92dd0.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 57
+; Bound: 61
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,14 +63,14 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %33 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %41 = OpTypeFunction %VertexOutput
+         %45 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %45 = OpConstantNull %VertexOutput
-         %47 = OpConstantNull %v4float
+         %49 = OpConstantNull %VertexOutput
+         %51 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_e92dd0 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -77,43 +79,46 @@
                OpStore %arg_1 %uint_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %uint %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpExtInst %uint %26 UMin %22 %24
+         %27 = OpImageRead %v4float %21 %25 None
+               OpStore %res %27
+         %30 = OpLoad %v4float %res None
+               OpReturnValue %30
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_e92dd0
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
+%fragment_main = OpFunction %void None %33
+         %34 = OpLabel
+         %35 = OpFunctionCall %v4float %textureLoad_e92dd0
+         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %36 %35 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %29
-         %36 = OpLabel
-         %37 = OpFunctionCall %v4float %textureLoad_e92dd0
-         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %38 %37 None
+%compute_main = OpFunction %void None %33
+         %40 = OpLabel
+         %41 = OpFunctionCall %v4float %textureLoad_e92dd0
+         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %42 %41 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %41
-         %42 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %45
-         %46 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %46 %47 None
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %49 = OpFunctionCall %v4float %textureLoad_e92dd0
-               OpStore %48 %49 None
-         %50 = OpLoad %VertexOutput %out None
-               OpReturnValue %50
+%vertex_main_inner = OpFunction %VertexOutput None %45
+         %46 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %49
+         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %50 %51 None
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %53 = OpFunctionCall %v4float %textureLoad_e92dd0
+               OpStore %52 %53 None
+         %54 = OpLoad %VertexOutput %out None
+               OpReturnValue %54
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %52 = OpLabel
-         %53 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %54 = OpCompositeExtract %v4float %53 0
-               OpStore %vertex_main_position_Output %54 None
-         %55 = OpCompositeExtract %v4float %53 1
-               OpStore %vertex_main_loc0_Output %55 None
+%vertex_main = OpFunction %void None %33
+         %56 = OpLabel
+         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %58 = OpCompositeExtract %v4float %57 0
+               OpStore %vertex_main_position_Output %58 None
+         %59 = OpCompositeExtract %v4float %57 1
+               OpStore %vertex_main_loc0_Output %59 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
index 946e637..f3f8dab 100644
--- a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_e9eb65() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
index 946e637..f3f8dab 100644
--- a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_e9eb65() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.msl
index 1f2ee4f..40513c5 100644
--- a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 uint4 textureLoad_e9eb65(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.msl
index 2bc4f30..b8c6025 100644
--- a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_e9eb65(texture2d_array<uint, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.spvasm
index c17f316..c0a7a22 100644
--- a/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/e9eb65.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 52
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_e9eb65 = OpFunction %v4uint None %10
@@ -58,24 +60,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2uint %arg_1 None
          %23 = OpLoad %int %arg_2 None
-         %24 = OpBitcast %uint %23
-         %26 = OpCompositeConstruct %v3uint %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpBitcast %uint %23
+         %29 = OpExtInst %uint %30 UMin %28 %27
+         %31 = OpImageQuerySize %v3uint %21
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %33 = OpISub %v2uint %32 %15
+         %34 = OpExtInst %v2uint %30 UMin %22 %33
+         %35 = OpCompositeConstruct %v3uint %34 %29
+         %36 = OpImageRead %v4uint %21 %35 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_e9eb65
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_e9eb65
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_e9eb65
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_e9eb65
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.glsl
index bd83e00..8713431 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_ea2abd() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba32f) uniform highp readonly image2D arg_0;
 vec4 textureLoad_ea2abd() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_ea2abd() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
index c1500ab5..ff2db65 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ea2abd() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ea2abd();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
index c1500ab5..ff2db65 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_ea2abd() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ea2abd();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.msl
index 36a339e..21c69d5 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_ea2abd(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.msl
index 6518260..9ddae2c 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_ea2abd(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.spvasm
index 8721ebe..900f492 100644
--- a/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ea2abd.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ea2abd = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_ea2abd
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_ea2abd
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_ea2abd
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_ea2abd
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_ea2abd
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_ea2abd
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.glsl
index e5ff4ea..18333c6 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_eb573b() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_eb573b() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_eb573b() {
   ivec2 arg_1 = ivec2(1);
-  ivec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  ivec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
index 99d23b6..2922259 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_eb573b() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eb573b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
index 99d23b6..2922259 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_eb573b() {
   int2 arg_1 = (int(1)).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  int4 res = int4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eb573b();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.msl
index f391bf8..7d8a00e 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_eb573b(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.msl
index c27c4bb..7f675ad 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_eb573b(texture2d<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  int4 res = tint_symbol_1.read(uint2(arg_1));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.spvasm
index a4d6328..c3bd04d 100644
--- a/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/eb573b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_eb573b = OpFunction %v4int None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
-         %27 = OpImageRead %v4int %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %30 = OpISub %v2uint %27 %31
+         %33 = OpBitcast %v2uint %26
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4int %25 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4int %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_eb573b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_eb573b
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_eb573b
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_eb573b
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %56 = OpFunctionCall %v4int %textureLoad_eb573b
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %63 = OpFunctionCall %v4int %textureLoad_eb573b
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4int %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4int %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.glsl
index 43517fc..a1d3786 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_ebfb92() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   uvec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp usampler2D arg_0;
 uvec4 textureLoad_ebfb92() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  uvec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   uvec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp usampler2D arg_0;
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ebfb92() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  uvec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
index 762eb81..bb223d7 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_ebfb92() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ebfb92();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
index 762eb81..bb223d7 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_ebfb92() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ebfb92();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.msl
index 918fd92..4b73bd3 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_ebfb92(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.msl
index 8a0c23d..eb5a5f5 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ebfb92(texture2d<uint, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.spvasm
index 88ade25..7d2020f 100644
--- a/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ebfb92.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ebfb92 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +91,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %31 %33
+         %36 = OpImageQuerySizeLod %v2uint %29 %34
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %30
+         %41 = OpExtInst %v2uint %35 UMin %40 %38
+         %42 = OpImageFetch %v4uint %29 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4uint %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_ebfb92
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_ebfb92
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_ebfb92
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4uint %textureLoad_ebfb92
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_ebfb92
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %69 = OpFunctionCall %v4uint %textureLoad_ebfb92
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4uint %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.glsl
index 2f8c49e..1d48868 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_ecc823() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_ecc823() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ecc823() {
   ivec2 arg_1 = ivec2(1);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v = arg_1;
+  uvec2 v_1 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  uvec4 res = imageLoad(arg_0, ivec2(min(uvec2(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
index 04759c8..d963eb5 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ecc823() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ecc823();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
index 04759c8..d963eb5 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ecc823() {
   int2 arg_1 = (int(1)).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ecc823();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.msl
index 6b8141a..51f0f0c 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_ecc823(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.msl
index 941a0db..6d28bdd 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ecc823(texture2d<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.spvasm
index c758d51..b5f1231 100644
--- a/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ecc823.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ecc823 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v2int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v2uint %26
+         %30 = OpISub %v2uint %28 %31
+         %33 = OpBitcast %v2uint %27
+         %34 = OpExtInst %v2uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_ecc823
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_ecc823
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_ecc823
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_ecc823
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_ecc823
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_ecc823
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.glsl
index 86b894c..e609475 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 ivec4 textureLoad_ed55a8() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 ivec4 textureLoad_ed55a8() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
index b33e2f5..69e45cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_ed55a8() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
index b33e2f5..69e45cd 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 int4 textureLoad_ed55a8() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  int4 res = int4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.msl
index 2066556..2ea8394 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_ed55a8(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.msl
index b2fc631..f936395 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_ed55a8(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.spvasm
index 0ca754b..2381189 100644
--- a/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ed55a8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -43,10 +45,12 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_ed55a8 = OpFunction %v4int None %10
@@ -59,24 +63,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4int %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4int %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4int %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4int %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4int %textureLoad_ed55a8
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_ed55a8
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4int %textureLoad_ed55a8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4int %textureLoad_ed55a8
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.glsl
index 2a9967a..8f52573 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_ee33c5() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage3D arg_0;
 ivec4 textureLoad_ee33c5() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v_1, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_ee33c5() {
   uvec3 arg_1 = uvec3(1u);
-  ivec4 res = imageLoad(arg_0, ivec3(arg_1));
+  uvec3 v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec3(min(v, (uvec3(imageSize(arg_0)) - uvec3(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
index 01e0b4d..7e6cf7d 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ee33c5() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ee33c5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
index 01e0b4d..7e6cf7d 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture3D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_ee33c5() {
   uint3 arg_1 = (1u).xxx;
-  int4 res = int4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  int4 res = int4(arg_0.Load(int4(int3(min(arg_1, (v - (1u).xxx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ee33c5();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.msl
index f92c132..fcb8aa0 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_ee33c5(tint_module_vars_struct tint_module_vars) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint3 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.msl
index 7c801b7..c047410 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_ee33c5(texture3d<int, access::read> tint_symbol_1) {
   uint3 arg_1 = uint3(1u);
-  int4 res = tint_symbol_1.read(uint3(arg_1));
+  int4 res = tint_symbol_1.read(uint3(min(arg_1, (uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.spvasm
index f9316ab..58c4ff2 100644
--- a/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ee33c5.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 63
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
          %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %46 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ee33c5 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,46 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3uint %arg_1 None
-         %28 = OpImageRead %v4int %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4int %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %29 = OpISub %v3uint %28 %24
+         %30 = OpExtInst %v3uint %31 UMin %27 %29
+         %32 = OpImageRead %v4int %26 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4int %textureLoad_ee33c5
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %38
+         %39 = OpLabel
+         %40 = OpFunctionCall %v4int %textureLoad_ee33c5
+         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4int %textureLoad_ee33c5
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %38
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4int %textureLoad_ee33c5
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %55 = OpFunctionCall %v4int %textureLoad_ee33c5
-               OpStore %54 %55 None
-         %56 = OpLoad %VertexOutput %out None
-               OpReturnValue %56
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_ee33c5
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %58 = OpLabel
-         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %60 = OpCompositeExtract %v4float %59 0
-               OpStore %vertex_main_position_Output %60 None
-         %61 = OpCompositeExtract %v4int %59 1
-               OpStore %vertex_main_loc0_Output %61 None
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.glsl
index e8eeb91..1799b79 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.glsl
@@ -10,9 +10,12 @@
 uvec4 textureLoad_eecf7d() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +31,12 @@
 uvec4 textureLoad_eecf7d() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_1), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +56,12 @@
 uvec4 textureLoad_eecf7d() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  uvec2 v_3 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v), v_3));
+  uvec4 res = imageLoad(arg_0, ivec3(v_4, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +71,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
index 3c06984..555db78 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_eecf7d() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eecf7d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
index 3c06984..555db78 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,14 @@
 uint4 textureLoad_eecf7d() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +38,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_eecf7d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_5 = tint_symbol;
+  return v_5;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_6 = vertex_main_inner();
+  vertex_main_outputs v_7 = {v_6.prevent_dce, v_6.pos};
+  return v_7;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.msl
index 9a9f41d..4334c32 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_eecf7d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.msl
index bef82ef..b3c59ed 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_eecf7d(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.spvasm
index 6deb562..e0452cb 100644
--- a/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/eecf7d.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 70
+; Bound: 81
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %37 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,18 +69,20 @@
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %42 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %52 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %53 = OpTypeFunction %VertexOutput
+         %64 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
+         %68 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %60 = OpConstantNull %v4float
+         %71 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_eecf7d = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -90,45 +94,53 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpBitcast %int %31
-         %34 = OpCompositeConstruct %v3int %30 %32
-         %35 = OpImageRead %v4uint %29 %34 None
-               OpStore %res %35
-         %38 = OpLoad %v4uint %res None
-               OpReturnValue %38
+         %32 = OpImageQuerySize %v3uint %29
+         %34 = OpCompositeExtract %uint %32 2
+         %35 = OpISub %uint %34 %uint_1
+         %36 = OpExtInst %uint %37 UMin %31 %35
+         %38 = OpImageQuerySize %v3uint %29
+         %39 = OpVectorShuffle %v2uint %38 %38 0 1
+         %41 = OpISub %v2uint %39 %42
+         %43 = OpBitcast %v2uint %30
+         %44 = OpExtInst %v2uint %37 UMin %43 %41
+         %45 = OpCompositeConstruct %v3uint %44 %36
+         %46 = OpImageRead %v4uint %29 %45 None
+               OpStore %res %46
+         %49 = OpLoad %v4uint %res None
+               OpReturnValue %49
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4uint %textureLoad_eecf7d
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %52
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4uint %textureLoad_eecf7d
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4uint %textureLoad_eecf7d
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %52
+         %59 = OpLabel
+         %60 = OpFunctionCall %v4uint %textureLoad_eecf7d
+         %61 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %61 %60 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %60 None
-         %61 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %62 = OpFunctionCall %v4uint %textureLoad_eecf7d
-               OpStore %61 %62 None
-         %63 = OpLoad %VertexOutput %out None
-               OpReturnValue %63
-               OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main_inner = OpFunction %VertexOutput None %64
          %65 = OpLabel
-         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %67 = OpCompositeExtract %v4float %66 0
-               OpStore %vertex_main_position_Output %67 None
-         %68 = OpCompositeExtract %v4uint %66 1
-               OpStore %vertex_main_loc0_Output %68 None
+        %out = OpVariable %_ptr_Function_VertexOutput Function %68
+         %69 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %69 %71 None
+         %72 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %73 = OpFunctionCall %v4uint %textureLoad_eecf7d
+               OpStore %72 %73 None
+         %74 = OpLoad %VertexOutput %out None
+               OpReturnValue %74
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %52
+         %76 = OpLabel
+         %77 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %78 = OpCompositeExtract %v4float %77 0
+               OpStore %vertex_main_position_Output %78 None
+         %79 = OpCompositeExtract %v4uint %77 1
+               OpStore %vertex_main_loc0_Output %79 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.glsl
index 7cdf5e2..35f9d1a 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_ef2ec3() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rg32i) uniform highp iimage2D arg_0;
 ivec4 textureLoad_ef2ec3() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
index f383fcc..39553f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ef2ec3() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
index f383fcc..39553f1 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_ef2ec3() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.msl
index f0c7ffc..bedfdfe 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_ef2ec3(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.msl
index c18b1eb..97cfd0e 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_ef2ec3(texture1d<int, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol.read(uint(arg_1));
+  int4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.spvasm
index f081894..7f40bc5 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ef2ec3.wgsl.expected.spvasm
@@ -1,11 +1,13 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_ef2ec3 = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4int %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4int %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4int %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4int %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4int %textureLoad_ef2ec3
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4int %textureLoad_ef2ec3
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_ef2ec3
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4int %textureLoad_ef2ec3
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.glsl
index 1094668..1c3422c 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_ef5405() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_ef5405() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_ef5405() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
index 539fed3..3df6743 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ef5405() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ef5405();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
index 539fed3..3df6743 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_ef5405() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ef5405();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.msl
index bd2b771..1ac29cb 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_ef5405(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.msl
index 79a5eb7..26f3533 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_ef5405(texture3d<uint, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.spvasm
index 1424c76..63b9d47 100644
--- a/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ef5405.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,18 +66,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ef5405 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -84,43 +88,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %30 = OpISub %v3uint %28 %31
+         %33 = OpBitcast %v3uint %27
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_ef5405
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_ef5405
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_ef5405
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_ef5405
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_ef5405
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_ef5405
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.glsl
index 0e085c4..5c51bfa 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_efa787() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_efa787() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_efa787() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
index ed053b2..961c6a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_efa787() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_efa787();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
index ed053b2..961c6a6 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_efa787() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_efa787();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.msl
index 1a21cc8..1b387b2 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_efa787(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.msl
index 1425252..0d04e9a 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_efa787(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.spvasm
index 4c3ff06..fe5e84e 100644
--- a/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/efa787.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_efa787 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,44 +86,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_efa787
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_efa787
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_efa787
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_efa787
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_efa787
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_efa787
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
index f8310b8..f93c609 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f0514a() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
index f8310b8..f93c609 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f0514a() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.msl
index 62aba7b..69986a3 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_f0514a(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.msl
index ecc26b9..951fab9 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f0514a(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.spvasm
index fa60e48..464e1b5 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f0514a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f0514a = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_f0514a
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_f0514a
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_f0514a
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.glsl
index 1b7eec9..b788c92 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f06b69() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f06b69() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f06b69() {
   int arg_1 = 1;
-  ivec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
index 62c6e03..54afd21 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f06b69() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f06b69();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
index 62c6e03..54afd21 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f06b69() {
   int arg_1 = int(1);
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  int4 res = int4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f06b69();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.msl
index 6218b4d..b99a2fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 int4 textureLoad_f06b69(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  int4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  int4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.msl
index aacfd05..1ec3728 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f06b69(texture1d<int, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.spvasm
index f4f6e15..1b2ca18 100644
--- a/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f06b69.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 67
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,19 +63,19 @@
          %18 = OpTypeFunction %v4int
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %38 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %50 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f06b69 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -82,43 +84,47 @@
                OpStore %arg_1 %int_1
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %int %arg_1 None
-         %25 = OpImageRead %v4int %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4int %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %uint %23
+         %27 = OpISub %uint %25 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageRead %v4int %23 %30 None
+               OpStore %res %32
+         %35 = OpLoad %v4int %res None
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4int %textureLoad_f06b69
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %34 %33 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %31
+%fragment_main = OpFunction %void None %38
          %39 = OpLabel
          %40 = OpFunctionCall %v4int %textureLoad_f06b69
          %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
                OpStore %41 %40 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
+%compute_main = OpFunction %void None %38
          %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %54 = OpFunctionCall %v4int %textureLoad_f06b69
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+         %46 = OpFunctionCall %v4int %textureLoad_f06b69
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %47 %46 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4int %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main_inner = OpFunction %VertexOutput None %50
+         %51 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %54
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %55 %57 None
+         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %59 = OpFunctionCall %v4int %textureLoad_f06b69
+               OpStore %58 %59 None
+         %60 = OpLoad %VertexOutput %out None
+               OpReturnValue %60
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %38
+         %62 = OpLabel
+         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %64 = OpCompositeExtract %v4float %63 0
+               OpStore %vertex_main_position_Output %64 None
+         %65 = OpCompositeExtract %v4int %63 1
+               OpStore %vertex_main_loc0_Output %65 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.glsl
index f4c1db3..39faa6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 vec4 textureLoad_f0abad() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 vec4 textureLoad_f0abad() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 vec4 textureLoad_f0abad() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  vec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
index f187074..2380c50 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f0abad();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
index f187074..2380c50 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f0abad();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.msl
index 06c4acf..ce449c4 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_f0abad(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  int const v_1 = arg_2;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.msl
index c135e5c..87050af 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_f0abad(texture2d_ms<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.spvasm
index 920170b..f367997 100644
--- a/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f0abad.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f0abad = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,43 +86,46 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Sample %29
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %30 = OpImageQuerySize %v2uint %27
+         %31 = OpISub %v2uint %30 %21
+         %32 = OpExtInst %v2uint %33 UMin %28 %31
+         %34 = OpImageFetch %v4float %27 %32 Sample %29
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f0abad
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f0abad
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_f0abad
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f0abad
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_f0abad
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_f0abad
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.glsl
index 63a3be4..a64961f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_f1c549() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp image3D arg_0;
 vec4 textureLoad_f1c549() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
index e8d7bea..b275921 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f1c549() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
index e8d7bea..b275921 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture3D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f1c549() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.msl
index c09124d..0dfb84a 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_f1c549(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.msl
index 3038528..d2d71ab 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f1c549(texture3d<float, access::read_write> tint_symbol) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol.read(uint3(arg_1));
+  float4 res = tint_symbol.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol.get_width(), tint_symbol.get_height(), tint_symbol.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.spvasm
index e71204b..ed76a7a 100644
--- a/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f1c549.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f1c549 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v3int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v3uint %18
+         %23 = OpISub %v3uint %20 %24
+         %26 = OpBitcast %v3uint %19
+         %27 = OpExtInst %v3uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_f1c549
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_f1c549
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_f1c549
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_f1c549
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.glsl
index 6b16477..3dcf360 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f2a7ff() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f2a7ff() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f2a7ff() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
index 271b3d9..014c734 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f2a7ff() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f2a7ff();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
index 271b3d9..014c734 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f2a7ff() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f2a7ff();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.msl
index f874edb..28f1a1f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_f2a7ff(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.msl
index 413b768..cd68d7f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_f2a7ff(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.spvasm
index 761dc61..b4764e3 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f2a7ff.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,14 +64,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f2a7ff = OpFunction %v4float None %15
          %16 = OpLabel
@@ -78,43 +80,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f2a7ff
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_f2a7ff
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_f2a7ff
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_f2a7ff
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_f2a7ff
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_f2a7ff
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.glsl
index 9c6fee7..14b504c 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_f2bdd4() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_f2bdd4() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
index a8097b8..b3d3189 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_f2bdd4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
index a8097b8..b3d3189 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,13 @@
 float4 textureLoad_f2bdd4() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.msl
index c3f359d..e2ed062 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_f2bdd4(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.msl
index 15a1ddf..19fb301 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_f2bdd4(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.spvasm
index 7a490fd..50456ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f2bdd4.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -45,7 +47,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_f2bdd4 = OpFunction %v4float None %10
@@ -58,23 +60,31 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2uint %arg_1 None
          %22 = OpLoad %uint %arg_2 None
-         %24 = OpCompositeConstruct %v3uint %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %25 = OpCompositeExtract %uint %23 2
+         %26 = OpISub %uint %25 %uint_1
+         %27 = OpExtInst %uint %28 UMin %22 %26
+         %29 = OpImageQuerySize %v3uint %20
+         %30 = OpVectorShuffle %v2uint %29 %29 0 1
+         %31 = OpISub %v2uint %30 %16
+         %32 = OpExtInst %v2uint %28 UMin %21 %31
+         %33 = OpCompositeConstruct %v3uint %32 %27
+         %34 = OpImageRead %v4float %20 %33 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f2bdd4
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f2bdd4
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_f2bdd4
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f2bdd4
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
index 33c4e7c..447b249 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_f2c311() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
index 33c4e7c..447b249 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 int4 textureLoad_f2c311() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.msl
index 6c13904..10de381 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 int4 textureLoad_f2c311(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.msl
index 438dd01..8c58262 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f2c311(texture2d_array<int, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.spvasm
index f984811..2cb8bac 100644
--- a/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f2c311.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 41
+; Bound: 55
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,12 +42,15 @@
       %int_1 = OpConstant %int 1
          %15 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %30 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f2c311 = OpFunction %v4int None %10
          %11 = OpLabel
@@ -57,23 +62,33 @@
          %19 = OpLoad %8 %arg_0 None
          %20 = OpLoad %v2int %arg_1 None
          %21 = OpLoad %int %arg_2 None
-         %23 = OpCompositeConstruct %v3int %20 %21
-         %24 = OpImageRead %v4int %19 %23 None
-               OpStore %res %24
-         %27 = OpLoad %v4int %res None
-               OpReturnValue %27
+         %22 = OpImageQuerySize %v3uint %19
+         %25 = OpCompositeExtract %uint %22 2
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpBitcast %uint %21
+         %29 = OpExtInst %uint %30 UMin %28 %26
+         %31 = OpImageQuerySize %v3uint %19
+         %32 = OpVectorShuffle %v2uint %31 %31 0 1
+         %34 = OpISub %v2uint %32 %35
+         %36 = OpBitcast %v2uint %20
+         %37 = OpExtInst %v2uint %30 UMin %36 %34
+         %38 = OpCompositeConstruct %v3uint %37 %29
+         %39 = OpImageRead %v4int %19 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4int %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %30
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4int %textureLoad_f2c311
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %33 %32 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4int %textureLoad_f2c311
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %30
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4int %textureLoad_f2c311
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4int %textureLoad_f2c311
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.glsl
index 7b69b5d..55685b3 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.glsl
@@ -2,20 +2,33 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_f348d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 void main() {
@@ -23,20 +36,33 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   vec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 vec4 textureLoad_f348d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v_1 = arg_2;
-  int v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  vec4 res = texelFetch(arg_0, v_4, int(v_2));
+  uvec2 v_2 = arg_1;
+  uint v_3 = arg_2;
+  int v_4 = arg_3;
+  uint v_5 = min(v_3, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_6 = (v_1.inner.tint_builtin_value_0 - 1u);
+  uint v_7 = min(uint(v_4), v_6);
+  ivec2 v_8 = ivec2(min(v_2, (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u))));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  vec4 res = texelFetch(arg_0, v_9, int(v_7));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +72,34 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   vec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f348d9() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  uint v = arg_2;
-  int v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  vec4 res = texelFetch(arg_0, v_3, int(v_1));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  int v_3 = arg_3;
+  uint v_4 = min(v_2, (uint(textureSize(arg_0, 0).z) - 1u));
+  uint v_5 = (v.inner.tint_builtin_value_0 - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  ivec2 v_7 = ivec2(min(v_1, (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u))));
+  ivec3 v_8 = ivec3(v_7, int(v_4));
+  vec4 res = texelFetch(arg_0, v_8, int(v_6));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +109,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_9 = vertex_main_inner();
+  gl_Position = v_9.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_9.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
index 525dbd6..f435d65 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f348d9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
index 525dbd6..f435d65 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,18 @@
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
   int arg_3 = int(1);
-  uint v = arg_2;
-  int v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float4 res = float4(arg_0.Load(int4(v_2, v_3, int(v_1))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint4 v_3 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_3.x, v_3.y, v_3.z, v_3.w);
+  uint v_4 = min(uint(arg_3), (v_3.w - 1u));
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(v_4), v_5.x, v_5.y, v_5.z, v_5.w);
+  int2 v_6 = int2(min(v, (v_5.xy - (1u).xx)));
+  int v_7 = int(v_2);
+  float4 res = float4(arg_0.Load(int4(v_6, v_7, int(v_4))));
   return res;
 }
 
@@ -36,13 +43,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f348d9();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_8 = tint_symbol;
+  return v_8;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_9 = vertex_main_inner();
+  vertex_main_outputs v_10 = {v_9.prevent_dce, v_9.pos};
+  return v_10;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.msl
index dfd6c54..40efddd 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.ir.msl
@@ -20,7 +20,10 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2, arg_3);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint const v_2 = min(uint(arg_3), (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(v_2), tint_module_vars.arg_0.get_height(v_2)) - uint2(1u))), v_1, v_2);
   return res;
 }
 
@@ -43,9 +46,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.msl
index d697693..ec2e64f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.msl
@@ -5,7 +5,8 @@
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
   int arg_3 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.spvasm
index 6118ee3..484fb05 100644
--- a/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f348d9.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -66,16 +68,16 @@
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
      %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %55 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %53 = OpTypeFunction %VertexOutput
+         %66 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %57 = OpConstantNull %VertexOutput
-         %59 = OpConstantNull %v4float
+         %70 = OpConstantNull %VertexOutput
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f348d9 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -90,44 +92,56 @@
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %uint %arg_2 None
          %32 = OpLoad %int %arg_3 None
-         %34 = OpCompositeConstruct %v3uint %30 %31
-         %35 = OpImageFetch %v4float %29 %34 Lod %32
-               OpStore %res %35
-         %38 = OpLoad %v4float %res None
-               OpReturnValue %38
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpExtInst %uint %39 UMin %31 %37
+         %40 = OpImageQueryLevels %uint %29
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %32
+         %43 = OpExtInst %uint %39 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %46 = OpISub %v2uint %45 %21
+         %47 = OpExtInst %v2uint %39 UMin %30 %46
+         %48 = OpCompositeConstruct %v3uint %47 %38
+         %49 = OpImageFetch %v4float %29 %48 Lod %43
+               OpStore %res %49
+         %52 = OpLoad %v4float %res None
+               OpReturnValue %52
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %textureLoad_f348d9
-         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %55
+         %56 = OpLabel
+         %57 = OpFunctionCall %v4float %textureLoad_f348d9
+         %58 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %58 %57 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
-         %48 = OpLabel
-         %49 = OpFunctionCall %v4float %textureLoad_f348d9
-         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %50 %49 None
+%compute_main = OpFunction %void None %55
+         %61 = OpLabel
+         %62 = OpFunctionCall %v4float %textureLoad_f348d9
+         %63 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %63 %62 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %53
-         %54 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %57
-         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %58 %59 None
-         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %61 = OpFunctionCall %v4float %textureLoad_f348d9
-               OpStore %60 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+%vertex_main_inner = OpFunction %VertexOutput None %66
+         %67 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %70
+         %71 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %71 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %74 = OpFunctionCall %v4float %textureLoad_f348d9
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4float %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main = OpFunction %void None %55
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4float %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.glsl
index bfeaac3..3d7afa6 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f35ac7() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f35ac7() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f35ac7() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
index 5415f7b..d90d3fb 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f35ac7() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f35ac7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
index 5415f7b..d90d3fb 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f35ac7() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f35ac7();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.msl
index 3f0695a..003ac05 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_f35ac7(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.msl
index 984d1dc..f847b0d 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_f35ac7(texture1d<int, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.spvasm
index 5fd98de..c27ffa8 100644
--- a/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f35ac7.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f35ac7 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageRead %v4int %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageRead %v4int %24 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_f35ac7
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_f35ac7
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_f35ac7
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_f35ac7
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_f35ac7
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_f35ac7
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.glsl
index 57df383..6600099 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_f379e2() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_f379e2() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 vec4 textureLoad_f379e2() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  vec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
index 5f8adab..e890e4e 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_f379e2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f379e2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
index 5f8adab..e890e4e 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 float4 textureLoad_f379e2() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f379e2();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.msl
index b9c8241..412bf9e 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 float4 textureLoad_f379e2(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.msl
index 18b9eb8..36b6801 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f379e2(texture2d_array<float, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.spvasm
index 6217752..1204b01 100644
--- a/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f379e2.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 79
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %36 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -62,19 +64,21 @@
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %41 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %51 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %49 = OpTypeFunction %VertexOutput
+         %63 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
-         %55 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %67 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f379e2 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -86,44 +90,54 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2int %arg_1 None
          %27 = OpLoad %int %arg_2 None
-         %29 = OpCompositeConstruct %v3int %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %31 = OpCompositeExtract %uint %28 2
+         %32 = OpISub %uint %31 %uint_1
+         %34 = OpBitcast %uint %27
+         %35 = OpExtInst %uint %36 UMin %34 %32
+         %37 = OpImageQuerySize %v3uint %25
+         %38 = OpVectorShuffle %v2uint %37 %37 0 1
+         %40 = OpISub %v2uint %38 %41
+         %42 = OpBitcast %v2uint %26
+         %43 = OpExtInst %v2uint %36 UMin %42 %40
+         %44 = OpCompositeConstruct %v3uint %43 %35
+         %45 = OpImageRead %v4float %25 %44 None
+               OpStore %res %45
+         %48 = OpLoad %v4float %res None
+               OpReturnValue %48
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f379e2
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %51
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_f379e2
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %44 = OpLabel
-         %45 = OpFunctionCall %v4float %textureLoad_f379e2
-         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %51
+         %58 = OpLabel
+         %59 = OpFunctionCall %v4float %textureLoad_f379e2
+         %60 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %60 %59 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %55 None
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %58 = OpFunctionCall %v4float %textureLoad_f379e2
-               OpStore %56 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %63
+         %64 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %67
+         %68 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %68 %69 None
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %71 = OpFunctionCall %v4float %textureLoad_f379e2
+               OpStore %70 %71 None
+         %72 = OpLoad %VertexOutput %out None
+               OpReturnValue %72
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %v4float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %51
+         %74 = OpLabel
+         %75 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %76 = OpCompositeExtract %v4float %75 0
+               OpStore %vertex_main_position_Output %76 None
+         %77 = OpCompositeExtract %v4float %75 1
+               OpStore %vertex_main_loc0_Output %77 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.glsl
index f1aed82..d475679 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_f56e6f() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16ui) uniform highp readonly uimage3D arg_0;
 uvec4 textureLoad_f56e6f() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_f56e6f() {
   ivec3 arg_1 = ivec3(1);
-  uvec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  uvec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
index 9b62a98..c67a927 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_f56e6f() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f56e6f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
index 9b62a98..c67a927 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_f56e6f() {
   int3 arg_1 = (int(1)).xxx;
-  uint4 res = uint4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  uint4 res = uint4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f56e6f();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.msl
index 4c7a4c2..26269bc 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 uint4 textureLoad_f56e6f(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.msl
index 94254f6..250455c 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_f56e6f(texture3d<uint, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  uint4 res = tint_symbol_1.read(uint3(arg_1));
+  uint4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.spvasm
index c17ffac..468358d 100644
--- a/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f56e6f.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,18 +65,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %31 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %46 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %50 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f56e6f = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -83,43 +87,47 @@
                OpStore %arg_1 %24
          %26 = OpLoad %8 %arg_0 None
          %27 = OpLoad %v3int %arg_1 None
-         %28 = OpImageRead %v4uint %26 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4uint %res None
-               OpReturnValue %31
+         %28 = OpImageQuerySize %v3uint %26
+         %30 = OpISub %v3uint %28 %31
+         %33 = OpBitcast %v3uint %27
+         %34 = OpExtInst %v3uint %35 UMin %33 %30
+         %36 = OpImageRead %v4uint %26 %34 None
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4uint %textureLoad_f56e6f
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_f56e6f
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4uint %textureLoad_f56e6f
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_f56e6f
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %46
-         %47 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %50
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %51 %53 None
-         %54 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %56 = OpFunctionCall %v4uint %textureLoad_f56e6f
-               OpStore %54 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_f56e6f
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %34
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4uint %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.glsl
index 0be308f..9213ade 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f5aee2() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, r8) uniform highp readonly image2D arg_0;
 vec4 textureLoad_f5aee2() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f5aee2() {
   uvec2 arg_1 = uvec2(1u);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  vec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
index ca3009f..4ff1700 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f5aee2() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f5aee2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
index ca3009f..4ff1700 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f5aee2() {
   uint2 arg_1 = (1u).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  float4 res = float4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f5aee2();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.msl
index e490e6f..3a3bfa7 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 float4 textureLoad_f5aee2(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.msl
index 2863dea..fffe8af 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_f5aee2(texture2d<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  float4 res = tint_symbol_1.read(uint2(arg_1));
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.spvasm
index bccab51..1aa87b7 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f5aee2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 63
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -63,14 +65,14 @@
          %21 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %43 = OpTypeFunction %VertexOutput
+         %47 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %47 = OpConstantNull %VertexOutput
-         %49 = OpConstantNull %v4float
+         %51 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f5aee2 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,46 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v2uint %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v2uint %23
+         %26 = OpISub %v2uint %25 %21
+         %27 = OpExtInst %v2uint %28 UMin %24 %26
+         %29 = OpImageRead %v4float %23 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f5aee2
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_f5aee2
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %38 = OpLabel
-         %39 = OpFunctionCall %v4float %textureLoad_f5aee2
-         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %40 %39 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_f5aee2
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %43
-         %44 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %47
-         %48 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %48 %49 None
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_f5aee2
-               OpStore %50 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+%vertex_main_inner = OpFunction %VertexOutput None %47
+         %48 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %51
+         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %52 %53 None
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %55 = OpFunctionCall %v4float %textureLoad_f5aee2
+               OpStore %54 %55 None
+         %56 = OpLoad %VertexOutput %out None
+               OpReturnValue %56
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main = OpFunction %void None %35
+         %58 = OpLabel
+         %59 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %60 = OpCompositeExtract %v4float %59 0
+               OpStore %vertex_main_position_Output %60 None
+         %61 = OpCompositeExtract %v4float %59 1
+               OpStore %vertex_main_loc0_Output %61 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
index 677cd81..1acaf35 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_f5fbc6() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
index 677cd81..1acaf35 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_f5fbc6() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.msl
index 56cdc6e..71ba549 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_f5fbc6(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.msl
index e5a4240..7d7bea4 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f5fbc6(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.spvasm
index cc03806..9c3208f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f5fbc6.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f5fbc6 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f5fbc6
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f5fbc6
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_f5fbc6
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_f5fbc6
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.glsl
index 206856f..35232b8 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f74bd8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rg32f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f74bd8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f74bd8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
index 85335e5..1526404 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f74bd8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f74bd8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
index 85335e5..1526404 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f74bd8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f74bd8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.msl
index 309e583..6bf14cc 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_f74bd8(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.msl
index d7ce860..93fd26e 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f74bd8(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.spvasm
index b264653..52740d3 100644
--- a/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f74bd8.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
                OpCapability StorageImageExtendedFormats
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -61,18 +63,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f74bd8 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -81,43 +85,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f74bd8
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_f74bd8
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_f74bd8
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f74bd8
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_f74bd8
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_f74bd8
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
index 2910b06..21fa52f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f7f3bc() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
index 2910b06..21fa52f 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f7f3bc() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.msl
index 76c6a2f..7b65cae 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_f7f3bc(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.msl
index 6eb4b0b..4136992 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f7f3bc(texture1d<float, access::read_write> tint_symbol) {
   int arg_1 = 1;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(tint_clamp(arg_1, 0, int((tint_symbol.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.spvasm
index 9fc3b83..3e69533 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f7f3bc.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 35
+; Bound: 41
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -38,11 +40,12 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %31 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f7f3bc = OpFunction %v4float None %10
          %11 = OpLabel
@@ -51,22 +54,26 @@
                OpStore %arg_1 %int_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %int %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %20 = OpISub %uint %18 %uint_1
+         %22 = OpBitcast %uint %17
+         %23 = OpExtInst %uint %24 UMin %22 %20
+         %25 = OpImageRead %v4float %16 %23 None
+               OpStore %res %25
+         %28 = OpLoad %v4float %res None
+               OpReturnValue %28
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_f7f3bc
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %24
+%fragment_main = OpFunction %void None %31
          %32 = OpLabel
          %33 = OpFunctionCall %v4float %textureLoad_f7f3bc
          %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %34 %33 None
                OpReturn
                OpFunctionEnd
+%compute_main = OpFunction %void None %31
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4float %textureLoad_f7f3bc
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %40 %39 None
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.glsl
index faedb5e..c3c6440 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.glsl
@@ -10,9 +10,11 @@
 vec4 textureLoad_f7f936() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 void main() {
@@ -28,9 +30,11 @@
 vec4 textureLoad_f7f936() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  uvec2 v_1 = arg_1;
+  uint v_2 = arg_2;
+  uint v_3 = min(v_2, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_4 = ivec2(min(v_1, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_4, int(v_3)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +54,11 @@
 vec4 textureLoad_f7f936() {
   uvec2 arg_1 = uvec2(1u);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  uvec2 v = arg_1;
+  uint v_1 = arg_2;
+  uint v_2 = min(v_1, (uint(imageSize(arg_0).z) - 1u));
+  ivec2 v_3 = ivec2(min(v, (uvec2(imageSize(arg_0).xy) - uvec2(1u))));
+  vec4 res = imageLoad(arg_0, ivec3(v_3, int(v_2)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +68,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_4 = vertex_main_inner();
+  gl_Position = v_4.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_4.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
index b33155b..a442d09 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_f7f936() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f7f936();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
index b33155b..a442d09 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,13 @@
 float4 textureLoad_f7f936() {
   uint2 arg_1 = (1u).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  int2 v_3 = int2(min(arg_1, (v_2.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_3, int(v_1), int(0))));
   return res;
 }
 
@@ -33,13 +37,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f7f936();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_4 = tint_symbol;
+  return v_4;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_5 = vertex_main_inner();
+  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
+  return v_6;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.msl
index daf603f..cd673c9 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float4 textureLoad_f7f936(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.msl
index 959a65f..0723a91 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float4 textureLoad_f7f936(texture2d_array<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   uint arg_2 = 1u;
-  float4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), min(arg_2, (tint_symbol_1.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.spvasm
index 43e812c..7d0a68b 100644
--- a/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f7f936.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 64
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,14 +67,14 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %36 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %48 = OpTypeFunction %VertexOutput
+         %57 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %52 = OpConstantNull %VertexOutput
-         %54 = OpConstantNull %v4float
+         %61 = OpConstantNull %VertexOutput
+         %63 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f7f936 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -84,44 +86,52 @@
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
          %27 = OpLoad %uint %arg_2 None
-         %29 = OpCompositeConstruct %v3uint %26 %27
-         %30 = OpImageRead %v4float %25 %29 None
-               OpStore %res %30
-         %33 = OpLoad %v4float %res None
-               OpReturnValue %33
+         %28 = OpImageQuerySize %v3uint %25
+         %30 = OpCompositeExtract %uint %28 2
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpExtInst %uint %33 UMin %27 %31
+         %34 = OpImageQuerySize %v3uint %25
+         %35 = OpVectorShuffle %v2uint %34 %34 0 1
+         %36 = OpISub %v2uint %35 %21
+         %37 = OpExtInst %v2uint %33 UMin %26 %36
+         %38 = OpCompositeConstruct %v3uint %37 %32
+         %39 = OpImageRead %v4float %25 %38 None
+               OpStore %res %39
+         %42 = OpLoad %v4float %res None
+               OpReturnValue %42
                OpFunctionEnd
-%fragment_main = OpFunction %void None %36
-         %37 = OpLabel
-         %38 = OpFunctionCall %v4float %textureLoad_f7f936
-         %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %39 %38 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %textureLoad_f7f936
+         %48 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %36
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %textureLoad_f7f936
-         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %45 %44 None
+%compute_main = OpFunction %void None %45
+         %52 = OpLabel
+         %53 = OpFunctionCall %v4float %textureLoad_f7f936
+         %54 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %54 %53 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %48
-         %49 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %52
-         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %53 %54 None
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %56 = OpFunctionCall %v4float %textureLoad_f7f936
-               OpStore %55 %56 None
-         %57 = OpLoad %VertexOutput %out None
-               OpReturnValue %57
+%vertex_main_inner = OpFunction %VertexOutput None %57
+         %58 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %61
+         %62 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %62 %63 None
+         %64 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %65 = OpFunctionCall %v4float %textureLoad_f7f936
+               OpStore %64 %65 None
+         %66 = OpLoad %VertexOutput %out None
+               OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %36
-         %59 = OpLabel
-         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %61 = OpCompositeExtract %v4float %60 0
-               OpStore %vertex_main_position_Output %61 None
-         %62 = OpCompositeExtract %v4float %60 1
-               OpStore %vertex_main_loc0_Output %62 None
+%vertex_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %70 = OpCompositeExtract %v4float %69 0
+               OpStore %vertex_main_position_Output %70 None
+         %71 = OpCompositeExtract %v4float %69 1
+               OpStore %vertex_main_loc0_Output %71 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.glsl
index 60439c5..773b991 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 vec4 textureLoad_f81792() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 vec4 textureLoad_f81792() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  vec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  vec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
index 48c549f..46e6021 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_f81792() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
index 48c549f..46e6021 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,15 @@
 float4 textureLoad_f81792() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  float4 res = float4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.msl
index e47c752..d21e92b 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 float4 textureLoad_f81792(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.msl
index dc29fc2..2517df0 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f81792(texture2d_array<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.spvasm
index 71ccdfb..ea3bd9b 100644
--- a/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f81792.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 56
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,12 +43,15 @@
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %36 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %46 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f81792 = OpFunction %v4float None %10
          %11 = OpLabel
@@ -58,23 +63,33 @@
          %20 = OpLoad %8 %arg_0 None
          %21 = OpLoad %v2int %arg_1 None
          %22 = OpLoad %int %arg_2 None
-         %24 = OpCompositeConstruct %v3int %21 %22
-         %25 = OpImageRead %v4float %20 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %23 = OpImageQuerySize %v3uint %20
+         %26 = OpCompositeExtract %uint %23 2
+         %27 = OpISub %uint %26 %uint_1
+         %29 = OpBitcast %uint %22
+         %30 = OpExtInst %uint %31 UMin %29 %27
+         %32 = OpImageQuerySize %v3uint %20
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %35 = OpISub %v2uint %33 %36
+         %37 = OpBitcast %v2uint %21
+         %38 = OpExtInst %v2uint %31 UMin %37 %35
+         %39 = OpCompositeConstruct %v3uint %38 %30
+         %40 = OpImageRead %v4float %20 %39 None
+               OpStore %res %40
+         %43 = OpLoad %v4float %res None
+               OpReturnValue %43
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_f81792
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %46
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_f81792
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_f81792
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %46
+         %53 = OpLabel
+         %54 = OpFunctionCall %v4float %textureLoad_f81792
+         %55 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %55 %54 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
index ba16789..fe8c9db 100644
--- a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f82eb2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
index ba16789..fe8c9db 100644
--- a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture1D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f82eb2() {
   uint arg_1 = 1u;
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  float4 res = float4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.msl
index b41a423..110a91d 100644
--- a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 float4 textureLoad_f82eb2(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  float4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.msl
index 20e9db8..d3a7711 100644
--- a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 float4 textureLoad_f82eb2(texture1d<float, access::read_write> tint_symbol) {
   uint arg_1 = 1u;
-  float4 res = tint_symbol.read(uint(arg_1));
+  float4 res = tint_symbol.read(uint(min(arg_1, (tint_symbol.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.spvasm
index 4fca67c..2fa5abc 100644
--- a/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f82eb2.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,7 +42,7 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_f82eb2 = OpFunction %v4float None %10
@@ -50,22 +52,25 @@
                OpStore %arg_1 %uint_1
          %16 = OpLoad %8 %arg_0 None
          %17 = OpLoad %uint %arg_1 None
-         %18 = OpImageRead %v4float %16 %17 None
-               OpStore %res %18
-         %21 = OpLoad %v4float %res None
-               OpReturnValue %21
+         %18 = OpImageQuerySize %uint %16
+         %19 = OpISub %uint %18 %uint_1
+         %20 = OpExtInst %uint %21 UMin %17 %19
+         %22 = OpImageRead %v4float %16 %20 None
+               OpStore %res %22
+         %25 = OpLoad %v4float %res None
+               OpReturnValue %25
                OpFunctionEnd
-%fragment_main = OpFunction %void None %24
-         %25 = OpLabel
-         %26 = OpFunctionCall %v4float %textureLoad_f82eb2
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %27 %26 None
+%fragment_main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpFunctionCall %v4float %textureLoad_f82eb2
+         %31 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %31 %30 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %24
-         %31 = OpLabel
-         %32 = OpFunctionCall %v4float %textureLoad_f82eb2
-         %33 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %33 %32 None
+%compute_main = OpFunction %void None %28
+         %35 = OpLabel
+         %36 = OpFunctionCall %v4float %textureLoad_f82eb2
+         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %37 %36 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.glsl
index 839748e..c0d5fed 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.glsl
@@ -2,17 +2,28 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_f85291() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 void main() {
@@ -20,17 +31,28 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   ivec4 inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp isampler2D arg_0;
 ivec4 textureLoad_f85291() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_2, int(v_1));
+  ivec2 v_2 = arg_1;
+  uint v_3 = min(arg_2, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_4 = (uvec2(textureSize(arg_0, int(v_3))) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v_2), v_4));
+  ivec4 res = texelFetch(arg_0, v_5, int(v_3));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -40,19 +62,29 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   ivec4 prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f85291() {
   ivec2 arg_1 = ivec2(1);
   uint arg_2 = 1u;
-  uint v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = texelFetch(arg_0, v_1, int(v));
+  ivec2 v_1 = arg_1;
+  uint v_2 = min(arg_2, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_3 = (uvec2(textureSize(arg_0, int(v_2))) - uvec2(1u));
+  ivec2 v_4 = ivec2(min(uvec2(v_1), v_3));
+  ivec4 res = texelFetch(arg_0, v_4, int(v_2));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +94,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_5 = vertex_main_inner();
+  gl_Position = v_5.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_5.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
index a62d9c8..8bbc10c 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_f85291() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f85291();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
index a62d9c8..8bbc10c 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_f85291() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int3(v_1, int(v))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(0u, v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(arg_2, (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(uint(v_2), v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int3(v_5, int(v_2))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f85291();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.msl
index 757e9ae..af435aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_f85291(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_num_mip_levels() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(v_1), tint_module_vars.arg_0.get_height(v_1)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<int, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.msl
index 385853f..d731267 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_f85291(texture2d<int, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint const level_idx = min(uint(arg_2), (tint_symbol_1.get_num_mip_levels() - 1u));
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.spvasm
index 75a4ca9..55adfc6 100644
--- a/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f85291.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,17 +67,19 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %39 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %48 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %50 = OpTypeFunction %VertexOutput
+         %60 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %64 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %67 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f85291 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -87,43 +91,50 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %uint %arg_2 None
-         %32 = OpImageFetch %v4int %29 %30 Lod %31
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %32 = OpImageQueryLevels %uint %29
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpExtInst %uint %35 UMin %31 %33
+         %36 = OpImageQuerySizeLod %v2uint %29 %34
+         %38 = OpISub %v2uint %36 %39
+         %40 = OpBitcast %v2uint %30
+         %41 = OpExtInst %v2uint %35 UMin %40 %38
+         %42 = OpImageFetch %v4int %29 %41 Lod %34
+               OpStore %res %42
+         %45 = OpLoad %v4int %res None
+               OpReturnValue %45
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_f85291
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4int %textureLoad_f85291
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4int %textureLoad_f85291
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %48
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4int %textureLoad_f85291
+         %57 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %57 %56 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %59 = OpFunctionCall %v4int %textureLoad_f85291
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %60
+         %61 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %64
+         %65 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %65 %67 None
+         %68 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %69 = OpFunctionCall %v4int %textureLoad_f85291
+               OpStore %68 %69 None
+         %70 = OpLoad %VertexOutput %out None
+               OpReturnValue %70
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4int %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %48
+         %72 = OpLabel
+         %73 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %74 = OpCompositeExtract %v4float %73 0
+               OpStore %vertex_main_position_Output %74 None
+         %75 = OpCompositeExtract %v4int %73 1
+               OpStore %vertex_main_loc0_Output %75 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.glsl
index a63982d..1dc0dbe 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f8a2e8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2))).zyxw;
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8) uniform highp readonly image3D arg_0;
 vec4 textureLoad_f8a2e8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2))).zyxw;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_f8a2e8() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1)).zyxw;
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1))).zyxw;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
index 26ebb7e..384b6ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f8a2e8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f8a2e8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
index 26ebb7e..384b6ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_f8a2e8() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f8a2e8();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.msl
index ecab9d7..9f18ad6 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_f8a2e8(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.msl
index 029fbee..b4aa533 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f8a2e8(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.spvasm
index 914b82e..8d7a40b 100644
--- a/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f8a2e8.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 69
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %45 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
-         %51 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %57 = OpConstantNull %VertexOutput
+         %59 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f8a2e8 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,44 +84,48 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-         %26 = OpVectorShuffle %v4float %25 %25 2 1 0 3
-               OpStore %res %26
-         %29 = OpLoad %v4float %res None
-               OpReturnValue %29
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+         %35 = OpVectorShuffle %v4float %34 %34 2 1 0 3
+               OpStore %res %35
+         %38 = OpLoad %v4float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4float %textureLoad_f8a2e8
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_f8a2e8
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4float %textureLoad_f8a2e8
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %v4float %textureLoad_f8a2e8
+         %50 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %54 = OpFunctionCall %v4float %textureLoad_f8a2e8
-               OpStore %52 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %59 None
+         %60 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %61 = OpFunctionCall %v4float %textureLoad_f8a2e8
+               OpStore %60 %61 None
+         %62 = OpLoad %VertexOutput %out None
+               OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4float %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %41
+         %64 = OpLabel
+         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %66 = OpCompositeExtract %v4float %65 0
+               OpStore %vertex_main_position_Output %66 None
+         %67 = OpCompositeExtract %v4float %65 1
+               OpStore %vertex_main_loc0_Output %67 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.glsl
index 8bf86c6..5d72303 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_f92c2d() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, r32f) uniform highp image2D arg_0;
 vec4 textureLoad_f92c2d() {
   ivec2 arg_1 = ivec2(1);
-  vec4 res = imageLoad(arg_0, ivec2(arg_1));
+  ivec2 v_1 = arg_1;
+  uvec2 v_2 = (uvec2(imageSize(arg_0)) - uvec2(1u));
+  vec4 res = imageLoad(arg_0, ivec2(min(uvec2(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
index 846b0f7..701e1a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f92c2d() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
index 846b0f7..701e1a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,10 @@
 RWTexture2D<float4> arg_0 : register(u0, space1);
 float4 textureLoad_f92c2d() {
   int2 arg_1 = (int(1)).xx;
-  float4 res = float4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint2 v_1 = (v - (1u).xx);
+  float4 res = float4(arg_0.Load(int3(int2(min(uint2(arg_1), v_1)), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.msl
index 26eb466..0b0aff6 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.ir.msl
@@ -8,7 +8,9 @@
 
 float4 textureLoad_f92c2d(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
-  float4 res = tint_module_vars.arg_0.read(uint2(arg_1));
+  int2 const v = arg_1;
+  uint2 const v_1 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint2(v), v_1));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.msl
index 9f28991..00bb4cf 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_f92c2d(texture2d<float, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
-  float4 res = tint_symbol.read(uint2(arg_1));
+  float4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.spvasm
index ac9adbc..27ac326 100644
--- a/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f92c2d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 37
+; Bound: 45
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -39,11 +41,14 @@
 %_ptr_Function_v2int = OpTypePointer Function %v2int
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %v2int %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %24 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %textureLoad_f92c2d = OpFunction %v4float None %10
          %11 = OpLabel
@@ -52,22 +57,26 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2int %arg_1 None
-         %20 = OpImageRead %v4float %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4float %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %23 = OpISub %v2uint %20 %24
+         %26 = OpBitcast %v2uint %19
+         %27 = OpExtInst %v2uint %28 UMin %26 %23
+         %29 = OpImageRead %v4float %18 %27 None
+               OpStore %res %29
+         %32 = OpLoad %v4float %res None
+               OpReturnValue %32
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4float %textureLoad_f92c2d
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpFunctionCall %v4float %textureLoad_f92c2d
+         %38 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %38 %37 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4float %textureLoad_f92c2d
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %36 %35 None
+%compute_main = OpFunction %void None %35
+         %42 = OpLabel
+         %43 = OpFunctionCall %v4float %textureLoad_f92c2d
+         %44 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.glsl
index 6fed891..b902a6e 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f9eaaf() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba16i) uniform highp readonly iimage2D arg_0;
 ivec4 textureLoad_f9eaaf() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v_1 = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v_1, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out ivec4 vertex_main_loc0_Output;
 ivec4 textureLoad_f9eaaf() {
   uint arg_1 = 1u;
-  ivec4 res = imageLoad(arg_0, ivec2(uvec2(arg_1, 0u)));
+  uint v = arg_1;
+  ivec4 res = imageLoad(arg_0, ivec2(uvec2(min(v, (uvec2(imageSize(arg_0)).x - 1u)), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
index dc2a599..46a8f41 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f9eaaf() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f9eaaf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
index dc2a599..46a8f41 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture1D<int4> arg_0 : register(t0, space1);
 int4 textureLoad_f9eaaf() {
   uint arg_1 = 1u;
-  int4 res = int4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  int4 res = int4(arg_0.Load(int2(int(min(arg_1, (v - 1u))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_f9eaaf();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.msl
index bc607d3..7d4e880 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 int4 textureLoad_f9eaaf(tint_module_vars_struct tint_module_vars) {
   uint arg_1 = 1u;
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint(tint_module_vars.arg_0.get_width()) - 1u)));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.msl
index e7b93e3..434c116 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_f9eaaf(texture1d<int, access::read> tint_symbol_1) {
   uint arg_1 = 1u;
-  int4 res = tint_symbol_1.read(uint(arg_1));
+  int4 res = tint_symbol_1.read(uint(min(arg_1, (tint_symbol_1.get_width(0) - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.spvasm
index 14b82f9..6d7b017 100644
--- a/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/f9eaaf.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 65
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %44 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
+         %52 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %51 = OpConstantNull %v4float
+         %55 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_f9eaaf = OpFunction %v4int None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %uint_1
          %24 = OpLoad %8 %arg_0 None
          %25 = OpLoad %uint %arg_1 None
-         %26 = OpImageRead %v4int %24 %25 None
-               OpStore %res %26
-         %29 = OpLoad %v4int %res None
-               OpReturnValue %29
+         %26 = OpImageQuerySize %uint %24
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %25 %27
+         %30 = OpImageRead %v4int %24 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4int %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %32
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_f9eaaf
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%fragment_main = OpFunction %void None %36
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_f9eaaf
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %32
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_f9eaaf
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %36
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4int %textureLoad_f9eaaf
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %51 None
-         %52 = OpAccessChain %_ptr_Function_v4int %out %uint_1
-         %53 = OpFunctionCall %v4int %textureLoad_f9eaaf
-               OpStore %52 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %55 None
+         %56 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %57 = OpFunctionCall %v4int %textureLoad_f9eaaf
+               OpStore %56 %57 None
+         %58 = OpLoad %VertexOutput %out None
+               OpReturnValue %58
                OpFunctionEnd
-%vertex_main = OpFunction %void None %32
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4int %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %36
+         %60 = OpLabel
+         %61 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %62 = OpCompositeExtract %v4float %61 0
+               OpStore %vertex_main_position_Output %62 None
+         %63 = OpCompositeExtract %v4int %61 1
+               OpStore %vertex_main_loc0_Output %63 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
index 97a278c..35a2a71 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_fc47ff() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
index 97a278c..35a2a71 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 RWTexture2D<int4> arg_0 : register(u0, space1);
 int4 textureLoad_fc47ff() {
   uint2 arg_1 = (1u).xx;
-  int4 res = int4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  int4 res = int4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.msl
index fecf92f..12f985e 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.ir.msl
@@ -8,7 +8,8 @@
 
 int4 textureLoad_fc47ff(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  int4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.msl
index bab07b7..b9b984f 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 int4 textureLoad_fc47ff(texture2d<int, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
-  int4 res = tint_symbol.read(uint2(arg_1));
+  int4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.spvasm
index 2f75f40..9e2146d 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fc47ff.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -41,7 +43,7 @@
          %16 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
      %uint_0 = OpConstant %uint 0
 %textureLoad_fc47ff = OpFunction %v4int None %10
@@ -51,22 +53,25 @@
                OpStore %arg_1 %16
          %18 = OpLoad %8 %arg_0 None
          %19 = OpLoad %v2uint %arg_1 None
-         %20 = OpImageRead %v4int %18 %19 None
-               OpStore %res %20
-         %23 = OpLoad %v4int %res None
-               OpReturnValue %23
+         %20 = OpImageQuerySize %v2uint %18
+         %21 = OpISub %v2uint %20 %16
+         %22 = OpExtInst %v2uint %23 UMin %19 %21
+         %24 = OpImageRead %v4int %18 %22 None
+               OpStore %res %24
+         %27 = OpLoad %v4int %res None
+               OpReturnValue %27
                OpFunctionEnd
-%fragment_main = OpFunction %void None %26
-         %27 = OpLabel
-         %28 = OpFunctionCall %v4int %textureLoad_fc47ff
-         %29 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %29 %28 None
+%fragment_main = OpFunction %void None %30
+         %31 = OpLabel
+         %32 = OpFunctionCall %v4int %textureLoad_fc47ff
+         %33 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %33 %32 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %26
-         %33 = OpLabel
-         %34 = OpFunctionCall %v4int %textureLoad_fc47ff
-         %35 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %35 %34 None
+%compute_main = OpFunction %void None %30
+         %37 = OpLabel
+         %38 = OpFunctionCall %v4int %textureLoad_fc47ff
+         %39 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.glsl
index fec8289..0c46241 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 ivec4 textureLoad_fc6d36() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 ivec4 textureLoad_fc6d36() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  ivec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 ivec4 textureLoad_fc6d36() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  ivec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  ivec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
index 33ed525..ed7238c 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_fc6d36() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fc6d36();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
index 33ed525..ed7238c 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 int4 textureLoad_fc6d36() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  int4 res = int4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  int4 res = int4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fc6d36();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.msl
index fcc0e87..72ded51 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 int4 textureLoad_fc6d36(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  int4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  int4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<int, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.msl
index b6ab539..ef988fa 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad_fc6d36(texture2d_array<int, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  int4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.spvasm
index 409b074..3710212 100644
--- a/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fc6d36.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,20 +66,22 @@
       %int_1 = OpConstant %int 1
          %23 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4int = OpTypePointer Function %v4int
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4int
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fc6d36 = OpFunction %v4int None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %27 = OpLoad %8 %arg_0 None
          %28 = OpLoad %v2int %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %31 = OpCompositeConstruct %v3int %28 %29
-         %32 = OpImageRead %v4int %27 %31 None
-               OpStore %res %32
-         %35 = OpLoad %v4int %res None
-               OpReturnValue %35
+         %30 = OpImageQuerySize %v3uint %27
+         %33 = OpCompositeExtract %uint %30 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %29
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %27
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %28
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4int %27 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4int %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4int %textureLoad_fc6d36
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4int %textureLoad_fc6d36
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4int %textureLoad_fc6d36
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4int %textureLoad_fc6d36
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4int %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4int %out %uint_1
+         %74 = OpFunctionCall %v4int %textureLoad_fc6d36
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4int %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.glsl
index 129488c..7bc561d 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 float textureLoad_fcd23d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 float textureLoad_fcd23d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_2, int(v_1)).x;
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_3, int(v_2)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 float textureLoad_fcd23d() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  float res = texelFetch(arg_0, v_1, int(v)).x;
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  float res = texelFetch(arg_0, v_2, int(v_1)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
index b634e31..6cabef8 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(v_2, int(v)).x;
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fcd23d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
index b634e31..6cabef8 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float res = arg_0.Load(v_1, int(v)).x;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  float res = arg_0.Load(v_2, int(v)).x;
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fcd23d();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.msl
index 19c2139..cc50961 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 float textureLoad_fcd23d(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  int const v_1 = arg_2;
+  float res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_ms<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.msl
index 3443921..7b37476 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.msl
@@ -4,7 +4,7 @@
 float textureLoad_fcd23d(depth2d_ms<float, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  float res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.spvasm
index d641b78..c726865 100644
--- a/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fcd23d.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,15 +67,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %37 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %49 = OpTypeFunction %VertexOutput
+         %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %53 = OpConstantNull %VertexOutput
+         %57 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %56 = OpConstantNull %v4float
+         %60 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fcd23d = OpFunction %float None %15
          %16 = OpLabel
@@ -85,44 +87,47 @@
          %27 = OpLoad %7 %arg_0 None
          %28 = OpLoad %v2uint %arg_1 None
          %29 = OpLoad %int %arg_2 None
-         %30 = OpImageFetch %v4float %27 %28 Sample %29
-         %31 = OpCompositeExtract %float %30 0
-               OpStore %res %31
-         %34 = OpLoad %float %res None
-               OpReturnValue %34
+         %30 = OpImageQuerySize %v2uint %27
+         %31 = OpISub %v2uint %30 %21
+         %32 = OpExtInst %v2uint %33 UMin %28 %31
+         %34 = OpImageFetch %v4float %27 %32 Sample %29
+         %35 = OpCompositeExtract %float %34 0
+               OpStore %res %35
+         %38 = OpLoad %float %res None
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %37
-         %38 = OpLabel
-         %39 = OpFunctionCall %float %textureLoad_fcd23d
-         %40 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %40 %39 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %float %textureLoad_fcd23d
+         %44 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %37
-         %44 = OpLabel
-         %45 = OpFunctionCall %float %textureLoad_fcd23d
-         %46 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %46 %45 None
+%compute_main = OpFunction %void None %41
+         %48 = OpLabel
+         %49 = OpFunctionCall %float %textureLoad_fcd23d
+         %50 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %50 %49 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %49
-         %50 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %53
-         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %54 %56 None
-         %57 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %58 = OpFunctionCall %float %textureLoad_fcd23d
-               OpStore %57 %58 None
-         %59 = OpLoad %VertexOutput %out None
-               OpReturnValue %59
+%vertex_main_inner = OpFunction %VertexOutput None %53
+         %54 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %57
+         %58 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %58 %60 None
+         %61 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %62 = OpFunctionCall %float %textureLoad_fcd23d
+               OpStore %61 %62 None
+         %63 = OpLoad %VertexOutput %out None
+               OpReturnValue %63
                OpFunctionEnd
-%vertex_main = OpFunction %void None %37
-         %61 = OpLabel
-         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %63 = OpCompositeExtract %v4float %62 0
-               OpStore %vertex_main_position_Output %63 None
-         %64 = OpCompositeExtract %float %62 1
-               OpStore %vertex_main_loc0_Output %64 None
+%vertex_main = OpFunction %void None %41
+         %65 = OpLabel
+         %66 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %67 = OpCompositeExtract %v4float %66 0
+               OpStore %vertex_main_position_Output %67 None
+         %68 = OpCompositeExtract %float %66 1
+               OpStore %vertex_main_loc0_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.glsl
index 3cf9055..eb02638 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.glsl
@@ -9,7 +9,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_fd6442() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 void main() {
@@ -24,7 +25,8 @@
 layout(binding = 0, rgba8ui) uniform highp readonly uimage2D arg_0;
 uvec4 textureLoad_fd6442() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v_1 = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v_1, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +45,8 @@
 layout(location = 0) flat out uvec4 vertex_main_loc0_Output;
 uvec4 textureLoad_fd6442() {
   uvec2 arg_1 = uvec2(1u);
-  uvec4 res = imageLoad(arg_0, ivec2(arg_1));
+  uvec2 v = arg_1;
+  uvec4 res = imageLoad(arg_0, ivec2(min(v, (uvec2(imageSize(arg_0)) - uvec2(1u)))));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +56,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_1 = vertex_main_inner();
+  gl_Position = v_1.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_1.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
index ec86be3..a8b6549 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fd6442() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fd6442();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
index ec86be3..a8b6549 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,9 @@
 Texture2D<uint4> arg_0 : register(t0, space1);
 uint4 textureLoad_fd6442() {
   uint2 arg_1 = (1u).xx;
-  uint4 res = uint4(arg_0.Load(int3(int2(arg_1), int(0))));
+  uint2 v = (0u).xx;
+  arg_0.GetDimensions(v.x, v.y);
+  uint4 res = uint4(arg_0.Load(int3(int2(min(arg_1, (v - (1u).xx))), int(0))));
   return res;
 }
 
@@ -30,13 +32,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fd6442();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_1 = tint_symbol;
+  return v_1;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_2 = vertex_main_inner();
+  vertex_main_outputs v_3 = {v_2.prevent_dce, v_2.pos};
+  return v_3;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.msl
index d856a92..4a220d9 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.ir.msl
@@ -18,7 +18,8 @@
 
 uint4 textureLoad_fd6442(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_module_vars.arg_0.read(arg_1);
+  uint2 const v = arg_1;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))));
   return res;
 }
 
@@ -41,9 +42,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_1.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.msl
index 6c2d263..ef13b27 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 uint4 textureLoad_fd6442(texture2d<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
-  uint4 res = tint_symbol_1.read(uint2(arg_1));
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.spvasm
index 04cbae1..cc737ef 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fd6442.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 66
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -64,15 +66,15 @@
          %23 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %45 = OpTypeFunction %VertexOutput
+         %49 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %49 = OpConstantNull %VertexOutput
+         %53 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %52 = OpConstantNull %v4float
+         %56 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fd6442 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -81,43 +83,46 @@
                OpStore %arg_1 %23
          %25 = OpLoad %8 %arg_0 None
          %26 = OpLoad %v2uint %arg_1 None
-         %27 = OpImageRead %v4uint %25 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %27 = OpImageQuerySize %v2uint %25
+         %28 = OpISub %v2uint %27 %23
+         %29 = OpExtInst %v2uint %30 UMin %26 %28
+         %31 = OpImageRead %v4uint %25 %29 None
+               OpStore %res %31
+         %34 = OpLoad %v4uint %res None
+               OpReturnValue %34
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_fd6442
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %37
+         %38 = OpLabel
+         %39 = OpFunctionCall %v4uint %textureLoad_fd6442
+         %40 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %40 %39 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_fd6442
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %37
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4uint %textureLoad_fd6442
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %45
-         %46 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %49
-         %50 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %50 %52 None
-         %53 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %54 = OpFunctionCall %v4uint %textureLoad_fd6442
-               OpStore %53 %54 None
-         %55 = OpLoad %VertexOutput %out None
-               OpReturnValue %55
+%vertex_main_inner = OpFunction %VertexOutput None %49
+         %50 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %53
+         %54 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %54 %56 None
+         %57 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %58 = OpFunctionCall %v4uint %textureLoad_fd6442
+               OpStore %57 %58 None
+         %59 = OpLoad %VertexOutput %out None
+               OpReturnValue %59
                OpFunctionEnd
-%vertex_main = OpFunction %void None %33
-         %57 = OpLabel
-         %58 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
-         %60 = OpCompositeExtract %v4uint %58 1
-               OpStore %vertex_main_loc0_Output %60 None
+%vertex_main = OpFunction %void None %37
+         %61 = OpLabel
+         %62 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %63 = OpCompositeExtract %v4float %62 0
+               OpStore %vertex_main_position_Output %63 None
+         %64 = OpCompositeExtract %v4uint %62 1
+               OpStore %vertex_main_loc0_Output %64 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
index 6845e05..8f3daa0 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_fd9606() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
index 6845e05..8f3daa0 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 float4 textureLoad_fd9606() {
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  float4 res = float4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  int2 v_4 = int2(min(v, (v_3.xy - (1u).xx)));
+  float4 res = float4(arg_0.Load(int4(v_4, int(v_2), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.msl
index 51e8cdb..1ba1c86 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.ir.msl
@@ -9,7 +9,9 @@
 float4 textureLoad_fd9606(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  float4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u))), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.msl
index f5f3077..d57a63e 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_fd9606(texture2d_array<float, access::read_write> tint_symbol) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  float4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  float4 res = tint_symbol.read(uint2(min(arg_1, (uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u)))), tint_clamp(arg_2, 0, int((tint_symbol.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.spvasm
index 8db848e..3f0d882 100644
--- a/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fd9606.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 53
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -46,7 +48,7 @@
      %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %34 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
      %uint_0 = OpConstant %uint 0
 %textureLoad_fd9606 = OpFunction %v4float None %10
@@ -59,24 +61,32 @@
          %22 = OpLoad %8 %arg_0 None
          %23 = OpLoad %v2uint %arg_1 None
          %24 = OpLoad %int %arg_2 None
-         %25 = OpBitcast %uint %24
-         %27 = OpCompositeConstruct %v3uint %23 %25
-         %28 = OpImageRead %v4float %22 %27 None
-               OpStore %res %28
-         %31 = OpLoad %v4float %res None
-               OpReturnValue %31
+         %25 = OpImageQuerySize %v3uint %22
+         %27 = OpCompositeExtract %uint %25 2
+         %28 = OpISub %uint %27 %uint_1
+         %29 = OpBitcast %uint %24
+         %30 = OpExtInst %uint %31 UMin %29 %28
+         %32 = OpImageQuerySize %v3uint %22
+         %33 = OpVectorShuffle %v2uint %32 %32 0 1
+         %34 = OpISub %v2uint %33 %16
+         %35 = OpExtInst %v2uint %31 UMin %23 %34
+         %36 = OpCompositeConstruct %v3uint %35 %30
+         %37 = OpImageRead %v4float %22 %36 None
+               OpStore %res %37
+         %40 = OpLoad %v4float %res None
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %34
-         %35 = OpLabel
-         %36 = OpFunctionCall %v4float %textureLoad_fd9606
-         %37 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %37 %36 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %v4float %textureLoad_fd9606
+         %46 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %34
-         %41 = OpLabel
-         %42 = OpFunctionCall %v4float %textureLoad_fd9606
-         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %43 %42 None
+%compute_main = OpFunction %void None %43
+         %50 = OpLabel
+         %51 = OpFunctionCall %v4float %textureLoad_fd9606
+         %52 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %52 %51 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.glsl
index 30c2eac..df364b4 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.glsl
@@ -10,9 +10,13 @@
 uvec4 textureLoad_fdebd0() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 void main() {
@@ -28,9 +32,13 @@
 uvec4 textureLoad_fdebd0() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_2, int(v_1)));
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_4 = min(uint(v_2), v_3);
+  uvec2 v_5 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_6 = ivec2(min(uvec2(v_1), v_5));
+  uvec4 res = imageLoad(arg_0, ivec3(v_6, int(v_4)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +58,13 @@
 uvec4 textureLoad_fdebd0() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = imageLoad(arg_0, ivec3(v_1, int(v)));
+  ivec2 v = arg_1;
+  int v_1 = arg_2;
+  uint v_2 = (uint(imageSize(arg_0).z) - 1u);
+  uint v_3 = min(uint(v_1), v_2);
+  uvec2 v_4 = (uvec2(imageSize(arg_0).xy) - uvec2(1u));
+  ivec2 v_5 = ivec2(min(uvec2(v), v_4));
+  uvec4 res = imageLoad(arg_0, ivec3(v_5, int(v_3)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +74,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_6 = vertex_main_inner();
+  gl_Position = v_6.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_6.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
index 278d557..3b3fd73 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_fdebd0() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fdebd0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
index 278d557..3b3fd73 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.fxc.hlsl
@@ -14,9 +14,15 @@
 uint4 textureLoad_fdebd0() {
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
-  int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  int2 v = arg_1;
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  uint v_2 = min(uint(arg_2), (v_1.z - 1u));
+  uint3 v_3 = (0u).xxx;
+  arg_0.GetDimensions(v_3.x, v_3.y, v_3.z);
+  uint2 v_4 = (v_3.xy - (1u).xx);
+  int2 v_5 = int2(min(uint2(v), v_4));
+  uint4 res = uint4(arg_0.Load(int4(v_5, int(v_2), int(0))));
   return res;
 }
 
@@ -33,13 +39,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fdebd0();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_6 = tint_symbol;
+  return v_6;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_7 = vertex_main_inner();
+  vertex_main_outputs v_8 = {v_7.prevent_dce, v_7.pos};
+  return v_8;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.msl
index 5323d74..ad9dcca 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.ir.msl
@@ -19,8 +19,10 @@
 uint4 textureLoad_fdebd0(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  int const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
@@ -43,9 +45,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_array<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_1 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_3 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_1.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_1.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_3.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_3.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.msl
index 86dd20e..1f60135 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.msl
@@ -1,10 +1,18 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_fdebd0(texture2d_array<uint, access::read> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.spvasm
index fe15dda..01973aa 100644
--- a/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fdebd0.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 69
+; Bound: 82
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %38 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,19 +67,21 @@
       %int_1 = OpConstant %int 1
          %24 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_int = OpTypePointer Function %int
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %43 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %53 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %51 = OpTypeFunction %VertexOutput
+         %65 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %55 = OpConstantNull %VertexOutput
+         %69 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %58 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %72 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fdebd0 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -89,44 +93,54 @@
          %28 = OpLoad %8 %arg_0 None
          %29 = OpLoad %v2int %arg_1 None
          %30 = OpLoad %int %arg_2 None
-         %32 = OpCompositeConstruct %v3int %29 %30
-         %33 = OpImageRead %v4uint %28 %32 None
-               OpStore %res %33
-         %36 = OpLoad %v4uint %res None
-               OpReturnValue %36
+         %31 = OpImageQuerySize %v3uint %28
+         %33 = OpCompositeExtract %uint %31 2
+         %34 = OpISub %uint %33 %uint_1
+         %36 = OpBitcast %uint %30
+         %37 = OpExtInst %uint %38 UMin %36 %34
+         %39 = OpImageQuerySize %v3uint %28
+         %40 = OpVectorShuffle %v2uint %39 %39 0 1
+         %42 = OpISub %v2uint %40 %43
+         %44 = OpBitcast %v2uint %29
+         %45 = OpExtInst %v2uint %38 UMin %44 %42
+         %46 = OpCompositeConstruct %v3uint %45 %37
+         %47 = OpImageRead %v4uint %28 %46 None
+               OpStore %res %47
+         %50 = OpLoad %v4uint %res None
+               OpReturnValue %50
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_fdebd0
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %53
+         %54 = OpLabel
+         %55 = OpFunctionCall %v4uint %textureLoad_fdebd0
+         %56 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %56 %55 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
-         %46 = OpLabel
-         %47 = OpFunctionCall %v4uint %textureLoad_fdebd0
-         %48 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %48 %47 None
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %51
-         %52 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %55
-         %56 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %56 %58 None
-         %59 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+%compute_main = OpFunction %void None %53
+         %60 = OpLabel
          %61 = OpFunctionCall %v4uint %textureLoad_fdebd0
-               OpStore %59 %61 None
-         %62 = OpLoad %VertexOutput %out None
-               OpReturnValue %62
+         %62 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %62 %61 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
-         %64 = OpLabel
-         %65 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %66 = OpCompositeExtract %v4float %65 0
-               OpStore %vertex_main_position_Output %66 None
-         %67 = OpCompositeExtract %v4uint %65 1
-               OpStore %vertex_main_loc0_Output %67 None
+%vertex_main_inner = OpFunction %VertexOutput None %65
+         %66 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %69
+         %70 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %70 %72 None
+         %73 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %74 = OpFunctionCall %v4uint %textureLoad_fdebd0
+               OpStore %73 %74 None
+         %75 = OpLoad %VertexOutput %out None
+               OpReturnValue %75
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %53
+         %77 = OpLabel
+         %78 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %79 = OpCompositeExtract %v4float %78 0
+               OpStore %vertex_main_position_Output %79 None
+         %80 = OpCompositeExtract %v4uint %78 1
+               OpStore %vertex_main_loc0_Output %80 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.glsl
index 0eeb65f..48e0008 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.glsl
@@ -10,9 +10,10 @@
 uvec4 textureLoad_fe0565() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 void main() {
@@ -28,9 +29,10 @@
 uvec4 textureLoad_fe0565() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v_1 = arg_2;
-  ivec2 v_2 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
+  uvec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  ivec2 v_3 = ivec2(min(v_1, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_3, int(v_2));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -50,9 +52,10 @@
 uvec4 textureLoad_fe0565() {
   uvec2 arg_1 = uvec2(1u);
   int arg_2 = 1;
-  int v = arg_2;
-  ivec2 v_1 = ivec2(arg_1);
-  uvec4 res = texelFetch(arg_0, v_1, int(v));
+  uvec2 v = arg_1;
+  int v_1 = arg_2;
+  ivec2 v_2 = ivec2(min(v, (uvec2(textureSize(arg_0)) - uvec2(1u))));
+  uvec4 res = texelFetch(arg_0, v_2, int(v_1));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -62,10 +65,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_2 = vertex_main_inner();
-  gl_Position = v_2.pos;
+  VertexOutput v_3 = vertex_main_inner();
+  gl_Position = v_3.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_2.prevent_dce;
+  vertex_main_loc0_Output = v_3.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
index 6fe9733..7567440 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.dxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe0565();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
index 6fe9733..7567440 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.fxc.hlsl
@@ -15,8 +15,10 @@
   uint2 arg_1 = (1u).xx;
   int arg_2 = int(1);
   int v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(v_1, int(v)));
+  uint3 v_1 = (0u).xxx;
+  arg_0.GetDimensions(v_1.x, v_1.y, v_1.z);
+  int2 v_2 = int2(min(arg_1, (v_1.xy - (1u).xx)));
+  uint4 res = uint4(arg_0.Load(v_2, int(v)));
   return res;
 }
 
@@ -33,13 +35,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe0565();
-  VertexOutput v_2 = tint_symbol;
-  return v_2;
+  VertexOutput v_3 = tint_symbol;
+  return v_3;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_3 = vertex_main_inner();
-  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
-  return v_4;
+  VertexOutput v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.prevent_dce, v_4.pos};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.msl
index 774ae92..f0c6ec4 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.ir.msl
@@ -19,7 +19,9 @@
 uint4 textureLoad_fe0565(tint_module_vars_struct tint_module_vars) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_module_vars.arg_0.read(arg_1, arg_2);
+  uint2 const v = arg_1;
+  int const v_1 = arg_2;
+  uint4 res = tint_module_vars.arg_0.read(min(v, (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u))), v_1);
   return res;
 }
 
@@ -42,9 +44,9 @@
 
 vertex vertex_main_outputs vertex_main(texture2d_ms<uint, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.msl
index 269651b..ee61edd 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.msl
@@ -4,7 +4,7 @@
 uint4 textureLoad_fe0565(texture2d_ms<uint, access::read> tint_symbol_1) {
   uint2 arg_1 = uint2(1u);
   int arg_2 = 1;
-  uint4 res = tint_symbol_1.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol_1.read(uint2(min(arg_1, (uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), arg_2);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.spvasm
index 3eafcf5..830adc3 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fe0565.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 67
+; Bound: 71
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %35 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -67,15 +69,15 @@
       %int_1 = OpConstant %int 1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4uint
-         %50 = OpTypeFunction %VertexOutput
+         %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %54 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %57 = OpConstantNull %v4float
+         %61 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fe0565 = OpFunction %v4uint None %18
          %19 = OpLabel
@@ -87,43 +89,46 @@
          %29 = OpLoad %8 %arg_0 None
          %30 = OpLoad %v2uint %arg_1 None
          %31 = OpLoad %int %arg_2 None
-         %32 = OpImageFetch %v4uint %29 %30 Sample %31
-               OpStore %res %32
-         %35 = OpLoad %v4uint %res None
-               OpReturnValue %35
+         %32 = OpImageQuerySize %v2uint %29
+         %33 = OpISub %v2uint %32 %23
+         %34 = OpExtInst %v2uint %35 UMin %30 %33
+         %36 = OpImageFetch %v4uint %29 %34 Sample %31
+               OpStore %res %36
+         %39 = OpLoad %v4uint %res None
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4uint %textureLoad_fe0565
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %v4uint %textureLoad_fe0565
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
-         %45 = OpLabel
-         %46 = OpFunctionCall %v4uint %textureLoad_fe0565
-         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %47 %46 None
+%compute_main = OpFunction %void None %42
+         %49 = OpLabel
+         %50 = OpFunctionCall %v4uint %textureLoad_fe0565
+         %51 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %51 %50 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %50
-         %51 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %54
-         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %55 %57 None
-         %58 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
-         %59 = OpFunctionCall %v4uint %textureLoad_fe0565
-               OpStore %58 %59 None
-         %60 = OpLoad %VertexOutput %out None
-               OpReturnValue %60
+%vertex_main_inner = OpFunction %VertexOutput None %54
+         %55 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %58
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %59 %61 None
+         %62 = OpAccessChain %_ptr_Function_v4uint %out %uint_1
+         %63 = OpFunctionCall %v4uint %textureLoad_fe0565
+               OpStore %62 %63 None
+         %64 = OpLoad %VertexOutput %out None
+               OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-         %62 = OpLabel
-         %63 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %64 = OpCompositeExtract %v4float %63 0
-               OpStore %vertex_main_position_Output %64 None
-         %65 = OpCompositeExtract %v4uint %63 1
-               OpStore %vertex_main_loc0_Output %65 None
+%vertex_main = OpFunction %void None %42
+         %66 = OpLabel
+         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
+         %69 = OpCompositeExtract %v4uint %67 1
+               OpStore %vertex_main_loc0_Output %69 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.glsl
index 4292f3e..4a4bb00 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_fe222a() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba8_snorm) uniform highp readonly image2D arg_0;
 vec4 textureLoad_fe222a() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v_1 = arg_1;
+  uint v_2 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v_1), v_2), 0u)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_fe222a() {
   int arg_1 = 1;
-  vec4 res = imageLoad(arg_0, ivec2(ivec2(arg_1, 0)));
+  int v = arg_1;
+  uint v_1 = (uvec2(imageSize(arg_0)).x - 1u);
+  vec4 res = imageLoad(arg_0, ivec2(uvec2(min(uint(v), v_1), 0u)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
index 50e21c8..a7fbd6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_fe222a() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe222a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
index 50e21c8..a7fbd6a 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture1D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_fe222a() {
   int arg_1 = int(1);
-  float4 res = float4(arg_0.Load(int2(int(arg_1), int(0))));
+  uint v = 0u;
+  arg_0.GetDimensions(v);
+  uint v_1 = (v - 1u);
+  float4 res = float4(arg_0.Load(int2(int(min(uint(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_fe222a();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.msl
index 15e37b3..01f8419 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_fe222a(tint_module_vars_struct tint_module_vars) {
   int arg_1 = 1;
-  float4 res = tint_module_vars.arg_0.read(uint(arg_1));
+  int const v = arg_1;
+  uint const v_1 = (uint(tint_module_vars.arg_0.get_width()) - 1u);
+  float4 res = tint_module_vars.arg_0.read(min(uint(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture1d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.msl
index 7842557..2e7e8b0 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int tint_clamp(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_fe222a(texture1d<float, access::read> tint_symbol_1) {
   int arg_1 = 1;
-  float4 res = tint_symbol_1.read(uint(arg_1));
+  float4 res = tint_symbol_1.read(uint(tint_clamp(arg_1, 0, int((tint_symbol_1.get_width(0) - 1u)))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.spvasm
index 6e0ad17..309e4905 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fe222a.wgsl.expected.spvasm
@@ -1,10 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 59
+; Bound: 64
 ; Schema: 0
                OpCapability Shader
                OpCapability Image1D
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -59,18 +61,18 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %36 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %42 = OpTypeFunction %VertexOutput
+         %48 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %46 = OpConstantNull %VertexOutput
-         %48 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %52 = OpConstantNull %VertexOutput
+         %54 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_fe222a = OpFunction %v4float None %15
          %16 = OpLabel
@@ -79,43 +81,47 @@
                OpStore %arg_1 %int_1
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %int %arg_1 None
-         %23 = OpImageRead %v4float %21 %22 None
-               OpStore %res %23
-         %26 = OpLoad %v4float %res None
-               OpReturnValue %26
+         %23 = OpImageQuerySize %uint %21
+         %25 = OpISub %uint %23 %uint_1
+         %27 = OpBitcast %uint %22
+         %28 = OpExtInst %uint %29 UMin %27 %25
+         %30 = OpImageRead %v4float %21 %28 None
+               OpStore %res %30
+         %33 = OpLoad %v4float %res None
+               OpReturnValue %33
                OpFunctionEnd
-%fragment_main = OpFunction %void None %29
-         %30 = OpLabel
-         %31 = OpFunctionCall %v4float %textureLoad_fe222a
-         %32 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %32 %31 None
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %29
+%fragment_main = OpFunction %void None %36
          %37 = OpLabel
          %38 = OpFunctionCall %v4float %textureLoad_fe222a
          %39 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
                OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %42
+%compute_main = OpFunction %void None %36
          %43 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %46
-         %47 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %47 %48 None
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %51 = OpFunctionCall %v4float %textureLoad_fe222a
-               OpStore %49 %51 None
-         %52 = OpLoad %VertexOutput %out None
-               OpReturnValue %52
+         %44 = OpFunctionCall %v4float %textureLoad_fe222a
+         %45 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %45 %44 None
+               OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %29
-         %54 = OpLabel
-         %55 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %56 = OpCompositeExtract %v4float %55 0
-               OpStore %vertex_main_position_Output %56 None
-         %57 = OpCompositeExtract %v4float %55 1
-               OpStore %vertex_main_loc0_Output %57 None
+%vertex_main_inner = OpFunction %VertexOutput None %48
+         %49 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %52
+         %53 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %53 %54 None
+         %55 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %56 = OpFunctionCall %v4float %textureLoad_fe222a
+               OpStore %55 %56 None
+         %57 = OpLoad %VertexOutput %out None
+               OpReturnValue %57
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %36
+         %59 = OpLabel
+         %60 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %61 = OpCompositeExtract %v4float %60 0
+               OpStore %vertex_main_position_Output %61 None
+         %62 = OpCompositeExtract %v4float %60 1
+               OpStore %vertex_main_loc0_Output %62 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
index ce4f84d..2e72c2a 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.dxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_fe2c1b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
index ce4f84d..2e72c2a 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.fxc.hlsl
@@ -4,9 +4,14 @@
 uint4 textureLoad_fe2c1b() {
   int2 arg_1 = (int(1)).xx;
   uint arg_2 = 1u;
-  uint v = arg_2;
-  int2 v_1 = int2(arg_1);
-  uint4 res = uint4(arg_0.Load(int4(v_1, int(v), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint v_1 = min(arg_2, (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(arg_1), v_3));
+  uint4 res = uint4(arg_0.Load(int4(v_4, int(v_1), int(0))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.msl
index 1a3f65e..45037a9 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.ir.msl
@@ -9,8 +9,10 @@
 uint4 textureLoad_fe2c1b(tint_module_vars_struct tint_module_vars) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint const v = arg_2;
-  uint4 res = tint_module_vars.arg_0.read(uint2(arg_1), v);
+  int2 const v = arg_1;
+  uint const v_1 = min(arg_2, (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_2 = (uint2(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u)) - uint2(1u));
+  uint4 res = tint_module_vars.arg_0.read(min(uint2(v), v_2), v_1);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.msl
index 3e71371..2b04660 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 uint4 textureLoad_fe2c1b(texture2d_array<uint, access::read_write> tint_symbol) {
   int2 arg_1 = int2(1);
   uint arg_2 = 1u;
-  uint4 res = tint_symbol.read(uint2(arg_1), arg_2);
+  uint4 res = tint_symbol.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol.get_width(), tint_symbol.get_height()) - uint2(1u))))), min(arg_2, (tint_symbol.get_array_size() - 1u)));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.spvasm
index 8709c35..6b0d73f 100644
--- a/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/fe2c1b.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 54
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -42,10 +44,12 @@
          %16 = OpConstantComposite %v2int %int_1 %int_1
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %v2uint = OpTypeVector %uint 2
+         %34 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_v4uint = OpTypePointer Function %v4uint
        %void = OpTypeVoid
-         %33 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %textureLoad_fe2c1b = OpFunction %v4uint None %10
@@ -58,24 +62,32 @@
          %21 = OpLoad %8 %arg_0 None
          %22 = OpLoad %v2int %arg_1 None
          %23 = OpLoad %uint %arg_2 None
-         %24 = OpBitcast %int %23
-         %26 = OpCompositeConstruct %v3int %22 %24
-         %27 = OpImageRead %v4uint %21 %26 None
-               OpStore %res %27
-         %30 = OpLoad %v4uint %res None
-               OpReturnValue %30
+         %24 = OpImageQuerySize %v3uint %21
+         %26 = OpCompositeExtract %uint %24 2
+         %27 = OpISub %uint %26 %uint_1
+         %28 = OpExtInst %uint %29 UMin %23 %27
+         %30 = OpImageQuerySize %v3uint %21
+         %31 = OpVectorShuffle %v2uint %30 %30 0 1
+         %33 = OpISub %v2uint %31 %34
+         %35 = OpBitcast %v2uint %22
+         %36 = OpExtInst %v2uint %29 UMin %35 %33
+         %37 = OpCompositeConstruct %v3uint %36 %28
+         %38 = OpImageRead %v4uint %21 %37 None
+               OpStore %res %38
+         %41 = OpLoad %v4uint %res None
+               OpReturnValue %41
                OpFunctionEnd
-%fragment_main = OpFunction %void None %33
-         %34 = OpLabel
-         %35 = OpFunctionCall %v4uint %textureLoad_fe2c1b
-         %36 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %36 %35 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %v4uint %textureLoad_fe2c1b
+         %47 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %33
-         %40 = OpLabel
-         %41 = OpFunctionCall %v4uint %textureLoad_fe2c1b
-         %42 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-               OpStore %42 %41 None
+%compute_main = OpFunction %void None %44
+         %51 = OpLabel
+         %52 = OpFunctionCall %v4uint %textureLoad_fe2c1b
+         %53 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+               OpStore %53 %52 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.glsl
index 31f3605..54e76a3 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.glsl
@@ -9,7 +9,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_feab99() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 void main() {
@@ -24,7 +26,9 @@
 layout(binding = 0, rgba16f) uniform highp readonly image3D arg_0;
 vec4 textureLoad_feab99() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v_1 = arg_1;
+  uvec3 v_2 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v_1), v_2)));
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -43,7 +47,9 @@
 layout(location = 0) flat out vec4 vertex_main_loc0_Output;
 vec4 textureLoad_feab99() {
   ivec3 arg_1 = ivec3(1);
-  vec4 res = imageLoad(arg_0, ivec3(arg_1));
+  ivec3 v = arg_1;
+  uvec3 v_1 = (uvec3(imageSize(arg_0)) - uvec3(1u));
+  vec4 res = imageLoad(arg_0, ivec3(min(uvec3(v), v_1)));
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -53,10 +59,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v = vertex_main_inner();
-  gl_Position = v.pos;
+  VertexOutput v_2 = vertex_main_inner();
+  gl_Position = v_2.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v.prevent_dce;
+  vertex_main_loc0_Output = v_2.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
index 5375854..14df26b 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_feab99() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_feab99();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
index 5375854..14df26b 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,10 @@
 Texture3D<float4> arg_0 : register(t0, space1);
 float4 textureLoad_feab99() {
   int3 arg_1 = (int(1)).xxx;
-  float4 res = float4(arg_0.Load(int4(int3(arg_1), int(0))));
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint3 v_1 = (v - (1u).xxx);
+  float4 res = float4(arg_0.Load(int4(int3(min(uint3(arg_1), v_1)), int(0))));
   return res;
 }
 
@@ -30,13 +33,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_feab99();
-  VertexOutput v = tint_symbol;
-  return v;
+  VertexOutput v_2 = tint_symbol;
+  return v_2;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_1 = vertex_main_inner();
-  vertex_main_outputs v_2 = {v_1.prevent_dce, v_1.pos};
-  return v_2;
+  VertexOutput v_3 = vertex_main_inner();
+  vertex_main_outputs v_4 = {v_3.prevent_dce, v_3.pos};
+  return v_4;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.msl
index 6e5994c..d3e76a2 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.ir.msl
@@ -18,7 +18,9 @@
 
 float4 textureLoad_feab99(tint_module_vars_struct tint_module_vars) {
   int3 arg_1 = int3(1);
-  float4 res = tint_module_vars.arg_0.read(uint3(arg_1));
+  int3 const v = arg_1;
+  uint3 const v_1 = (uint3(tint_module_vars.arg_0.get_width(0u), tint_module_vars.arg_0.get_height(0u), tint_module_vars.arg_0.get_depth(0u)) - uint3(1u));
+  float4 res = tint_module_vars.arg_0.read(min(uint3(v), v_1));
   return res;
 }
 
@@ -41,9 +43,9 @@
 
 vertex vertex_main_outputs vertex_main(texture3d<float, access::read> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_2.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.msl
index dfc00f5..65a8509 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int3 tint_clamp(int3 e, int3 low, int3 high) {
+  return min(max(e, low), high);
+}
+
 float4 textureLoad_feab99(texture3d<float, access::read> tint_symbol_1) {
   int3 arg_1 = int3(1);
-  float4 res = tint_symbol_1.read(uint3(arg_1));
+  float4 res = tint_symbol_1.read(uint3(tint_clamp(arg_1, int3(0), int3((uint3(tint_symbol_1.get_width(), tint_symbol_1.get_height(), tint_symbol_1.get_depth()) - uint3(1u))))));
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.spvasm
index 9f01c60..fc1fd28 100644
--- a/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/feab99.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 68
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -60,18 +62,20 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
       %int_1 = OpConstant %int 1
          %21 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
+         %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %void = OpTypeVoid
-         %31 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
-       %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %v4float
-         %44 = OpTypeFunction %VertexOutput
+         %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %48 = OpConstantNull %VertexOutput
-         %50 = OpConstantNull %v4float
-     %uint_1 = OpConstant %uint 1
+         %56 = OpConstantNull %VertexOutput
+         %58 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_feab99 = OpFunction %v4float None %15
          %16 = OpLabel
@@ -80,43 +84,47 @@
                OpStore %arg_1 %21
          %23 = OpLoad %8 %arg_0 None
          %24 = OpLoad %v3int %arg_1 None
-         %25 = OpImageRead %v4float %23 %24 None
-               OpStore %res %25
-         %28 = OpLoad %v4float %res None
-               OpReturnValue %28
+         %25 = OpImageQuerySize %v3uint %23
+         %28 = OpISub %v3uint %25 %29
+         %31 = OpBitcast %v3uint %24
+         %32 = OpExtInst %v3uint %33 UMin %31 %28
+         %34 = OpImageRead %v4float %23 %32 None
+               OpStore %res %34
+         %37 = OpLoad %v4float %res None
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %v4float %textureLoad_feab99
-         %34 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %34 %33 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %v4float %textureLoad_feab99
+         %43 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %31
-         %39 = OpLabel
-         %40 = OpFunctionCall %v4float %textureLoad_feab99
-         %41 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
-               OpStore %41 %40 None
+%compute_main = OpFunction %void None %40
+         %47 = OpLabel
+         %48 = OpFunctionCall %v4float %textureLoad_feab99
+         %49 = OpAccessChain %_ptr_StorageBuffer_v4float %1 %uint_0
+               OpStore %49 %48 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %44
-         %45 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %48
-         %49 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %49 %50 None
-         %51 = OpAccessChain %_ptr_Function_v4float %out %uint_1
-         %53 = OpFunctionCall %v4float %textureLoad_feab99
-               OpStore %51 %53 None
-         %54 = OpLoad %VertexOutput %out None
-               OpReturnValue %54
+%vertex_main_inner = OpFunction %VertexOutput None %52
+         %53 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %56
+         %57 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %57 %58 None
+         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_1
+         %60 = OpFunctionCall %v4float %textureLoad_feab99
+               OpStore %59 %60 None
+         %61 = OpLoad %VertexOutput %out None
+               OpReturnValue %61
                OpFunctionEnd
-%vertex_main = OpFunction %void None %31
-         %56 = OpLabel
-         %57 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %58 = OpCompositeExtract %v4float %57 0
-               OpStore %vertex_main_position_Output %58 None
-         %59 = OpCompositeExtract %v4float %57 1
-               OpStore %vertex_main_loc0_Output %59 None
+%vertex_main = OpFunction %void None %40
+         %63 = OpLabel
+         %64 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %65 = OpCompositeExtract %v4float %64 0
+               OpStore %vertex_main_position_Output %65 None
+         %66 = OpCompositeExtract %v4float %64 1
+               OpStore %vertex_main_loc0_Output %66 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.glsl
index f428017..666b4a3 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.glsl
@@ -2,20 +2,34 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_ff1119() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  float res = texelFetch(arg_0, v_10, int(v_7)).x;
   return res;
 }
 void main() {
@@ -23,20 +37,34 @@
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 layout(binding = 0, std430)
 buffer prevent_dce_block_1_ssbo {
   float inner;
 } v;
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v_1;
 uniform highp sampler2DArray arg_0;
 float textureLoad_ff1119() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v_1 = arg_2;
-  uint v_2 = arg_3;
-  ivec2 v_3 = ivec2(arg_1);
-  ivec3 v_4 = ivec3(v_3, int(v_1));
-  float res = texelFetch(arg_0, v_4, int(v_2)).x;
+  ivec2 v_2 = arg_1;
+  int v_3 = arg_2;
+  uint v_4 = arg_3;
+  uint v_5 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_6 = min(uint(v_3), v_5);
+  uint v_7 = min(v_4, (v_1.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_8 = (uvec2(textureSize(arg_0, int(v_7)).xy) - uvec2(1u));
+  ivec2 v_9 = ivec2(min(uvec2(v_2), v_8));
+  ivec3 v_10 = ivec3(v_9, int(v_6));
+  float res = texelFetch(arg_0, v_10, int(v_7)).x;
   return res;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
@@ -46,22 +74,35 @@
 #version 310 es
 
 
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
 struct VertexOutput {
   vec4 pos;
   float prevent_dce;
 };
 
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray arg_0;
 layout(location = 0) flat out float vertex_main_loc0_Output;
 float textureLoad_ff1119() {
   ivec2 arg_1 = ivec2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int v = arg_2;
-  uint v_1 = arg_3;
-  ivec2 v_2 = ivec2(arg_1);
-  ivec3 v_3 = ivec3(v_2, int(v));
-  float res = texelFetch(arg_0, v_3, int(v_1)).x;
+  ivec2 v_1 = arg_1;
+  int v_2 = arg_2;
+  uint v_3 = arg_3;
+  uint v_4 = (uint(textureSize(arg_0, 0).z) - 1u);
+  uint v_5 = min(uint(v_2), v_4);
+  uint v_6 = min(v_3, (v.inner.tint_builtin_value_0 - 1u));
+  uvec2 v_7 = (uvec2(textureSize(arg_0, int(v_6)).xy) - uvec2(1u));
+  ivec2 v_8 = ivec2(min(uvec2(v_1), v_7));
+  ivec3 v_9 = ivec3(v_8, int(v_5));
+  float res = texelFetch(arg_0, v_9, int(v_6)).x;
   return res;
 }
 VertexOutput vertex_main_inner() {
@@ -71,10 +112,10 @@
   return tint_symbol;
 }
 void main() {
-  VertexOutput v_4 = vertex_main_inner();
-  gl_Position = v_4.pos;
+  VertexOutput v_10 = vertex_main_inner();
+  gl_Position = v_10.pos;
   gl_Position[1u] = -(gl_Position.y);
   gl_Position[2u] = ((2.0f * gl_Position.z) - gl_Position.w);
-  vertex_main_loc0_Output = v_4.prevent_dce;
+  vertex_main_loc0_Output = v_10.prevent_dce;
   gl_PointSize = 1.0f;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
index 17da49f..af9cd14 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.dxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  float res = arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ff1119();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
index 17da49f..af9cd14 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.fxc.hlsl
@@ -15,11 +15,19 @@
   int2 arg_1 = (int(1)).xx;
   int arg_2 = int(1);
   uint arg_3 = 1u;
-  int v = arg_2;
+  int2 v = arg_1;
   uint v_1 = arg_3;
-  int2 v_2 = int2(arg_1);
-  int v_3 = int(v);
-  float res = arg_0.Load(int4(v_2, v_3, int(v_1))).x;
+  uint3 v_2 = (0u).xxx;
+  arg_0.GetDimensions(v_2.x, v_2.y, v_2.z);
+  uint v_3 = min(uint(arg_2), (v_2.z - 1u));
+  uint4 v_4 = (0u).xxxx;
+  arg_0.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  arg_0.GetDimensions(uint(min(v_1, (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 v_6 = (v_5.xy - (1u).xx);
+  int2 v_7 = int2(min(uint2(v), v_6));
+  int v_8 = int(v_3);
+  float res = arg_0.Load(int4(v_7, v_8, int(min(v_1, (v_4.w - 1u))))).x;
   return res;
 }
 
@@ -36,13 +44,13 @@
   VertexOutput tint_symbol = (VertexOutput)0;
   tint_symbol.pos = (0.0f).xxxx;
   tint_symbol.prevent_dce = textureLoad_ff1119();
-  VertexOutput v_4 = tint_symbol;
-  return v_4;
+  VertexOutput v_9 = tint_symbol;
+  return v_9;
 }
 
 vertex_main_outputs vertex_main() {
-  VertexOutput v_5 = vertex_main_inner();
-  vertex_main_outputs v_6 = {v_5.prevent_dce, v_5.pos};
-  return v_6;
+  VertexOutput v_10 = vertex_main_inner();
+  vertex_main_outputs v_11 = {v_10.prevent_dce, v_10.pos};
+  return v_11;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.msl
index fb43258..256f2d4 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.ir.msl
@@ -20,9 +20,11 @@
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  int const v = arg_2;
+  int2 const v = arg_1;
   uint const v_1 = arg_3;
-  float res = tint_module_vars.arg_0.read(uint2(arg_1), v, v_1);
+  uint const v_2 = min(uint(arg_2), (tint_module_vars.arg_0.get_array_size() - 1u));
+  uint2 const v_3 = (uint2(tint_module_vars.arg_0.get_width(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u))), tint_module_vars.arg_0.get_height(min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)))) - uint2(1u));
+  float res = tint_module_vars.arg_0.read(min(uint2(v), v_3), v_2, min(v_1, (tint_module_vars.arg_0.get_num_mip_levels() - 1u)));
   return res;
 }
 
@@ -45,9 +47,9 @@
 
 vertex vertex_main_outputs vertex_main(depth2d_array<float, access::sample> arg_0 [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
-  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
+  VertexOutput const v_4 = vertex_main_inner(tint_module_vars);
   vertex_main_outputs tint_wrapper_result = {};
-  tint_wrapper_result.VertexOutput_pos = v_2.pos;
-  tint_wrapper_result.VertexOutput_prevent_dce = v_2.prevent_dce;
+  tint_wrapper_result.VertexOutput_pos = v_4.pos;
+  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
   return tint_wrapper_result;
 }
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.msl b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.msl
index fde3992..e335f30 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.msl
@@ -1,11 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
+int tint_clamp_1(int e, int low, int high) {
+  return min(max(e, low), high);
+}
+
 float textureLoad_ff1119(depth2d_array<float, access::sample> tint_symbol_1) {
   int2 arg_1 = int2(1);
   int arg_2 = 1;
   uint arg_3 = 1u;
-  float res = tint_symbol_1.read(uint2(arg_1), arg_2, arg_3);
+  uint const level_idx = min(uint(arg_3), (tint_symbol_1.get_num_mip_levels() - 1u));
+  float res = tint_symbol_1.read(uint2(tint_clamp(arg_1, int2(0), int2((uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx)) - uint2(1u))))), tint_clamp_1(arg_2, 0, int((tint_symbol_1.get_array_size() - 1u))), level_idx);
   return res;
 }
 
diff --git a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.spvasm b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.spvasm
index 7bf5ecb..d71a394 100644
--- a/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/textureLoad/ff1119.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 71
+; Bound: 87
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -65,18 +67,20 @@
        %uint = OpTypeInt 32 0
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %v3int = OpTypeVector %int 3
+     %v3uint = OpTypeVector %uint 3
+     %uint_0 = OpConstant %uint 0
+     %v2uint = OpTypeVector %uint 2
+         %48 = OpConstantComposite %v2uint %uint_1 %uint_1
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %59 = OpTypeFunction %void
 %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %float
-         %54 = OpTypeFunction %VertexOutput
+         %70 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
-         %58 = OpConstantNull %VertexOutput
+         %74 = OpConstantNull %VertexOutput
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %61 = OpConstantNull %v4float
+         %77 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad_ff1119 = OpFunction %float None %15
          %16 = OpLabel
@@ -91,45 +95,58 @@
          %30 = OpLoad %v2int %arg_1 None
          %31 = OpLoad %int %arg_2 None
          %32 = OpLoad %uint %arg_3 None
-         %34 = OpCompositeConstruct %v3int %30 %31
-         %35 = OpImageFetch %v4float %29 %34 Lod %32
-         %36 = OpCompositeExtract %float %35 0
-               OpStore %res %36
-         %39 = OpLoad %float %res None
-               OpReturnValue %39
+         %33 = OpImageQuerySizeLod %v3uint %29 %uint_0
+         %36 = OpCompositeExtract %uint %33 2
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpBitcast %uint %31
+         %39 = OpExtInst %uint %40 UMin %38 %37
+         %41 = OpImageQueryLevels %uint %29
+         %42 = OpISub %uint %41 %uint_1
+         %43 = OpExtInst %uint %40 UMin %32 %42
+         %44 = OpImageQuerySizeLod %v3uint %29 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+         %47 = OpISub %v2uint %45 %48
+         %49 = OpBitcast %v2uint %30
+         %50 = OpExtInst %v2uint %40 UMin %49 %47
+         %51 = OpCompositeConstruct %v3uint %50 %39
+         %52 = OpImageFetch %v4float %29 %51 Lod %43
+         %53 = OpCompositeExtract %float %52 0
+               OpStore %res %53
+         %56 = OpLoad %float %res None
+               OpReturnValue %56
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %float %textureLoad_ff1119
-         %45 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %59
+         %60 = OpLabel
+         %61 = OpFunctionCall %float %textureLoad_ff1119
+         %62 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %62 %61 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
-         %49 = OpLabel
-         %50 = OpFunctionCall %float %textureLoad_ff1119
-         %51 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
-               OpStore %51 %50 None
+%compute_main = OpFunction %void None %59
+         %65 = OpLabel
+         %66 = OpFunctionCall %float %textureLoad_ff1119
+         %67 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0
+               OpStore %67 %66 None
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %VertexOutput None %54
-         %55 = OpLabel
-        %out = OpVariable %_ptr_Function_VertexOutput Function %58
-         %59 = OpAccessChain %_ptr_Function_v4float %out %uint_0
-               OpStore %59 %61 None
-         %62 = OpAccessChain %_ptr_Function_float %out %uint_1
-         %63 = OpFunctionCall %float %textureLoad_ff1119
-               OpStore %62 %63 None
-         %64 = OpLoad %VertexOutput %out None
-               OpReturnValue %64
+%vertex_main_inner = OpFunction %VertexOutput None %70
+         %71 = OpLabel
+        %out = OpVariable %_ptr_Function_VertexOutput Function %74
+         %75 = OpAccessChain %_ptr_Function_v4float %out %uint_0
+               OpStore %75 %77 None
+         %78 = OpAccessChain %_ptr_Function_float %out %uint_1
+         %79 = OpFunctionCall %float %textureLoad_ff1119
+               OpStore %78 %79 None
+         %80 = OpLoad %VertexOutput %out None
+               OpReturnValue %80
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
-         %66 = OpLabel
-         %67 = OpFunctionCall %VertexOutput %vertex_main_inner
-         %68 = OpCompositeExtract %v4float %67 0
-               OpStore %vertex_main_position_Output %68 None
-         %69 = OpCompositeExtract %float %67 1
-               OpStore %vertex_main_loc0_Output %69 None
+%vertex_main = OpFunction %void None %59
+         %82 = OpLabel
+         %83 = OpFunctionCall %VertexOutput %vertex_main_inner
+         %84 = OpCompositeExtract %v4float %83 0
+               OpStore %vertex_main_position_Output %84 None
+         %85 = OpCompositeExtract %float %83 1
+               OpStore %vertex_main_loc0_Output %85 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.glsl
index 5220dc2..818b04d 100644
--- a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_06794e() {
   f16mat3 arg_0 = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_06794e();
@@ -25,7 +25,7 @@
 int transpose_06794e() {
   f16mat3 arg_0 = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_06794e() {
   f16mat3 arg_0 = f16mat3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.dxc.hlsl
index c78ee5e..3a5f160 100644
--- a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_06794e() {
   matrix<float16_t, 3, 3> arg_0 = matrix<float16_t, 3, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
   matrix<float16_t, 3, 3> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.msl
index 98bd92e..935704c 100644
--- a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_06794e() {
   half3x3 arg_0 = half3x3(half3(1.0h), half3(1.0h), half3(1.0h));
   half3x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.spvasm
index d98eb99..0878f41 100644
--- a/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/06794e.wgsl.expected.spvasm
@@ -61,16 +61,16 @@
          %22 = OpConstantComposite %v3half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat3v3half %22 %22 %22
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -88,21 +88,21 @@
          %24 = OpLoad %mat3v3half %arg_0 None
          %25 = OpTranspose %mat3v3half %24
                OpStore %res %25
-         %27 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %30 = OpAccessChain %_ptr_Function_half %27 %int_0
-         %32 = OpLoad %half %30 None
-         %33 = OpFOrdEqual %bool %32 %half_0x0p_0
-         %36 = OpSelect %int %33 %int_1 %int_0
-               OpReturnValue %36
+         %27 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %31 = OpAccessChain %_ptr_Function_half %27 %uint_0
+         %33 = OpLoad %half %31 None
+         %34 = OpFOrdEqual %bool %33 %half_0x0p_0
+         %37 = OpSelect %int %34 %int_1 %int_0
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %int %transpose_06794e
-         %43 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %int %transpose_06794e
+         %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
+%compute_main = OpFunction %void None %42
          %48 = OpLabel
          %49 = OpFunctionCall %int %transpose_06794e
          %50 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -120,7 +120,7 @@
          %65 = OpLoad %VertexOutput %out None
                OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
+%vertex_main = OpFunction %void None %42
          %67 = OpLabel
          %68 = OpFunctionCall %VertexOutput %vertex_main_inner
          %69 = OpCompositeExtract %v4float %68 0
diff --git a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.glsl
index b9d18df..d8353b9 100644
--- a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_2585cd() {
   mat4x3 arg_0 = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_2585cd();
@@ -23,7 +23,7 @@
 int transpose_2585cd() {
   mat4x3 arg_0 = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_2585cd() {
   mat4x3 arg_0 = mat4x3(vec3(1.0f), vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
index 23492c6..dc8dda1 100644
--- a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_2585cd() {
   float4x3 arg_0 = float4x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
   float3x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
index 23492c6..dc8dda1 100644
--- a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_2585cd() {
   float4x3 arg_0 = float4x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
   float3x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.msl
index 6fc97f3..e694077 100644
--- a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_2585cd() {
   float4x3 arg_0 = float4x3(float3(1.0f), float3(1.0f), float3(1.0f), float3(1.0f));
   float3x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.spvasm
index 2a13ce5..43cbe72 100644
--- a/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/2585cd.wgsl.expected.spvasm
@@ -59,16 +59,16 @@
 %mat3v4float = OpTypeMatrix %v4float 3
 %_ptr_Function_mat3v4float = OpTypePointer Function %mat3v4float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -84,21 +84,21 @@
          %23 = OpLoad %mat4v3float %arg_0 None
          %24 = OpTranspose %mat3v4float %23
                OpStore %res %24
-         %28 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %31 = OpAccessChain %_ptr_Function_float %28 %int_0
-         %33 = OpLoad %float %31 None
-         %34 = OpFOrdEqual %bool %33 %float_0
-         %37 = OpSelect %int %34 %int_1 %int_0
-               OpReturnValue %37
+         %28 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %32 = OpAccessChain %_ptr_Function_float %28 %uint_0
+         %34 = OpLoad %float %32 None
+         %35 = OpFOrdEqual %bool %34 %float_0
+         %38 = OpSelect %int %35 %int_1 %int_0
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %int %transpose_2585cd
-         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %int %transpose_2585cd
+         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %43
          %49 = OpLabel
          %50 = OpFunctionCall %int %transpose_2585cd
          %51 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -116,7 +116,7 @@
          %65 = OpLoad %VertexOutput %out None
                OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main = OpFunction %void None %43
          %67 = OpLabel
          %68 = OpFunctionCall %VertexOutput %vertex_main_inner
          %69 = OpCompositeExtract %v4float %68 0
diff --git a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.glsl
index 13a8890..f16988f 100644
--- a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_31d679() {
   mat2 arg_0 = mat2(vec2(1.0f), vec2(1.0f));
   mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_31d679();
@@ -23,7 +23,7 @@
 int transpose_31d679() {
   mat2 arg_0 = mat2(vec2(1.0f), vec2(1.0f));
   mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_31d679() {
   mat2 arg_0 = mat2(vec2(1.0f), vec2(1.0f));
   mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.dxc.hlsl
index e64b128..8e8e4b9 100644
--- a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_31d679() {
   float2x2 arg_0 = float2x2((1.0f).xx, (1.0f).xx);
   float2x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.fxc.hlsl
index e64b128..8e8e4b9 100644
--- a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_31d679() {
   float2x2 arg_0 = float2x2((1.0f).xx, (1.0f).xx);
   float2x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.msl
index 932a869..42bf101 100644
--- a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_31d679() {
   float2x2 arg_0 = float2x2(float2(1.0f), float2(1.0f));
   float2x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.spvasm
index 6082e74..64fd0c1 100644
--- a/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/31d679.wgsl.expected.spvasm
@@ -57,16 +57,16 @@
          %21 = OpConstantComposite %v2float %float_1 %float_1
          %20 = OpConstantComposite %mat2v2float %21 %21
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %23 = OpLoad %mat2v2float %arg_0 None
          %24 = OpTranspose %mat2v2float %23
                OpStore %res %24
-         %26 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %29 = OpAccessChain %_ptr_Function_float %26 %int_0
-         %31 = OpLoad %float %29 None
-         %32 = OpFOrdEqual %bool %31 %float_0
-         %35 = OpSelect %int %32 %int_1 %int_0
-               OpReturnValue %35
+         %26 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %30 = OpAccessChain %_ptr_Function_float %26 %uint_0
+         %32 = OpLoad %float %30 None
+         %33 = OpFOrdEqual %bool %32 %float_0
+         %36 = OpSelect %int %33 %int_1 %int_0
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %int %transpose_31d679
-         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %int %transpose_31d679
+         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
+%compute_main = OpFunction %void None %41
          %47 = OpLabel
          %48 = OpFunctionCall %int %transpose_31d679
          %49 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %64 = OpLoad %VertexOutput %out None
                OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
+%vertex_main = OpFunction %void None %41
          %66 = OpLabel
          %67 = OpFunctionCall %VertexOutput %vertex_main_inner
          %68 = OpCompositeExtract %v4float %67 0
diff --git a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.glsl
index a5aabd5..4fb6b0d 100644
--- a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_31e37e() {
   mat4x2 arg_0 = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_31e37e();
@@ -23,7 +23,7 @@
 int transpose_31e37e() {
   mat4x2 arg_0 = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_31e37e() {
   mat4x2 arg_0 = mat4x2(vec2(1.0f), vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
index dd06914..cee88b2 100644
--- a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_31e37e() {
   float4x2 arg_0 = float4x2((1.0f).xx, (1.0f).xx, (1.0f).xx, (1.0f).xx);
   float2x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
index dd06914..cee88b2 100644
--- a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_31e37e() {
   float4x2 arg_0 = float4x2((1.0f).xx, (1.0f).xx, (1.0f).xx, (1.0f).xx);
   float2x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.msl
index 70cc9ec..7ddfddc 100644
--- a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_31e37e() {
   float4x2 arg_0 = float4x2(float2(1.0f), float2(1.0f), float2(1.0f), float2(1.0f));
   float2x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.spvasm
index 32de25f..fcd74c7 100644
--- a/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/31e37e.wgsl.expected.spvasm
@@ -59,16 +59,16 @@
 %mat2v4float = OpTypeMatrix %v4float 2
 %_ptr_Function_mat2v4float = OpTypePointer Function %mat2v4float
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -84,21 +84,21 @@
          %23 = OpLoad %mat4v2float %arg_0 None
          %24 = OpTranspose %mat2v4float %23
                OpStore %res %24
-         %28 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %31 = OpAccessChain %_ptr_Function_float %28 %int_0
-         %33 = OpLoad %float %31 None
-         %34 = OpFOrdEqual %bool %33 %float_0
-         %37 = OpSelect %int %34 %int_1 %int_0
-               OpReturnValue %37
+         %28 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %32 = OpAccessChain %_ptr_Function_float %28 %uint_0
+         %34 = OpLoad %float %32 None
+         %35 = OpFOrdEqual %bool %34 %float_0
+         %38 = OpSelect %int %35 %int_1 %int_0
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %int %transpose_31e37e
-         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %int %transpose_31e37e
+         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %43
          %49 = OpLabel
          %50 = OpFunctionCall %int %transpose_31e37e
          %51 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -116,7 +116,7 @@
          %65 = OpLoad %VertexOutput %out None
                OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main = OpFunction %void None %43
          %67 = OpLabel
          %68 = OpFunctionCall %VertexOutput %vertex_main_inner
          %69 = OpCompositeExtract %v4float %68 0
diff --git a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.glsl
index 8a3b76c..1045640 100644
--- a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_4ce359() {
   mat2x4 arg_0 = mat2x4(vec4(1.0f), vec4(1.0f));
   mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_4ce359();
@@ -23,7 +23,7 @@
 int transpose_4ce359() {
   mat2x4 arg_0 = mat2x4(vec4(1.0f), vec4(1.0f));
   mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_4ce359() {
   mat2x4 arg_0 = mat2x4(vec4(1.0f), vec4(1.0f));
   mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
index 52cf187..cdf7e64 100644
--- a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_4ce359() {
   float2x4 arg_0 = float2x4((1.0f).xxxx, (1.0f).xxxx);
   float4x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
index 52cf187..cdf7e64 100644
--- a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_4ce359() {
   float2x4 arg_0 = float2x4((1.0f).xxxx, (1.0f).xxxx);
   float4x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.msl
index 59ee9e1..cc06cec 100644
--- a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_4ce359() {
   float2x4 arg_0 = float2x4(float4(1.0f), float4(1.0f));
   float4x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.spvasm
index d6391ad..fba7d90 100644
--- a/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/4ce359.wgsl.expected.spvasm
@@ -59,16 +59,16 @@
 %mat4v2float = OpTypeMatrix %v2float 4
 %_ptr_Function_mat4v2float = OpTypePointer Function %mat4v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -85,21 +85,21 @@
          %22 = OpLoad %mat2v4float %arg_0 None
          %23 = OpTranspose %mat4v2float %22
                OpStore %res %23
-         %28 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %31 = OpAccessChain %_ptr_Function_float %28 %int_0
-         %33 = OpLoad %float %31 None
-         %34 = OpFOrdEqual %bool %33 %float_0
-         %37 = OpSelect %int %34 %int_1 %int_0
-               OpReturnValue %37
+         %28 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %32 = OpAccessChain %_ptr_Function_float %28 %uint_0
+         %34 = OpLoad %float %32 None
+         %35 = OpFOrdEqual %bool %34 %float_0
+         %38 = OpSelect %int %35 %int_1 %int_0
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %int %transpose_4ce359
-         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %int %transpose_4ce359
+         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %43
          %49 = OpLabel
          %50 = OpFunctionCall %int %transpose_4ce359
          %51 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -117,7 +117,7 @@
          %66 = OpLoad %VertexOutput %out None
                OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main = OpFunction %void None %43
          %68 = OpLabel
          %69 = OpFunctionCall %VertexOutput %vertex_main_inner
          %70 = OpCompositeExtract %v4float %69 0
diff --git a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.glsl
index 6acadb7..401b148 100644
--- a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_4dc9a1() {
   mat2x3 arg_0 = mat2x3(vec3(1.0f), vec3(1.0f));
   mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_4dc9a1();
@@ -23,7 +23,7 @@
 int transpose_4dc9a1() {
   mat2x3 arg_0 = mat2x3(vec3(1.0f), vec3(1.0f));
   mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_4dc9a1() {
   mat2x3 arg_0 = mat2x3(vec3(1.0f), vec3(1.0f));
   mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
index 156a5b9..ff0443c 100644
--- a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_4dc9a1() {
   float2x3 arg_0 = float2x3((1.0f).xxx, (1.0f).xxx);
   float3x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
index 156a5b9..ff0443c 100644
--- a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_4dc9a1() {
   float2x3 arg_0 = float2x3((1.0f).xxx, (1.0f).xxx);
   float3x2 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.msl
index ec2c89f..6f4e86f 100644
--- a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_4dc9a1() {
   float2x3 arg_0 = float2x3(float3(1.0f), float3(1.0f));
   float3x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.spvasm
index f19ca0f..909b568 100644
--- a/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/4dc9a1.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
 %mat3v2float = OpTypeMatrix %v2float 3
 %_ptr_Function_mat3v2float = OpTypePointer Function %mat3v2float
 %_ptr_Function_v2float = OpTypePointer Function %v2float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -86,21 +86,21 @@
          %23 = OpLoad %mat2v3float %arg_0 None
          %24 = OpTranspose %mat3v2float %23
                OpStore %res %24
-         %29 = OpAccessChain %_ptr_Function_v2float %res %int_0
-         %32 = OpAccessChain %_ptr_Function_float %29 %int_0
-         %34 = OpLoad %float %32 None
-         %35 = OpFOrdEqual %bool %34 %float_0
-         %38 = OpSelect %int %35 %int_1 %int_0
-               OpReturnValue %38
+         %29 = OpAccessChain %_ptr_Function_v2float %res %uint_0
+         %33 = OpAccessChain %_ptr_Function_float %29 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpFOrdEqual %bool %35 %float_0
+         %39 = OpSelect %int %36 %int_1 %int_0
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %int %transpose_4dc9a1
-         %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %int %transpose_4dc9a1
+         %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
+%compute_main = OpFunction %void None %44
          %50 = OpLabel
          %51 = OpFunctionCall %int %transpose_4dc9a1
          %52 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -118,7 +118,7 @@
          %67 = OpLoad %VertexOutput %out None
                OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
+%vertex_main = OpFunction %void None %44
          %69 = OpLabel
          %70 = OpFunctionCall %VertexOutput %vertex_main_inner
          %71 = OpCompositeExtract %v4float %70 0
diff --git a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.glsl
index daa9162..c69d697 100644
--- a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_5edd96() {
   f16mat4x2 arg_0 = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_5edd96();
@@ -25,7 +25,7 @@
 int transpose_5edd96() {
   f16mat4x2 arg_0 = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_5edd96() {
   f16mat4x2 arg_0 = f16mat4x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
index 4a0c5e3..5956421 100644
--- a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_5edd96() {
   matrix<float16_t, 4, 2> arg_0 = matrix<float16_t, 4, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
   matrix<float16_t, 2, 4> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.msl
index 60b115f..5b1a827 100644
--- a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_5edd96() {
   half4x2 arg_0 = half4x2(half2(1.0h), half2(1.0h), half2(1.0h), half2(1.0h));
   half2x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.spvasm
index cd7f217..060f3fe 100644
--- a/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/5edd96.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat2v4half = OpTypeMatrix %v4half 2
 %_ptr_Function_mat2v4half = OpTypePointer Function %mat2v4half
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat4v2half %arg_0 None
          %25 = OpTranspose %mat2v4half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_5edd96
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_5edd96
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_5edd96
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.glsl
index 5d5806f..c5a1550 100644
--- a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_5f36bf() {
   f16mat4x3 arg_0 = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_5f36bf();
@@ -25,7 +25,7 @@
 int transpose_5f36bf() {
   f16mat4x3 arg_0 = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_5f36bf() {
   f16mat4x3 arg_0 = f16mat4x3(f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
index e8cc6f9..c6b8b63 100644
--- a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_5f36bf() {
   matrix<float16_t, 4, 3> arg_0 = matrix<float16_t, 4, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
   matrix<float16_t, 3, 4> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.msl
index c4caec4b..bd30f54 100644
--- a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_5f36bf() {
   half4x3 arg_0 = half4x3(half3(1.0h), half3(1.0h), half3(1.0h), half3(1.0h));
   half3x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.spvasm
index c79e5a0..f7ad357 100644
--- a/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/5f36bf.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat3v4half = OpTypeMatrix %v4half 3
 %_ptr_Function_mat3v4half = OpTypePointer Function %mat3v4half
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat4v3half %arg_0 None
          %25 = OpTranspose %mat3v4half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_5f36bf
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_5f36bf
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_5f36bf
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.glsl
index 9dfdc44..3cbb339 100644
--- a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_7be8b2() {
   f16mat2 arg_0 = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_7be8b2();
@@ -25,7 +25,7 @@
 int transpose_7be8b2() {
   f16mat2 arg_0 = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_7be8b2() {
   f16mat2 arg_0 = f16mat2(f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
index a44610b..59b26d1 100644
--- a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_7be8b2() {
   matrix<float16_t, 2, 2> arg_0 = matrix<float16_t, 2, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
   matrix<float16_t, 2, 2> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.msl
index fbed703..fbf6548 100644
--- a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_7be8b2() {
   half2x2 arg_0 = half2x2(half2(1.0h), half2(1.0h));
   half2x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.spvasm
index f6c547c..6859835 100644
--- a/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/7be8b2.wgsl.expected.spvasm
@@ -61,16 +61,16 @@
          %22 = OpConstantComposite %v2half %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat2v2half %22 %22
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -88,21 +88,21 @@
          %24 = OpLoad %mat2v2half %arg_0 None
          %25 = OpTranspose %mat2v2half %24
                OpStore %res %25
-         %27 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %30 = OpAccessChain %_ptr_Function_half %27 %int_0
-         %32 = OpLoad %half %30 None
-         %33 = OpFOrdEqual %bool %32 %half_0x0p_0
-         %36 = OpSelect %int %33 %int_1 %int_0
-               OpReturnValue %36
+         %27 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %31 = OpAccessChain %_ptr_Function_half %27 %uint_0
+         %33 = OpLoad %half %31 None
+         %34 = OpFOrdEqual %bool %33 %half_0x0p_0
+         %37 = OpSelect %int %34 %int_1 %int_0
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %int %transpose_7be8b2
-         %43 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %int %transpose_7be8b2
+         %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
+%compute_main = OpFunction %void None %42
          %48 = OpLabel
          %49 = OpFunctionCall %int %transpose_7be8b2
          %50 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -120,7 +120,7 @@
          %65 = OpLoad %VertexOutput %out None
                OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
+%vertex_main = OpFunction %void None %42
          %67 = OpLabel
          %68 = OpFunctionCall %VertexOutput %vertex_main_inner
          %69 = OpCompositeExtract %v4float %68 0
diff --git a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.glsl
index 303c56b..117a2fa 100644
--- a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_844869() {
   f16mat4 arg_0 = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_844869();
@@ -25,7 +25,7 @@
 int transpose_844869() {
   f16mat4 arg_0 = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_844869() {
   f16mat4 arg_0 = f16mat4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.dxc.hlsl
index 4a58f96..fc35522 100644
--- a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_844869() {
   matrix<float16_t, 4, 4> arg_0 = matrix<float16_t, 4, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
   matrix<float16_t, 4, 4> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.msl
index 8ec562a..20ce28c 100644
--- a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_844869() {
   half4x4 arg_0 = half4x4(half4(1.0h), half4(1.0h), half4(1.0h), half4(1.0h));
   half4x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.spvasm
index 5b0e062..2eb8444 100644
--- a/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/844869.wgsl.expected.spvasm
@@ -61,16 +61,16 @@
          %22 = OpConstantComposite %v4half %half_0x1p_0 %half_0x1p_0 %half_0x1p_0 %half_0x1p_0
          %21 = OpConstantComposite %mat4v4half %22 %22 %22 %22
 %_ptr_Function_v4half = OpTypePointer Function %v4half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %40 = OpTypeFunction %void
+         %42 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %53 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -88,21 +88,21 @@
          %24 = OpLoad %mat4v4half %arg_0 None
          %25 = OpTranspose %mat4v4half %24
                OpStore %res %25
-         %27 = OpAccessChain %_ptr_Function_v4half %res %int_0
-         %30 = OpAccessChain %_ptr_Function_half %27 %int_0
-         %32 = OpLoad %half %30 None
-         %33 = OpFOrdEqual %bool %32 %half_0x0p_0
-         %36 = OpSelect %int %33 %int_1 %int_0
-               OpReturnValue %36
+         %27 = OpAccessChain %_ptr_Function_v4half %res %uint_0
+         %31 = OpAccessChain %_ptr_Function_half %27 %uint_0
+         %33 = OpLoad %half %31 None
+         %34 = OpFOrdEqual %bool %33 %half_0x0p_0
+         %37 = OpSelect %int %34 %int_1 %int_0
+               OpReturnValue %37
                OpFunctionEnd
-%fragment_main = OpFunction %void None %40
-         %41 = OpLabel
-         %42 = OpFunctionCall %int %transpose_844869
-         %43 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %43 %42 None
+%fragment_main = OpFunction %void None %42
+         %43 = OpLabel
+         %44 = OpFunctionCall %int %transpose_844869
+         %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %45 %44 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %40
+%compute_main = OpFunction %void None %42
          %48 = OpLabel
          %49 = OpFunctionCall %int %transpose_844869
          %50 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -120,7 +120,7 @@
          %65 = OpLoad %VertexOutput %out None
                OpReturnValue %65
                OpFunctionEnd
-%vertex_main = OpFunction %void None %40
+%vertex_main = OpFunction %void None %42
          %67 = OpLabel
          %68 = OpFunctionCall %VertexOutput %vertex_main_inner
          %69 = OpCompositeExtract %v4float %68 0
diff --git a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.glsl
index 5f096a8..600f4fd 100644
--- a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_854336() {
   mat3 arg_0 = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_854336();
@@ -23,7 +23,7 @@
 int transpose_854336() {
   mat3 arg_0 = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_854336() {
   mat3 arg_0 = mat3(vec3(1.0f), vec3(1.0f), vec3(1.0f));
   mat3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.dxc.hlsl
index 05ca32f..ab4cfbe 100644
--- a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_854336() {
   float3x3 arg_0 = float3x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
   float3x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.fxc.hlsl
index 05ca32f..ab4cfbe 100644
--- a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_854336() {
   float3x3 arg_0 = float3x3((1.0f).xxx, (1.0f).xxx, (1.0f).xxx);
   float3x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.msl
index 016b6ec..ce15126 100644
--- a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_854336() {
   float3x3 arg_0 = float3x3(float3(1.0f), float3(1.0f), float3(1.0f));
   float3x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.spvasm
index c7021ca..77bb14b 100644
--- a/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/854336.wgsl.expected.spvasm
@@ -57,16 +57,16 @@
          %21 = OpConstantComposite %v3float %float_1 %float_1 %float_1
          %20 = OpConstantComposite %mat3v3float %21 %21 %21
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %39 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %52 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -83,21 +83,21 @@
          %23 = OpLoad %mat3v3float %arg_0 None
          %24 = OpTranspose %mat3v3float %23
                OpStore %res %24
-         %26 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %29 = OpAccessChain %_ptr_Function_float %26 %int_0
-         %31 = OpLoad %float %29 None
-         %32 = OpFOrdEqual %bool %31 %float_0
-         %35 = OpSelect %int %32 %int_1 %int_0
-               OpReturnValue %35
+         %26 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %30 = OpAccessChain %_ptr_Function_float %26 %uint_0
+         %32 = OpLoad %float %30 None
+         %33 = OpFOrdEqual %bool %32 %float_0
+         %36 = OpSelect %int %33 %int_1 %int_0
+               OpReturnValue %36
                OpFunctionEnd
-%fragment_main = OpFunction %void None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %int %transpose_854336
-         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %42 %41 None
+%fragment_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpFunctionCall %int %transpose_854336
+         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %44 %43 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %39
+%compute_main = OpFunction %void None %41
          %47 = OpLabel
          %48 = OpFunctionCall %int %transpose_854336
          %49 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -115,7 +115,7 @@
          %64 = OpLoad %VertexOutput %out None
                OpReturnValue %64
                OpFunctionEnd
-%vertex_main = OpFunction %void None %39
+%vertex_main = OpFunction %void None %41
          %66 = OpLabel
          %67 = OpFunctionCall %VertexOutput %vertex_main_inner
          %68 = OpCompositeExtract %v4float %67 0
diff --git a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.glsl
index cec6ced..5c1a073 100644
--- a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_8c06ce() {
   f16mat3x4 arg_0 = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_8c06ce();
@@ -25,7 +25,7 @@
 int transpose_8c06ce() {
   f16mat3x4 arg_0 = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_8c06ce() {
   f16mat3x4 arg_0 = f16mat3x4(f16vec4(1.0hf), f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
index 4f7404d..5b44a3b 100644
--- a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_8c06ce() {
   matrix<float16_t, 3, 4> arg_0 = matrix<float16_t, 3, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
   matrix<float16_t, 4, 3> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.msl
index 4b8a99e..b2c5e50 100644
--- a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_8c06ce() {
   half3x4 arg_0 = half3x4(half4(1.0h), half4(1.0h), half4(1.0h));
   half4x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.spvasm
index c23f231..a204260 100644
--- a/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/8c06ce.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat4v3half = OpTypeMatrix %v3half 4
 %_ptr_Function_mat4v3half = OpTypePointer Function %mat4v3half
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat3v4half %arg_0 None
          %25 = OpTranspose %mat4v3half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_8c06ce
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_8c06ce
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_8c06ce
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.glsl
index 5482381..f28f7ff 100644
--- a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_b9ad1f() {
   f16mat3x2 arg_0 = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_b9ad1f();
@@ -25,7 +25,7 @@
 int transpose_b9ad1f() {
   f16mat3x2 arg_0 = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_b9ad1f() {
   f16mat3x2 arg_0 = f16mat3x2(f16vec2(1.0hf), f16vec2(1.0hf), f16vec2(1.0hf));
   f16mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
index 2407e6c..04523e0 100644
--- a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_b9ad1f() {
   matrix<float16_t, 3, 2> arg_0 = matrix<float16_t, 3, 2>((float16_t(1.0h)).xx, (float16_t(1.0h)).xx, (float16_t(1.0h)).xx);
   matrix<float16_t, 2, 3> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.msl
index 29ec46c..1d9c569 100644
--- a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_b9ad1f() {
   half3x2 arg_0 = half3x2(half2(1.0h), half2(1.0h), half2(1.0h));
   half2x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.spvasm
index e07ce3e..3a1270c 100644
--- a/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/b9ad1f.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat2v3half = OpTypeMatrix %v3half 2
 %_ptr_Function_mat2v3half = OpTypePointer Function %mat2v3half
 %_ptr_Function_v3half = OpTypePointer Function %v3half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat3v2half %arg_0 None
          %25 = OpTranspose %mat2v3half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v3half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v3half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_b9ad1f
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_b9ad1f
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_b9ad1f
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.glsl
index 8d0b667..71b146c 100644
--- a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_c1b600() {
   mat4 arg_0 = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_c1b600();
@@ -23,7 +23,7 @@
 int transpose_c1b600() {
   mat4 arg_0 = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_c1b600() {
   mat4 arg_0 = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
index 064304f..6374a0d 100644
--- a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_c1b600() {
   float4x4 arg_0 = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
   float4x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
index 064304f..6374a0d 100644
--- a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_c1b600() {
   float4x4 arg_0 = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
   float4x4 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.msl
index a9462d1..d90b1e2 100644
--- a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_c1b600() {
   float4x4 arg_0 = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f));
   float4x4 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.spvasm
index bd0017e..0ee5a37 100644
--- a/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/c1b600.wgsl.expected.spvasm
@@ -56,16 +56,16 @@
          %20 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
          %19 = OpConstantComposite %mat4v4float %20 %20 %20 %20
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %40 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %51 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -81,21 +81,21 @@
          %22 = OpLoad %mat4v4float %arg_0 None
          %23 = OpTranspose %mat4v4float %22
                OpStore %res %23
-         %25 = OpAccessChain %_ptr_Function_v4float %res %int_0
-         %28 = OpAccessChain %_ptr_Function_float %25 %int_0
-         %30 = OpLoad %float %28 None
-         %31 = OpFOrdEqual %bool %30 %float_0
-         %34 = OpSelect %int %31 %int_1 %int_0
-               OpReturnValue %34
+         %25 = OpAccessChain %_ptr_Function_v4float %res %uint_0
+         %29 = OpAccessChain %_ptr_Function_float %25 %uint_0
+         %31 = OpLoad %float %29 None
+         %32 = OpFOrdEqual %bool %31 %float_0
+         %35 = OpSelect %int %32 %int_1 %int_0
+               OpReturnValue %35
                OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpFunctionCall %int %transpose_c1b600
-         %41 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %41 %40 None
+%fragment_main = OpFunction %void None %40
+         %41 = OpLabel
+         %42 = OpFunctionCall %int %transpose_c1b600
+         %43 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %43 %42 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %38
+%compute_main = OpFunction %void None %40
          %46 = OpLabel
          %47 = OpFunctionCall %int %transpose_c1b600
          %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -113,7 +113,7 @@
          %62 = OpLoad %VertexOutput %out None
                OpReturnValue %62
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
+%vertex_main = OpFunction %void None %40
          %64 = OpLabel
          %65 = OpFunctionCall %VertexOutput %vertex_main_inner
          %66 = OpCompositeExtract %v4float %65 0
diff --git a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.glsl
index 6170dbb..45a7e84 100644
--- a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_d6faec() {
   f16mat2x3 arg_0 = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_d6faec();
@@ -25,7 +25,7 @@
 int transpose_d6faec() {
   f16mat2x3 arg_0 = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_d6faec() {
   f16mat2x3 arg_0 = f16mat2x3(f16vec3(1.0hf), f16vec3(1.0hf));
   f16mat3x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
index 6e2e048..a038348 100644
--- a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_d6faec() {
   matrix<float16_t, 2, 3> arg_0 = matrix<float16_t, 2, 3>((float16_t(1.0h)).xxx, (float16_t(1.0h)).xxx);
   matrix<float16_t, 3, 2> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.msl
index d566d30..c9c2686 100644
--- a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_d6faec() {
   half2x3 arg_0 = half2x3(half3(1.0h), half3(1.0h));
   half3x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.spvasm
index 6e89367..5cb0dbf 100644
--- a/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/d6faec.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat3v2half = OpTypeMatrix %v2half 3
 %_ptr_Function_mat3v2half = OpTypePointer Function %mat3v2half
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat2v3half %arg_0 None
          %25 = OpTranspose %mat3v2half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_d6faec
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_d6faec
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_d6faec
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.glsl
index 7948fb9..dab3a45 100644
--- a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_d8f8ba() {
   mat3x4 arg_0 = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_d8f8ba();
@@ -23,7 +23,7 @@
 int transpose_d8f8ba() {
   mat3x4 arg_0 = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_d8f8ba() {
   mat3x4 arg_0 = mat3x4(vec4(1.0f), vec4(1.0f), vec4(1.0f));
   mat4x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
index c7cd0bf..83df40b 100644
--- a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_d8f8ba() {
   float3x4 arg_0 = float3x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
   float4x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
index c7cd0bf..83df40b 100644
--- a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_d8f8ba() {
   float3x4 arg_0 = float3x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
   float4x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.msl
index a955560..a69df64 100644
--- a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_d8f8ba() {
   float3x4 arg_0 = float3x4(float4(1.0f), float4(1.0f), float4(1.0f));
   float4x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.spvasm
index 3c5d2cf..991ac23 100644
--- a/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/d8f8ba.wgsl.expected.spvasm
@@ -59,16 +59,16 @@
 %mat4v3float = OpTypeMatrix %v3float 4
 %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %41 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %54 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -85,21 +85,21 @@
          %22 = OpLoad %mat3v4float %arg_0 None
          %23 = OpTranspose %mat4v3float %22
                OpStore %res %23
-         %28 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %31 = OpAccessChain %_ptr_Function_float %28 %int_0
-         %33 = OpLoad %float %31 None
-         %34 = OpFOrdEqual %bool %33 %float_0
-         %37 = OpSelect %int %34 %int_1 %int_0
-               OpReturnValue %37
+         %28 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %32 = OpAccessChain %_ptr_Function_float %28 %uint_0
+         %34 = OpLoad %float %32 None
+         %35 = OpFOrdEqual %bool %34 %float_0
+         %38 = OpSelect %int %35 %int_1 %int_0
+               OpReturnValue %38
                OpFunctionEnd
-%fragment_main = OpFunction %void None %41
-         %42 = OpLabel
-         %43 = OpFunctionCall %int %transpose_d8f8ba
-         %44 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %44 %43 None
+%fragment_main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpFunctionCall %int %transpose_d8f8ba
+         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %46 %45 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %41
+%compute_main = OpFunction %void None %43
          %49 = OpLabel
          %50 = OpFunctionCall %int %transpose_d8f8ba
          %51 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -117,7 +117,7 @@
          %66 = OpLoad %VertexOutput %out None
                OpReturnValue %66
                OpFunctionEnd
-%vertex_main = OpFunction %void None %41
+%vertex_main = OpFunction %void None %43
          %68 = OpLabel
          %69 = OpFunctionCall %VertexOutput %vertex_main_inner
          %70 = OpCompositeExtract %v4float %69 0
diff --git a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.glsl
index c830620..fdf5c79 100644
--- a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.glsl
@@ -9,7 +9,7 @@
 int transpose_ed4bdc() {
   mat3x2 arg_0 = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 void main() {
   v.inner = transpose_ed4bdc();
@@ -23,7 +23,7 @@
 int transpose_ed4bdc() {
   mat3x2 arg_0 = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -41,7 +41,7 @@
 int transpose_ed4bdc() {
   mat3x2 arg_0 = mat3x2(vec2(1.0f), vec2(1.0f), vec2(1.0f));
   mat2x3 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0f));
+  return mix(0, 1, (res[0u].x == 0.0f));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
index d285526..33dbd7c 100644
--- a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_ed4bdc() {
   float3x2 arg_0 = float3x2((1.0f).xx, (1.0f).xx, (1.0f).xx);
   float2x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
index d285526..33dbd7c 100644
--- a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_ed4bdc() {
   float3x2 arg_0 = float3x2((1.0f).xx, (1.0f).xx, (1.0f).xx);
   float2x3 res = transpose(arg_0);
-  return (((res[int(0)].x == 0.0f)) ? (int(1)) : (int(0)));
+  return (((res[0u].x == 0.0f)) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.msl
index 40bd7e0..85e10de 100644
--- a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_ed4bdc() {
   float3x2 arg_0 = float3x2(float2(1.0f), float2(1.0f), float2(1.0f));
   float2x3 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0f));
+  return select(0, 1, (res[0u][0u] == 0.0f));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.spvasm
index 816a046..b814339 100644
--- a/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/ed4bdc.wgsl.expected.spvasm
@@ -60,16 +60,16 @@
 %mat2v3float = OpTypeMatrix %v3float 2
 %_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %42 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %55 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -86,21 +86,21 @@
          %23 = OpLoad %mat3v2float %arg_0 None
          %24 = OpTranspose %mat2v3float %23
                OpStore %res %24
-         %29 = OpAccessChain %_ptr_Function_v3float %res %int_0
-         %32 = OpAccessChain %_ptr_Function_float %29 %int_0
-         %34 = OpLoad %float %32 None
-         %35 = OpFOrdEqual %bool %34 %float_0
-         %38 = OpSelect %int %35 %int_1 %int_0
-               OpReturnValue %38
+         %29 = OpAccessChain %_ptr_Function_v3float %res %uint_0
+         %33 = OpAccessChain %_ptr_Function_float %29 %uint_0
+         %35 = OpLoad %float %33 None
+         %36 = OpFOrdEqual %bool %35 %float_0
+         %39 = OpSelect %int %36 %int_1 %int_0
+               OpReturnValue %39
                OpFunctionEnd
-%fragment_main = OpFunction %void None %42
-         %43 = OpLabel
-         %44 = OpFunctionCall %int %transpose_ed4bdc
-         %45 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %45 %44 None
+%fragment_main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %int %transpose_ed4bdc
+         %47 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %47 %46 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %42
+%compute_main = OpFunction %void None %44
          %50 = OpLabel
          %51 = OpFunctionCall %int %transpose_ed4bdc
          %52 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -118,7 +118,7 @@
          %67 = OpLoad %VertexOutput %out None
                OpReturnValue %67
                OpFunctionEnd
-%vertex_main = OpFunction %void None %42
+%vertex_main = OpFunction %void None %44
          %69 = OpLabel
          %70 = OpFunctionCall %VertexOutput %vertex_main_inner
          %71 = OpCompositeExtract %v4float %70 0
diff --git a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.glsl b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.glsl
index 7e53e8c..9bee850 100644
--- a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.glsl
@@ -10,7 +10,7 @@
 int transpose_faeb05() {
   f16mat2x4 arg_0 = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 void main() {
   v.inner = transpose_faeb05();
@@ -25,7 +25,7 @@
 int transpose_faeb05() {
   f16mat2x4 arg_0 = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
@@ -44,7 +44,7 @@
 int transpose_faeb05() {
   f16mat2x4 arg_0 = f16mat2x4(f16vec4(1.0hf), f16vec4(1.0hf));
   f16mat4x2 res = transpose(arg_0);
-  return mix(0, 1, (res[0].x == 0.0hf));
+  return mix(0, 1, (res[0u].x == 0.0hf));
 }
 VertexOutput vertex_main_inner() {
   VertexOutput tint_symbol = VertexOutput(vec4(0.0f), 0);
diff --git a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
index d8ff398..5c18323 100644
--- a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 int transpose_faeb05() {
   matrix<float16_t, 2, 4> arg_0 = matrix<float16_t, 2, 4>((float16_t(1.0h)).xxxx, (float16_t(1.0h)).xxxx);
   matrix<float16_t, 4, 2> res = transpose(arg_0);
-  return (((res[int(0)].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
+  return (((res[0u].x == float16_t(0.0h))) ? (int(1)) : (int(0)));
 }
 
 void fragment_main() {
diff --git a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.msl b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.msl
index e7c8384..714c392 100644
--- a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.msl
+++ b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
 int transpose_faeb05() {
   half2x4 arg_0 = half2x4(half4(1.0h), half4(1.0h));
   half4x2 res = transpose(arg_0);
-  return select(0, 1, (res[0][0] == 0.0h));
+  return select(0, 1, (res[0u][0u] == 0.0h));
 }
 
 fragment void fragment_main(device int* prevent_dce [[buffer(0)]]) {
diff --git a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.spvasm b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.spvasm
index 7924e50..19b4470 100644
--- a/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/transpose/faeb05.wgsl.expected.spvasm
@@ -64,16 +64,16 @@
  %mat4v2half = OpTypeMatrix %v2half 4
 %_ptr_Function_mat4v2half = OpTypePointer Function %mat4v2half
 %_ptr_Function_v2half = OpTypePointer Function %v2half
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Function_half = OpTypePointer Function %half
 %half_0x0p_0 = OpConstant %half 0x0p+0
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
+      %int_0 = OpConstant %int 0
        %void = OpTypeVoid
-         %43 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
 %VertexOutput = OpTypeStruct %v4float %int
          %56 = OpTypeFunction %VertexOutput
 %_ptr_Function_VertexOutput = OpTypePointer Function %VertexOutput
@@ -91,21 +91,21 @@
          %24 = OpLoad %mat2v4half %arg_0 None
          %25 = OpTranspose %mat4v2half %24
                OpStore %res %25
-         %30 = OpAccessChain %_ptr_Function_v2half %res %int_0
-         %33 = OpAccessChain %_ptr_Function_half %30 %int_0
-         %35 = OpLoad %half %33 None
-         %36 = OpFOrdEqual %bool %35 %half_0x0p_0
-         %39 = OpSelect %int %36 %int_1 %int_0
-               OpReturnValue %39
+         %30 = OpAccessChain %_ptr_Function_v2half %res %uint_0
+         %34 = OpAccessChain %_ptr_Function_half %30 %uint_0
+         %36 = OpLoad %half %34 None
+         %37 = OpFOrdEqual %bool %36 %half_0x0p_0
+         %40 = OpSelect %int %37 %int_1 %int_0
+               OpReturnValue %40
                OpFunctionEnd
-%fragment_main = OpFunction %void None %43
-         %44 = OpLabel
-         %45 = OpFunctionCall %int %transpose_faeb05
-         %46 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
-               OpStore %46 %45 None
+%fragment_main = OpFunction %void None %45
+         %46 = OpLabel
+         %47 = OpFunctionCall %int %transpose_faeb05
+         %48 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
+               OpStore %48 %47 None
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %43
+%compute_main = OpFunction %void None %45
          %51 = OpLabel
          %52 = OpFunctionCall %int %transpose_faeb05
          %53 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0
@@ -123,7 +123,7 @@
          %68 = OpLoad %VertexOutput %out None
                OpReturnValue %68
                OpFunctionEnd
-%vertex_main = OpFunction %void None %43
+%vertex_main = OpFunction %void None %45
          %70 = OpLabel
          %71 = OpFunctionCall %VertexOutput %vertex_main_inner
          %72 = OpCompositeExtract %v4float %71 0
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.glsl b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.glsl
index ce0034d..aaa3f2f 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.glsl
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.glsl
@@ -9,8 +9,9 @@
 uniform highp sampler2DMS arg_0;
 void textureLoad_6273b1() {
   float res = 0.0f;
-  ivec2 v = ivec2(ivec2(0));
-  res = vec4(texelFetch(arg_0, v, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(0)), v));
+  res = vec4(texelFetch(arg_0, v_1, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
 }
 void tint_symbol_2(vec4 tint_symbol) {
   tint_symbol_1 = tint_symbol;
@@ -36,8 +37,9 @@
 uniform highp sampler2DMS arg_0;
 void textureLoad_6273b1() {
   float res = 0.0f;
-  ivec2 v = ivec2(ivec2(0));
-  res = vec4(texelFetch(arg_0, v, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(0)), v));
+  res = vec4(texelFetch(arg_0, v_1, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
 }
 void fragment_main_1() {
   textureLoad_6273b1();
@@ -50,8 +52,9 @@
 uniform highp sampler2DMS arg_0;
 void textureLoad_6273b1() {
   float res = 0.0f;
-  ivec2 v = ivec2(ivec2(0));
-  res = vec4(texelFetch(arg_0, v, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
+  uvec2 v = (uvec2(textureSize(arg_0)) - uvec2(1u));
+  ivec2 v_1 = ivec2(min(uvec2(ivec2(0)), v));
+  res = vec4(texelFetch(arg_0, v_1, int(1)).x, 0.0f, 0.0f, 0.0f)[0u];
 }
 void compute_main_1() {
   textureLoad_6273b1();
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.dxc.hlsl b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.dxc.hlsl
index 70c2e86..1e02687 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.dxc.hlsl
@@ -11,8 +11,11 @@
 static float4 tint_symbol_1 = (0.0f).xxxx;
 void textureLoad_6273b1() {
   float res = 0.0f;
-  int2 v = int2((int(0)).xx);
-  res = float4(arg_0.Load(v, int(int(1))).x, 0.0f, 0.0f, 0.0f).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(0)).xx), v_1));
+  res = float4(arg_0.Load(v_2, int(int(1))).x, 0.0f, 0.0f, 0.0f).x;
 }
 
 void tint_symbol_2(float4 tint_symbol) {
@@ -26,8 +29,8 @@
 
 vertex_main_out vertex_main_inner() {
   vertex_main_1();
-  vertex_main_out v_1 = {tint_symbol_1};
-  return v_1;
+  vertex_main_out v_3 = {tint_symbol_1};
+  return v_3;
 }
 
 void fragment_main_1() {
@@ -48,8 +51,8 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_out v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.tint_symbol_1_1};
-  return v_3;
+  vertex_main_out v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.tint_symbol_1_1};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.fxc.hlsl b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.fxc.hlsl
index 70c2e86..1e02687 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.fxc.hlsl
@@ -11,8 +11,11 @@
 static float4 tint_symbol_1 = (0.0f).xxxx;
 void textureLoad_6273b1() {
   float res = 0.0f;
-  int2 v = int2((int(0)).xx);
-  res = float4(arg_0.Load(v, int(int(1))).x, 0.0f, 0.0f, 0.0f).x;
+  uint3 v = (0u).xxx;
+  arg_0.GetDimensions(v.x, v.y, v.z);
+  uint2 v_1 = (v.xy - (1u).xx);
+  int2 v_2 = int2(min(uint2((int(0)).xx), v_1));
+  res = float4(arg_0.Load(v_2, int(int(1))).x, 0.0f, 0.0f, 0.0f).x;
 }
 
 void tint_symbol_2(float4 tint_symbol) {
@@ -26,8 +29,8 @@
 
 vertex_main_out vertex_main_inner() {
   vertex_main_1();
-  vertex_main_out v_1 = {tint_symbol_1};
-  return v_1;
+  vertex_main_out v_3 = {tint_symbol_1};
+  return v_3;
 }
 
 void fragment_main_1() {
@@ -48,8 +51,8 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_out v_2 = vertex_main_inner();
-  vertex_main_outputs v_3 = {v_2.tint_symbol_1_1};
-  return v_3;
+  vertex_main_out v_4 = vertex_main_inner();
+  vertex_main_outputs v_5 = {v_4.tint_symbol_1_1};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.msl b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.msl
index 04c2fd4..399346e 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.msl
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.ir.msl
@@ -16,7 +16,8 @@
 
 void textureLoad_6273b1(tint_module_vars_struct tint_module_vars) {
   float res = 0.0f;
-  res = float4(tint_module_vars.arg_0.read(uint2(int2(0)), 1), 0.0f, 0.0f, 0.0f)[0u];
+  uint2 const v = (uint2(tint_module_vars.arg_0.get_width(), tint_module_vars.arg_0.get_height()) - uint2(1u));
+  res = float4(tint_module_vars.arg_0.read(min(uint2(int2(0)), v), 1), 0.0f, 0.0f, 0.0f)[0u];
 }
 
 void tint_symbol_2(float4 tint_symbol, tint_module_vars_struct tint_module_vars) {
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.msl b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.msl
index 6644784..af24c80 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.msl
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.msl
@@ -5,9 +5,13 @@
   float4 tint_symbol_1;
 };
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 void textureLoad_6273b1(depth2d_ms<float, access::read> tint_symbol_5) {
   float res = 0.0f;
-  res = float4(tint_symbol_5.read(uint2(int2(0)), 1), 0.0f, 0.0f, 0.0f)[0];
+  res = float4(tint_symbol_5.read(uint2(tint_clamp(int2(0), int2(0), int2((uint2(tint_symbol_5.get_width(), tint_symbol_5.get_height()) - uint2(1u))))), 1), 0.0f, 0.0f, 0.0f)[0];
   return;
 }
 
diff --git a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.spvasm b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.spvasm
index d0230c1..d98e03c 100644
--- a/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.spvasm
+++ b/test/tint/builtins/textureLoad/depth_ms.spvasm.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 61
+; Bound: 70
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -48,70 +50,78 @@
          %15 = OpTypeFunction %void
 %_ptr_Function_float = OpTypePointer Function %float
     %float_0 = OpConstant %float 0
+       %uint = OpTypeInt 32 0
+     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
+         %25 = OpConstantComposite %v2uint %uint_1 %uint_1
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
-         %22 = OpConstantNull %v2int
+         %28 = OpConstantNull %v2int
       %int_1 = OpConstant %int 1
-         %31 = OpTypeFunction %void %v4float
+         %40 = OpTypeFunction %void %v4float
 %vertex_main_out = OpTypeStruct %v4float
-         %39 = OpTypeFunction %vertex_main_out
+         %48 = OpTypeFunction %vertex_main_out
     %float_1 = OpConstant %float 1
 %textureLoad_6273b1 = OpFunction %void None %15
          %16 = OpLabel
         %res = OpVariable %_ptr_Function_float Function
                OpStore %res %float_0
          %20 = OpLoad %3 %arg_0 None
-         %21 = OpImageFetch %v4float %20 %22 Sample %int_1
-         %26 = OpCompositeExtract %float %21 0
-         %27 = OpCompositeConstruct %v4float %26 %float_0 %float_0 %float_0
-         %28 = OpCompositeExtract %float %27 0
-               OpStore %res %28 None
+         %21 = OpImageQuerySize %v2uint %20
+         %24 = OpISub %v2uint %21 %25
+         %27 = OpBitcast %v2uint %28
+         %31 = OpExtInst %v2uint %32 UMin %27 %24
+         %33 = OpImageFetch %v4float %20 %31 Sample %int_1
+         %35 = OpCompositeExtract %float %33 0
+         %36 = OpCompositeConstruct %v4float %35 %float_0 %float_0 %float_0
+         %37 = OpCompositeExtract %float %36 0
+               OpStore %res %37 None
                OpReturn
                OpFunctionEnd
-%tint_symbol_2 = OpFunction %void None %31
+%tint_symbol_2 = OpFunction %void None %40
 %tint_symbol = OpFunctionParameter %v4float
-         %32 = OpLabel
+         %41 = OpLabel
                OpStore %tint_symbol_1 %tint_symbol None
                OpReturn
                OpFunctionEnd
 %vertex_main_1 = OpFunction %void None %15
-         %34 = OpLabel
-         %35 = OpFunctionCall %void %textureLoad_6273b1
-         %36 = OpFunctionCall %void %tint_symbol_2 %8
+         %43 = OpLabel
+         %44 = OpFunctionCall %void %textureLoad_6273b1
+         %45 = OpFunctionCall %void %tint_symbol_2 %8
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %vertex_main_out None %39
-         %40 = OpLabel
-         %41 = OpFunctionCall %void %vertex_main_1
-         %42 = OpLoad %v4float %tint_symbol_1 None
-         %43 = OpCompositeConstruct %vertex_main_out %42
-               OpReturnValue %43
+%vertex_main_inner = OpFunction %vertex_main_out None %48
+         %49 = OpLabel
+         %50 = OpFunctionCall %void %vertex_main_1
+         %51 = OpLoad %v4float %tint_symbol_1 None
+         %52 = OpCompositeConstruct %vertex_main_out %51
+               OpReturnValue %52
                OpFunctionEnd
 %fragment_main_1 = OpFunction %void None %15
-         %45 = OpLabel
-         %46 = OpFunctionCall %void %textureLoad_6273b1
+         %54 = OpLabel
+         %55 = OpFunctionCall %void %textureLoad_6273b1
                OpReturn
                OpFunctionEnd
 %fragment_main = OpFunction %void None %15
-         %48 = OpLabel
-         %49 = OpFunctionCall %void %fragment_main_1
+         %57 = OpLabel
+         %58 = OpFunctionCall %void %fragment_main_1
                OpReturn
                OpFunctionEnd
 %compute_main_1 = OpFunction %void None %15
-         %51 = OpLabel
-         %52 = OpFunctionCall %void %textureLoad_6273b1
+         %60 = OpLabel
+         %61 = OpFunctionCall %void %textureLoad_6273b1
                OpReturn
                OpFunctionEnd
 %compute_main = OpFunction %void None %15
-         %54 = OpLabel
-         %55 = OpFunctionCall %void %compute_main_1
+         %63 = OpLabel
+         %64 = OpFunctionCall %void %compute_main_1
                OpReturn
                OpFunctionEnd
 %vertex_main = OpFunction %void None %15
-         %57 = OpLabel
-         %58 = OpFunctionCall %vertex_main_out %vertex_main_inner
-         %59 = OpCompositeExtract %v4float %58 0
-               OpStore %vertex_main_position_Output %59 None
+         %66 = OpLabel
+         %67 = OpFunctionCall %vertex_main_out %vertex_main_inner
+         %68 = OpCompositeExtract %v4float %67 0
+               OpStore %vertex_main_position_Output %68 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.glsl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.glsl
index b4d5414..7e0e9a7 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.glsl
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.glsl
@@ -94,7 +94,7 @@
   return vec4(v_13, v_6);
 }
 vec4 textureLoad2d(tint_ExternalTextureParams tint_symbol_params, ivec2 coords) {
-  return tint_TextureLoadExternal(tint_symbol_params, uvec2(coords));
+  return tint_TextureLoadExternal(tint_symbol_params, min(uvec2(coords), ((tint_symbol_params.apparentSize + uvec2(1u)) - uvec2(1u))));
 }
 tint_ExternalTextureParams tint_convert_tint_ExternalTextureParams(tint_ExternalTextureParams_std140 tint_input) {
   mat3 v_14 = mat3(tint_input.gamutConversionMatrix_col0, tint_input.gamutConversionMatrix_col1, tint_input.gamutConversionMatrix_col2);
@@ -212,7 +212,7 @@
   return vec4(v_13, v_6);
 }
 vec4 textureLoad2d(tint_ExternalTextureParams tint_symbol_params, ivec2 coords) {
-  return tint_TextureLoadExternal(tint_symbol_params, uvec2(coords));
+  return tint_TextureLoadExternal(tint_symbol_params, min(uvec2(coords), ((tint_symbol_params.apparentSize + uvec2(1u)) - uvec2(1u))));
 }
 tint_ExternalTextureParams tint_convert_tint_ExternalTextureParams(tint_ExternalTextureParams_std140 tint_input) {
   mat3 v_14 = mat3(tint_input.gamutConversionMatrix_col0, tint_input.gamutConversionMatrix_col1, tint_input.gamutConversionMatrix_col2);
@@ -321,7 +321,7 @@
   return vec4(v_13, v_6);
 }
 vec4 textureLoad2d(tint_ExternalTextureParams tint_symbol_params, ivec2 coords) {
-  return tint_TextureLoadExternal(tint_symbol_params, uvec2(coords));
+  return tint_TextureLoadExternal(tint_symbol_params, min(uvec2(coords), ((tint_symbol_params.apparentSize + uvec2(1u)) - uvec2(1u))));
 }
 tint_ExternalTextureParams tint_convert_tint_ExternalTextureParams(tint_ExternalTextureParams_std140 tint_input) {
   mat3 v_14 = mat3(tint_input.gamutConversionMatrix_col0, tint_input.gamutConversionMatrix_col1, tint_input.gamutConversionMatrix_col2);
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.dxc.hlsl
index 1a37ba8..2dc2e61 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.dxc.hlsl
@@ -53,82 +53,95 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
 float4 textureLoad2d(Texture2D<float4> tint_symbol_plane0, Texture2D<float4> tint_symbol_plane1, tint_ExternalTextureParams tint_symbol_params, int2 coords) {
   return tint_TextureLoadExternal(tint_symbol_plane0, tint_symbol_plane1, tint_symbol_params, uint2(coords));
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 void doTextureLoad() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = textureLoad2d(arg_0_plane0, arg_0_plane1, v_48, (int(0)).xx);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = textureLoad2d(arg_0_plane0, arg_0_plane1, v_55, (int(0)).xx);
 }
 
 float4 vertex_main_inner() {
@@ -146,7 +159,7 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_outputs v_49 = {vertex_main_inner()};
-  return v_49;
+  vertex_main_outputs v_56 = {vertex_main_inner()};
+  return v_56;
 }
 
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.fxc.hlsl
index 1a37ba8..2dc2e61 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.fxc.hlsl
@@ -53,82 +53,95 @@
   float3 v_6 = (0.0f).xxx;
   float v_7 = 0.0f;
   if ((params.numPlanes == 1u)) {
-    int2 v_8 = int2(v_5);
-    float4 v_9 = float4(plane_0.Load(int3(v_8, int(0u))));
-    v_6 = v_9.xyz;
-    v_7 = v_9.w;
+    uint3 v_8 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_8.x, v_8.y, v_8.z);
+    uint3 v_9 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_8.z - 1u))), v_9.x, v_9.y, v_9.z);
+    int2 v_10 = int2(min(v_5, (v_9.xy - (1u).xx)));
+    float4 v_11 = float4(plane_0.Load(int3(v_10, int(min(0u, (v_8.z - 1u))))));
+    v_6 = v_11.xyz;
+    v_7 = v_11.w;
   } else {
-    int2 v_10 = int2(v_5);
-    float v_11 = float4(plane_0.Load(int3(v_10, int(0u)))).x;
-    int2 v_12 = int2(tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor)));
-    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_11, float4(plane_1.Load(int3(v_12, int(0u)))).xy, 1.0f));
+    uint3 v_12 = (0u).xxx;
+    plane_0.GetDimensions(0u, v_12.x, v_12.y, v_12.z);
+    uint3 v_13 = (0u).xxx;
+    plane_0.GetDimensions(uint(min(0u, (v_12.z - 1u))), v_13.x, v_13.y, v_13.z);
+    int2 v_14 = int2(min(v_5, (v_13.xy - (1u).xx)));
+    float v_15 = float4(plane_0.Load(int3(v_14, int(min(0u, (v_12.z - 1u)))))).x;
+    uint2 v_16 = tint_v2f32_to_v2u32((v_4 * params.plane1CoordFactor));
+    uint3 v_17 = (0u).xxx;
+    plane_1.GetDimensions(0u, v_17.x, v_17.y, v_17.z);
+    uint3 v_18 = (0u).xxx;
+    plane_1.GetDimensions(uint(min(0u, (v_17.z - 1u))), v_18.x, v_18.y, v_18.z);
+    int2 v_19 = int2(min(v_16, (v_18.xy - (1u).xx)));
+    v_6 = mul(params.yuvToRgbConversionMatrix, float4(v_15, float4(plane_1.Load(int3(v_19, int(min(0u, (v_17.z - 1u)))))).xy, 1.0f));
     v_7 = 1.0f;
   }
-  float3 v_13 = v_6;
-  float3 v_14 = (0.0f).xxx;
+  float3 v_20 = v_6;
+  float3 v_21 = (0.0f).xxx;
   if ((params.doYuvToRgbConversionOnly == 0u)) {
-    tint_GammaTransferParams v_15 = params.gammaDecodeParams;
-    tint_GammaTransferParams v_16 = params.gammaEncodeParams;
-    v_14 = tint_GammaCorrection(mul(tint_GammaCorrection(v_13, v_15), params.gamutConversionMatrix), v_16);
+    tint_GammaTransferParams v_22 = params.gammaDecodeParams;
+    tint_GammaTransferParams v_23 = params.gammaEncodeParams;
+    v_21 = tint_GammaCorrection(mul(tint_GammaCorrection(v_20, v_22), params.gamutConversionMatrix), v_23);
   } else {
-    v_14 = v_13;
+    v_21 = v_20;
   }
-  return float4(v_14, v_7);
+  return float4(v_21, v_7);
 }
 
 float4 textureLoad2d(Texture2D<float4> tint_symbol_plane0, Texture2D<float4> tint_symbol_plane1, tint_ExternalTextureParams tint_symbol_params, int2 coords) {
   return tint_TextureLoadExternal(tint_symbol_plane0, tint_symbol_plane1, tint_symbol_params, uint2(coords));
 }
 
-float3x2 v_17(uint start_byte_offset) {
-  uint4 v_18 = arg_0_params[(start_byte_offset / 16u)];
-  float2 v_19 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_18.zw) : (v_18.xy)));
-  uint4 v_20 = arg_0_params[((8u + start_byte_offset) / 16u)];
-  float2 v_21 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_20.zw) : (v_20.xy)));
-  uint4 v_22 = arg_0_params[((16u + start_byte_offset) / 16u)];
-  return float3x2(v_19, v_21, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_22.zw) : (v_22.xy))));
+float3x2 v_24(uint start_byte_offset) {
+  uint4 v_25 = arg_0_params[(start_byte_offset / 16u)];
+  float2 v_26 = asfloat((((((start_byte_offset % 16u) / 4u) == 2u)) ? (v_25.zw) : (v_25.xy)));
+  uint4 v_27 = arg_0_params[((8u + start_byte_offset) / 16u)];
+  float2 v_28 = asfloat(((((((8u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_27.zw) : (v_27.xy)));
+  uint4 v_29 = arg_0_params[((16u + start_byte_offset) / 16u)];
+  return float3x2(v_26, v_28, asfloat(((((((16u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_29.zw) : (v_29.xy))));
 }
 
-float3x3 v_23(uint start_byte_offset) {
+float3x3 v_30(uint start_byte_offset) {
   return float3x3(asfloat(arg_0_params[(start_byte_offset / 16u)].xyz), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)].xyz), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)].xyz));
 }
 
-tint_GammaTransferParams v_24(uint start_byte_offset) {
-  tint_GammaTransferParams v_25 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
-  return v_25;
+tint_GammaTransferParams v_31(uint start_byte_offset) {
+  tint_GammaTransferParams v_32 = {asfloat(arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)]), asfloat(arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((8u + start_byte_offset) / 16u)][(((8u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((12u + start_byte_offset) / 16u)][(((12u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)][(((16u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((20u + start_byte_offset) / 16u)][(((20u + start_byte_offset) % 16u) / 4u)]), asfloat(arg_0_params[((24u + start_byte_offset) / 16u)][(((24u + start_byte_offset) % 16u) / 4u)]), arg_0_params[((28u + start_byte_offset) / 16u)][(((28u + start_byte_offset) % 16u) / 4u)]};
+  return v_32;
 }
 
-float3x4 v_26(uint start_byte_offset) {
+float3x4 v_33(uint start_byte_offset) {
   return float3x4(asfloat(arg_0_params[(start_byte_offset / 16u)]), asfloat(arg_0_params[((16u + start_byte_offset) / 16u)]), asfloat(arg_0_params[((32u + start_byte_offset) / 16u)]));
 }
 
-tint_ExternalTextureParams v_27(uint start_byte_offset) {
-  uint v_28 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
-  uint v_29 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
-  float3x4 v_30 = v_26((16u + start_byte_offset));
-  tint_GammaTransferParams v_31 = v_24((64u + start_byte_offset));
-  tint_GammaTransferParams v_32 = v_24((96u + start_byte_offset));
-  float3x3 v_33 = v_23((128u + start_byte_offset));
-  float3x2 v_34 = v_17((176u + start_byte_offset));
-  float3x2 v_35 = v_17((200u + start_byte_offset));
-  uint4 v_36 = arg_0_params[((224u + start_byte_offset) / 16u)];
-  float2 v_37 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_36.zw) : (v_36.xy)));
-  uint4 v_38 = arg_0_params[((232u + start_byte_offset) / 16u)];
-  float2 v_39 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_38.zw) : (v_38.xy)));
-  uint4 v_40 = arg_0_params[((240u + start_byte_offset) / 16u)];
-  float2 v_41 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_40.zw) : (v_40.xy)));
-  uint4 v_42 = arg_0_params[((248u + start_byte_offset) / 16u)];
-  float2 v_43 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_42.zw) : (v_42.xy)));
-  uint4 v_44 = arg_0_params[((256u + start_byte_offset) / 16u)];
-  uint2 v_45 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_44.zw) : (v_44.xy));
-  uint4 v_46 = arg_0_params[((264u + start_byte_offset) / 16u)];
-  tint_ExternalTextureParams v_47 = {v_28, v_29, v_30, v_31, v_32, v_33, v_34, v_35, v_37, v_39, v_41, v_43, v_45, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_46.zw) : (v_46.xy)))};
-  return v_47;
+tint_ExternalTextureParams v_34(uint start_byte_offset) {
+  uint v_35 = arg_0_params[(start_byte_offset / 16u)][((start_byte_offset % 16u) / 4u)];
+  uint v_36 = arg_0_params[((4u + start_byte_offset) / 16u)][(((4u + start_byte_offset) % 16u) / 4u)];
+  float3x4 v_37 = v_33((16u + start_byte_offset));
+  tint_GammaTransferParams v_38 = v_31((64u + start_byte_offset));
+  tint_GammaTransferParams v_39 = v_31((96u + start_byte_offset));
+  float3x3 v_40 = v_30((128u + start_byte_offset));
+  float3x2 v_41 = v_24((176u + start_byte_offset));
+  float3x2 v_42 = v_24((200u + start_byte_offset));
+  uint4 v_43 = arg_0_params[((224u + start_byte_offset) / 16u)];
+  float2 v_44 = asfloat(((((((224u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_43.zw) : (v_43.xy)));
+  uint4 v_45 = arg_0_params[((232u + start_byte_offset) / 16u)];
+  float2 v_46 = asfloat(((((((232u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_45.zw) : (v_45.xy)));
+  uint4 v_47 = arg_0_params[((240u + start_byte_offset) / 16u)];
+  float2 v_48 = asfloat(((((((240u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_47.zw) : (v_47.xy)));
+  uint4 v_49 = arg_0_params[((248u + start_byte_offset) / 16u)];
+  float2 v_50 = asfloat(((((((248u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_49.zw) : (v_49.xy)));
+  uint4 v_51 = arg_0_params[((256u + start_byte_offset) / 16u)];
+  uint2 v_52 = ((((((256u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_51.zw) : (v_51.xy));
+  uint4 v_53 = arg_0_params[((264u + start_byte_offset) / 16u)];
+  tint_ExternalTextureParams v_54 = {v_35, v_36, v_37, v_38, v_39, v_40, v_41, v_42, v_44, v_46, v_48, v_50, v_52, asfloat(((((((264u + start_byte_offset) % 16u) / 4u) == 2u)) ? (v_53.zw) : (v_53.xy)))};
+  return v_54;
 }
 
 void doTextureLoad() {
-  tint_ExternalTextureParams v_48 = v_27(0u);
-  float4 res = textureLoad2d(arg_0_plane0, arg_0_plane1, v_48, (int(0)).xx);
+  tint_ExternalTextureParams v_55 = v_34(0u);
+  float4 res = textureLoad2d(arg_0_plane0, arg_0_plane1, v_55, (int(0)).xx);
 }
 
 float4 vertex_main_inner() {
@@ -146,7 +159,7 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_outputs v_49 = {vertex_main_inner()};
-  return v_49;
+  vertex_main_outputs v_56 = {vertex_main_inner()};
+  return v_56;
 }
 
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.msl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.msl
index bd8c484..910a92c 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.msl
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.ir.msl
@@ -104,7 +104,7 @@
 }
 
 float4 textureLoad2d(texture2d<float, access::sample> tint_symbol_plane0, texture2d<float, access::sample> tint_symbol_plane1, tint_ExternalTextureParams tint_symbol_params, int2 coords) {
-  return tint_TextureLoadExternal(tint_symbol_plane0, tint_symbol_plane1, tint_symbol_params, uint2(coords));
+  return tint_TextureLoadExternal(tint_symbol_plane0, tint_symbol_plane1, tint_symbol_params, min(uint2(coords), ((tint_symbol_params.apparentSize + uint2(1u)) - uint2(1u))));
 }
 
 tint_ExternalTextureParams tint_load_struct_packed_vec3(const constant tint_ExternalTextureParams_packed_vec3* const from) {
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl
index 5f384e0c..68548d5 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.msl
@@ -93,6 +93,10 @@
   return select(uint2(4294967295u), select(uint2(v), uint2(0u), (v < float2(0.0f))), (v <= float2(4294967040.0f)));
 }
 
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 float3 gammaCorrection(float3 v, GammaTransferParams params) {
   bool3 const cond = (fabs(v) < float3(params.D));
   float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F));
@@ -119,7 +123,7 @@
 }
 
 float4 textureLoad2d(texture2d<float, access::sample> tint_symbol, texture2d<float, access::sample> ext_tex_plane_1_1, ExternalTextureParams ext_tex_params_1, int2 coords) {
-  return textureLoadExternal(tint_symbol, ext_tex_plane_1_1, coords, ext_tex_params_1);
+  return textureLoadExternal(tint_symbol, ext_tex_plane_1_1, tint_clamp(coords, int2(0), int2(((ext_tex_params_1.apparentSize + uint2(1u)) - uint2(1u)))), ext_tex_params_1);
 }
 
 void doTextureLoad(texture2d<float, access::sample> tint_symbol_2, texture2d<float, access::sample> tint_symbol_3, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_4) {
diff --git a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.spvasm b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.spvasm
index b9744f5..7d3f026 100644
--- a/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.spvasm
+++ b/test/tint/builtins/textureLoad/texture_external_param.wgsl.expected.spvasm
@@ -1,10 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 174
+; Bound: 179
 ; Schema: 0
                OpCapability Shader
-         %75 = OpExtInstImport "GLSL.std.450"
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -172,178 +172,183 @@
         %int = OpTypeInt 32 1
       %v2int = OpTypeVector %int 2
          %31 = OpTypeFunction %v4float %3 %3 %tint_ExternalTextureParams %v2int
+     %uint_1 = OpConstant %uint 1
+         %35 = OpConstantComposite %v2uint %uint_1 %uint_1
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %45 = OpTypeFunction %void
 %_ptr_Uniform_tint_ExternalTextureParams_std140 = OpTypePointer Uniform %tint_ExternalTextureParams_std140
      %uint_0 = OpConstant %uint 0
-         %49 = OpConstantNull %v2int
+         %56 = OpConstantNull %v2int
 %_ptr_Function_v4float = OpTypePointer Function %v4float
-         %53 = OpTypeFunction %v4float
-         %56 = OpConstantNull %v4float
-         %67 = OpTypeFunction %v4float %3 %3 %tint_ExternalTextureParams %v2uint
+         %60 = OpTypeFunction %v4float
+         %63 = OpConstantNull %v4float
+         %74 = OpTypeFunction %v4float %3 %3 %tint_ExternalTextureParams %v2uint
     %float_1 = OpConstant %float 1
-     %uint_1 = OpConstant %uint 1
        %bool = OpTypeBool
-        %117 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
+        %122 = OpTypeFunction %v3float %v3float %tint_GammaTransferParams
      %v3bool = OpTypeVector %bool 3
-        %148 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
+        %153 = OpTypeFunction %tint_ExternalTextureParams %tint_ExternalTextureParams_std140
 %textureLoad2d = OpFunction %v4float None %31
 %texture_plane0 = OpFunctionParameter %3
 %texture_plane1 = OpFunctionParameter %3
 %texture_params = OpFunctionParameter %tint_ExternalTextureParams
      %coords = OpFunctionParameter %v2int
          %32 = OpLabel
-         %33 = OpBitcast %v2uint %coords
-         %34 = OpFunctionCall %v4float %tint_TextureLoadExternal %texture_plane0 %texture_plane1 %texture_params %33
-               OpReturnValue %34
+         %33 = OpCompositeExtract %v2uint %texture_params 12
+         %34 = OpIAdd %v2uint %33 %35
+         %37 = OpISub %v2uint %34 %35
+         %38 = OpBitcast %v2uint %coords
+         %39 = OpExtInst %v2uint %40 UMin %38 %37
+         %41 = OpFunctionCall %v4float %tint_TextureLoadExternal %texture_plane0 %texture_plane1 %texture_params %39
+               OpReturnValue %41
                OpFunctionEnd
-%doTextureLoad = OpFunction %void None %38
-         %39 = OpLabel
+%doTextureLoad = OpFunction %void None %45
+         %46 = OpLabel
         %res = OpVariable %_ptr_Function_v4float Function
-         %40 = OpLoad %3 %arg_0_plane0 None
-         %41 = OpLoad %3 %arg_0_plane1 None
-         %42 = OpAccessChain %_ptr_Uniform_tint_ExternalTextureParams_std140 %6 %uint_0
-         %45 = OpLoad %tint_ExternalTextureParams_std140 %42 None
-         %46 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %45
-         %48 = OpFunctionCall %v4float %textureLoad2d %40 %41 %46 %49
-               OpStore %res %48
+         %47 = OpLoad %3 %arg_0_plane0 None
+         %48 = OpLoad %3 %arg_0_plane1 None
+         %49 = OpAccessChain %_ptr_Uniform_tint_ExternalTextureParams_std140 %6 %uint_0
+         %52 = OpLoad %tint_ExternalTextureParams_std140 %49 None
+         %53 = OpFunctionCall %tint_ExternalTextureParams %tint_convert_tint_ExternalTextureParams %52
+         %55 = OpFunctionCall %v4float %textureLoad2d %47 %48 %53 %56
+               OpStore %res %55
                OpReturn
                OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %53
-         %54 = OpLabel
-         %55 = OpFunctionCall %void %doTextureLoad
-               OpReturnValue %56
-               OpFunctionEnd
-%fragment_main = OpFunction %void None %38
-         %58 = OpLabel
-         %59 = OpFunctionCall %void %doTextureLoad
-               OpReturn
-               OpFunctionEnd
-%compute_main = OpFunction %void None %38
+%vertex_main_inner = OpFunction %v4float None %60
          %61 = OpLabel
          %62 = OpFunctionCall %void %doTextureLoad
+               OpReturnValue %63
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %45
+         %65 = OpLabel
+         %66 = OpFunctionCall %void %doTextureLoad
                OpReturn
                OpFunctionEnd
-%tint_TextureLoadExternal = OpFunction %v4float None %67
+%compute_main = OpFunction %void None %45
+         %68 = OpLabel
+         %69 = OpFunctionCall %void %doTextureLoad
+               OpReturn
+               OpFunctionEnd
+%tint_TextureLoadExternal = OpFunction %v4float None %74
     %plane_0 = OpFunctionParameter %3
     %plane_1 = OpFunctionParameter %3
      %params = OpFunctionParameter %tint_ExternalTextureParams
    %coords_0 = OpFunctionParameter %v2uint
-         %68 = OpLabel
-         %69 = OpCompositeExtract %uint %params 1
-         %70 = OpCompositeExtract %mat3v4float %params 2
-         %71 = OpCompositeExtract %mat3v2float %params 7
-         %72 = OpCompositeExtract %v2uint %params 12
-         %73 = OpCompositeExtract %v2float %params 13
-         %74 = OpExtInst %v2uint %75 UMin %coords_0 %72
-         %76 = OpConvertUToF %v2float %74
-         %77 = OpCompositeConstruct %v3float %76 %float_1
-         %79 = OpMatrixTimesVector %v2float %71 %77
-         %80 = OpExtInst %v2float %75 RoundEven %79
-         %81 = OpConvertFToU %v2uint %80
-         %82 = OpCompositeExtract %uint %params 0
-         %83 = OpIEqual %bool %82 %uint_1
-               OpSelectionMerge %86 None
-               OpBranchConditional %83 %87 %88
-         %87 = OpLabel
-         %89 = OpImageFetch %v4float %plane_0 %81 Lod %uint_0
-         %90 = OpVectorShuffle %v3float %89 %89 0 1 2
-         %91 = OpCompositeExtract %float %89 3
-               OpBranch %86
-         %88 = OpLabel
-         %92 = OpImageFetch %v4float %plane_0 %81 Lod %uint_0
-         %93 = OpCompositeExtract %float %92 0
-         %94 = OpFMul %v2float %80 %73
-         %95 = OpConvertFToU %v2uint %94
-         %96 = OpImageFetch %v4float %plane_1 %95 Lod %uint_0
-         %97 = OpVectorShuffle %v2float %96 %96 0 1
-         %98 = OpCompositeConstruct %v4float %93 %97 %float_1
-         %99 = OpVectorTimesMatrix %v3float %98 %70
-               OpBranch %86
-         %86 = OpLabel
-        %100 = OpPhi %v3float %90 %87 %99 %88
-        %101 = OpPhi %float %91 %87 %float_1 %88
-        %102 = OpIEqual %bool %69 %uint_0
-               OpSelectionMerge %103 None
-               OpBranchConditional %102 %104 %105
-        %104 = OpLabel
-        %106 = OpCompositeExtract %tint_GammaTransferParams %params 3
-        %107 = OpCompositeExtract %tint_GammaTransferParams %params 4
-        %108 = OpCompositeExtract %mat3v3float %params 5
-        %109 = OpFunctionCall %v3float %tint_GammaCorrection %100 %106
-        %111 = OpMatrixTimesVector %v3float %108 %109
-        %112 = OpFunctionCall %v3float %tint_GammaCorrection %111 %107
-               OpBranch %103
-        %105 = OpLabel
-               OpBranch %103
-        %103 = OpLabel
-        %113 = OpPhi %v3float %112 %104 %100 %105
-        %114 = OpCompositeConstruct %v4float %113 %101
-               OpReturnValue %114
+         %75 = OpLabel
+         %76 = OpCompositeExtract %uint %params 1
+         %77 = OpCompositeExtract %mat3v4float %params 2
+         %78 = OpCompositeExtract %mat3v2float %params 7
+         %79 = OpCompositeExtract %v2uint %params 12
+         %80 = OpCompositeExtract %v2float %params 13
+         %81 = OpExtInst %v2uint %40 UMin %coords_0 %79
+         %82 = OpConvertUToF %v2float %81
+         %83 = OpCompositeConstruct %v3float %82 %float_1
+         %85 = OpMatrixTimesVector %v2float %78 %83
+         %86 = OpExtInst %v2float %40 RoundEven %85
+         %87 = OpConvertFToU %v2uint %86
+         %88 = OpCompositeExtract %uint %params 0
+         %89 = OpIEqual %bool %88 %uint_1
+               OpSelectionMerge %91 None
+               OpBranchConditional %89 %92 %93
+         %92 = OpLabel
+         %94 = OpImageFetch %v4float %plane_0 %87 Lod %uint_0
+         %95 = OpVectorShuffle %v3float %94 %94 0 1 2
+         %96 = OpCompositeExtract %float %94 3
+               OpBranch %91
+         %93 = OpLabel
+         %97 = OpImageFetch %v4float %plane_0 %87 Lod %uint_0
+         %98 = OpCompositeExtract %float %97 0
+         %99 = OpFMul %v2float %86 %80
+        %100 = OpConvertFToU %v2uint %99
+        %101 = OpImageFetch %v4float %plane_1 %100 Lod %uint_0
+        %102 = OpVectorShuffle %v2float %101 %101 0 1
+        %103 = OpCompositeConstruct %v4float %98 %102 %float_1
+        %104 = OpVectorTimesMatrix %v3float %103 %77
+               OpBranch %91
+         %91 = OpLabel
+        %105 = OpPhi %v3float %95 %92 %104 %93
+        %106 = OpPhi %float %96 %92 %float_1 %93
+        %107 = OpIEqual %bool %76 %uint_0
+               OpSelectionMerge %108 None
+               OpBranchConditional %107 %109 %110
+        %109 = OpLabel
+        %111 = OpCompositeExtract %tint_GammaTransferParams %params 3
+        %112 = OpCompositeExtract %tint_GammaTransferParams %params 4
+        %113 = OpCompositeExtract %mat3v3float %params 5
+        %114 = OpFunctionCall %v3float %tint_GammaCorrection %105 %111
+        %116 = OpMatrixTimesVector %v3float %113 %114
+        %117 = OpFunctionCall %v3float %tint_GammaCorrection %116 %112
+               OpBranch %108
+        %110 = OpLabel
+               OpBranch %108
+        %108 = OpLabel
+        %118 = OpPhi %v3float %117 %109 %105 %110
+        %119 = OpCompositeConstruct %v4float %118 %106
+               OpReturnValue %119
                OpFunctionEnd
-%tint_GammaCorrection = OpFunction %v3float None %117
+%tint_GammaCorrection = OpFunction %v3float None %122
           %v = OpFunctionParameter %v3float
    %params_0 = OpFunctionParameter %tint_GammaTransferParams
-        %118 = OpLabel
-        %119 = OpCompositeExtract %float %params_0 0
-        %120 = OpCompositeExtract %float %params_0 1
-        %121 = OpCompositeExtract %float %params_0 2
-        %122 = OpCompositeExtract %float %params_0 3
-        %123 = OpCompositeExtract %float %params_0 4
-        %124 = OpCompositeExtract %float %params_0 5
-        %125 = OpCompositeExtract %float %params_0 6
-        %126 = OpCompositeConstruct %v3float %119 %119 %119
-        %127 = OpCompositeConstruct %v3float %123 %123 %123
-        %128 = OpExtInst %v3float %75 FAbs %v
-        %129 = OpExtInst %v3float %75 FSign %v
-        %130 = OpFOrdLessThan %v3bool %128 %127
-        %132 = OpVectorTimesScalar %v3float %128 %122
-        %133 = OpCompositeConstruct %v3float %125 %125 %125
-        %134 = OpFAdd %v3float %132 %133
-        %135 = OpFMul %v3float %129 %134
-        %136 = OpVectorTimesScalar %v3float %128 %120
-        %137 = OpCompositeConstruct %v3float %121 %121 %121
-        %138 = OpFAdd %v3float %136 %137
-        %139 = OpExtInst %v3float %75 Pow %138 %126
-        %140 = OpCompositeConstruct %v3float %124 %124 %124
-        %141 = OpFAdd %v3float %139 %140
-        %142 = OpFMul %v3float %129 %141
-        %143 = OpSelect %v3float %130 %135 %142
-               OpReturnValue %143
+        %123 = OpLabel
+        %124 = OpCompositeExtract %float %params_0 0
+        %125 = OpCompositeExtract %float %params_0 1
+        %126 = OpCompositeExtract %float %params_0 2
+        %127 = OpCompositeExtract %float %params_0 3
+        %128 = OpCompositeExtract %float %params_0 4
+        %129 = OpCompositeExtract %float %params_0 5
+        %130 = OpCompositeExtract %float %params_0 6
+        %131 = OpCompositeConstruct %v3float %124 %124 %124
+        %132 = OpCompositeConstruct %v3float %128 %128 %128
+        %133 = OpExtInst %v3float %40 FAbs %v
+        %134 = OpExtInst %v3float %40 FSign %v
+        %135 = OpFOrdLessThan %v3bool %133 %132
+        %137 = OpVectorTimesScalar %v3float %133 %127
+        %138 = OpCompositeConstruct %v3float %130 %130 %130
+        %139 = OpFAdd %v3float %137 %138
+        %140 = OpFMul %v3float %134 %139
+        %141 = OpVectorTimesScalar %v3float %133 %125
+        %142 = OpCompositeConstruct %v3float %126 %126 %126
+        %143 = OpFAdd %v3float %141 %142
+        %144 = OpExtInst %v3float %40 Pow %143 %131
+        %145 = OpCompositeConstruct %v3float %129 %129 %129
+        %146 = OpFAdd %v3float %144 %145
+        %147 = OpFMul %v3float %134 %146
+        %148 = OpSelect %v3float %135 %140 %147
+               OpReturnValue %148
                OpFunctionEnd
-%vertex_main = OpFunction %void None %38
-        %145 = OpLabel
-        %146 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %vertex_main_position_Output %146 None
+%vertex_main = OpFunction %void None %45
+        %150 = OpLabel
+        %151 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %vertex_main_position_Output %151 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %148
+%tint_convert_tint_ExternalTextureParams = OpFunction %tint_ExternalTextureParams None %153
  %tint_input = OpFunctionParameter %tint_ExternalTextureParams_std140
-        %149 = OpLabel
-        %150 = OpCompositeExtract %uint %tint_input 0
-        %151 = OpCompositeExtract %uint %tint_input 1
-        %152 = OpCompositeExtract %mat3v4float %tint_input 2
-        %153 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
-        %154 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
-        %155 = OpCompositeExtract %v3float %tint_input 5
-        %156 = OpCompositeExtract %v3float %tint_input 6
-        %157 = OpCompositeExtract %v3float %tint_input 7
-        %158 = OpCompositeConstruct %mat3v3float %155 %156 %157
-        %159 = OpCompositeExtract %v2float %tint_input 8
-        %160 = OpCompositeExtract %v2float %tint_input 9
-        %161 = OpCompositeExtract %v2float %tint_input 10
-        %162 = OpCompositeConstruct %mat3v2float %159 %160 %161
-        %163 = OpCompositeExtract %v2float %tint_input 11
-        %164 = OpCompositeExtract %v2float %tint_input 12
-        %165 = OpCompositeExtract %v2float %tint_input 13
-        %166 = OpCompositeConstruct %mat3v2float %163 %164 %165
-        %167 = OpCompositeExtract %v2float %tint_input 14
-        %168 = OpCompositeExtract %v2float %tint_input 15
-        %169 = OpCompositeExtract %v2float %tint_input 16
-        %170 = OpCompositeExtract %v2float %tint_input 17
-        %171 = OpCompositeExtract %v2uint %tint_input 18
-        %172 = OpCompositeExtract %v2float %tint_input 19
-        %173 = OpCompositeConstruct %tint_ExternalTextureParams %150 %151 %152 %153 %154 %158 %162 %166 %167 %168 %169 %170 %171 %172
-               OpReturnValue %173
+        %154 = OpLabel
+        %155 = OpCompositeExtract %uint %tint_input 0
+        %156 = OpCompositeExtract %uint %tint_input 1
+        %157 = OpCompositeExtract %mat3v4float %tint_input 2
+        %158 = OpCompositeExtract %tint_GammaTransferParams %tint_input 3
+        %159 = OpCompositeExtract %tint_GammaTransferParams %tint_input 4
+        %160 = OpCompositeExtract %v3float %tint_input 5
+        %161 = OpCompositeExtract %v3float %tint_input 6
+        %162 = OpCompositeExtract %v3float %tint_input 7
+        %163 = OpCompositeConstruct %mat3v3float %160 %161 %162
+        %164 = OpCompositeExtract %v2float %tint_input 8
+        %165 = OpCompositeExtract %v2float %tint_input 9
+        %166 = OpCompositeExtract %v2float %tint_input 10
+        %167 = OpCompositeConstruct %mat3v2float %164 %165 %166
+        %168 = OpCompositeExtract %v2float %tint_input 11
+        %169 = OpCompositeExtract %v2float %tint_input 12
+        %170 = OpCompositeExtract %v2float %tint_input 13
+        %171 = OpCompositeConstruct %mat3v2float %168 %169 %170
+        %172 = OpCompositeExtract %v2float %tint_input 14
+        %173 = OpCompositeExtract %v2float %tint_input 15
+        %174 = OpCompositeExtract %v2float %tint_input 16
+        %175 = OpCompositeExtract %v2float %tint_input 17
+        %176 = OpCompositeExtract %v2uint %tint_input 18
+        %177 = OpCompositeExtract %v2float %tint_input 19
+        %178 = OpCompositeConstruct %tint_ExternalTextureParams %155 %156 %157 %158 %159 %163 %167 %171 %172 %173 %174 %175 %176 %177
+               OpReturnValue %178
                OpFunctionEnd
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.glsl b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.glsl
index b5f6468..6a85ec9 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.glsl
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.glsl
@@ -1,12 +1,23 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
-ivec4 textureLoad2d(ivec2 coords, int level) {
-  ivec2 v = ivec2(coords);
-  return texelFetch(arg_0, v, int(level));
+ivec4 textureLoad2d(ivec2 coords, int level, uint tint_tex_value) {
+  uint v_1 = min(uint(level), (tint_tex_value - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(coords), v_2));
+  return texelFetch(arg_0, v_3, int(v_1));
 }
 void doTextureLoad() {
-  ivec4 res = textureLoad2d(ivec2(0), 0);
+  ivec4 res = textureLoad2d(ivec2(0), 0, v.inner.tint_builtin_value_0);
 }
 vec4 vertex_main_inner() {
   doTextureLoad();
@@ -22,26 +33,48 @@
 precision highp float;
 precision highp int;
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
-ivec4 textureLoad2d(ivec2 coords, int level) {
-  ivec2 v = ivec2(coords);
-  return texelFetch(arg_0, v, int(level));
+ivec4 textureLoad2d(ivec2 coords, int level, uint tint_tex_value) {
+  uint v_1 = min(uint(level), (tint_tex_value - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(coords), v_2));
+  return texelFetch(arg_0, v_3, int(v_1));
 }
 void doTextureLoad() {
-  ivec4 res = textureLoad2d(ivec2(0), 0);
+  ivec4 res = textureLoad2d(ivec2(0), 0, v.inner.tint_builtin_value_0);
 }
 void main() {
   doTextureLoad();
 }
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp isampler2D arg_0;
-ivec4 textureLoad2d(ivec2 coords, int level) {
-  ivec2 v = ivec2(coords);
-  return texelFetch(arg_0, v, int(level));
+ivec4 textureLoad2d(ivec2 coords, int level, uint tint_tex_value) {
+  uint v_1 = min(uint(level), (tint_tex_value - 1u));
+  uvec2 v_2 = (uvec2(textureSize(arg_0, int(v_1))) - uvec2(1u));
+  ivec2 v_3 = ivec2(min(uvec2(coords), v_2));
+  return texelFetch(arg_0, v_3, int(v_1));
 }
 void doTextureLoad() {
-  ivec4 res = textureLoad2d(ivec2(0), 0);
+  ivec4 res = textureLoad2d(ivec2(0), 0, v.inner.tint_builtin_value_0);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.dxc.hlsl
index f51a504..5158428 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.dxc.hlsl
@@ -5,8 +5,14 @@
 
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad2d(Texture2D<int4> tint_symbol, int2 coords, int level) {
-  int2 v = int2(coords);
-  return int4(tint_symbol.Load(int3(v, int(level))));
+  uint3 v = (0u).xxx;
+  tint_symbol.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(level), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  tint_symbol.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(coords), v_3));
+  return int4(tint_symbol.Load(int3(v_4, int(v_1))));
 }
 
 void doTextureLoad() {
@@ -28,7 +34,7 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_outputs v_1 = {vertex_main_inner()};
-  return v_1;
+  vertex_main_outputs v_5 = {vertex_main_inner()};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.fxc.hlsl
index f51a504..5158428 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.fxc.hlsl
@@ -5,8 +5,14 @@
 
 Texture2D<int4> arg_0 : register(t0, space1);
 int4 textureLoad2d(Texture2D<int4> tint_symbol, int2 coords, int level) {
-  int2 v = int2(coords);
-  return int4(tint_symbol.Load(int3(v, int(level))));
+  uint3 v = (0u).xxx;
+  tint_symbol.GetDimensions(0u, v.x, v.y, v.z);
+  uint v_1 = min(uint(level), (v.z - 1u));
+  uint3 v_2 = (0u).xxx;
+  tint_symbol.GetDimensions(uint(v_1), v_2.x, v_2.y, v_2.z);
+  uint2 v_3 = (v_2.xy - (1u).xx);
+  int2 v_4 = int2(min(uint2(coords), v_3));
+  return int4(tint_symbol.Load(int3(v_4, int(v_1))));
 }
 
 void doTextureLoad() {
@@ -28,7 +34,7 @@
 }
 
 vertex_main_outputs vertex_main() {
-  vertex_main_outputs v_1 = {vertex_main_inner()};
-  return v_1;
+  vertex_main_outputs v_5 = {vertex_main_inner()};
+  return v_5;
 }
 
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.msl b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.msl
index 6610306..8b6bf57 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.msl
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.ir.msl
@@ -10,7 +10,9 @@
 };
 
 int4 textureLoad2d(texture2d<int, access::sample> tint_symbol, int2 coords, int level) {
-  return tint_symbol.read(uint2(coords), level);
+  uint const v = min(uint(level), (tint_symbol.get_num_mip_levels() - 1u));
+  uint2 const v_1 = (uint2(tint_symbol.get_width(v), tint_symbol.get_height(v)) - uint2(1u));
+  return tint_symbol.read(min(uint2(coords), v_1), v);
 }
 
 void doTextureLoad(tint_module_vars_struct tint_module_vars) {
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.msl b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.msl
index eda6fa1..51a64a1 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.msl
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+int2 tint_clamp(int2 e, int2 low, int2 high) {
+  return min(max(e, low), high);
+}
+
 int4 textureLoad2d(texture2d<int, access::sample> tint_symbol, int2 coords, int level) {
-  return tint_symbol.read(uint2(coords), level);
+  uint const level_idx = min(uint(level), (tint_symbol.get_num_mip_levels() - 1u));
+  return tint_symbol.read(uint2(tint_clamp(coords, int2(0), int2((uint2(tint_symbol.get_width(level_idx), tint_symbol.get_height(level_idx)) - uint2(1u))))), level_idx);
 }
 
 void doTextureLoad(texture2d<int, access::sample> tint_symbol_2) {
diff --git a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.spvasm b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.spvasm
index ad79d7d..534f33e 100644
--- a/test/tint/builtins/textureLoad/texture_param.wgsl.expected.spvasm
+++ b/test/tint/builtins/textureLoad/texture_param.wgsl.expected.spvasm
@@ -1,9 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 58
 ; Schema: 0
                OpCapability Shader
+               OpCapability ImageQuery
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %fragment_main "fragment_main"
                OpEntryPoint GLCompute %compute_main "compute_main"
@@ -40,49 +42,61 @@
       %v4int = OpTypeVector %int 4
       %v2int = OpTypeVector %int 2
          %17 = OpTypeFunction %v4int %3 %v2int %int
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
+     %v2uint = OpTypeVector %uint 2
+         %29 = OpConstantComposite %v2uint %uint_1 %uint_1
        %void = OpTypeVoid
-         %22 = OpTypeFunction %void
-         %26 = OpConstantNull %v2int
+         %35 = OpTypeFunction %void
+         %39 = OpConstantNull %v2int
       %int_0 = OpConstant %int 0
 %_ptr_Function_v4int = OpTypePointer Function %v4int
-         %31 = OpTypeFunction %v4float
-         %34 = OpConstantNull %v4float
+         %44 = OpTypeFunction %v4float
+         %47 = OpConstantNull %v4float
     %float_1 = OpConstant %float 1
 %textureLoad2d = OpFunction %v4int None %17
     %texture = OpFunctionParameter %3
      %coords = OpFunctionParameter %v2int
       %level = OpFunctionParameter %int
          %18 = OpLabel
-         %19 = OpImageFetch %v4int %texture %coords Lod %level
-               OpReturnValue %19
+         %19 = OpImageQueryLevels %uint %texture
+         %21 = OpISub %uint %19 %uint_1
+         %23 = OpBitcast %uint %level
+         %24 = OpExtInst %uint %25 UMin %23 %21
+         %26 = OpImageQuerySizeLod %v2uint %texture %24
+         %28 = OpISub %v2uint %26 %29
+         %30 = OpBitcast %v2uint %coords
+         %31 = OpExtInst %v2uint %25 UMin %30 %28
+         %32 = OpImageFetch %v4int %texture %31 Lod %24
+               OpReturnValue %32
                OpFunctionEnd
-%doTextureLoad = OpFunction %void None %22
-         %23 = OpLabel
-        %res = OpVariable %_ptr_Function_v4int Function
-         %24 = OpLoad %3 %arg_0 None
-         %25 = OpFunctionCall %v4int %textureLoad2d %24 %26 %int_0
-               OpStore %res %25
-               OpReturn
-               OpFunctionEnd
-%vertex_main_inner = OpFunction %v4float None %31
-         %32 = OpLabel
-         %33 = OpFunctionCall %void %doTextureLoad
-               OpReturnValue %34
-               OpFunctionEnd
-%fragment_main = OpFunction %void None %22
+%doTextureLoad = OpFunction %void None %35
          %36 = OpLabel
-         %37 = OpFunctionCall %void %doTextureLoad
+        %res = OpVariable %_ptr_Function_v4int Function
+         %37 = OpLoad %3 %arg_0 None
+         %38 = OpFunctionCall %v4int %textureLoad2d %37 %39 %int_0
+               OpStore %res %38
                OpReturn
                OpFunctionEnd
-%compute_main = OpFunction %void None %22
-         %39 = OpLabel
-         %40 = OpFunctionCall %void %doTextureLoad
+%vertex_main_inner = OpFunction %v4float None %44
+         %45 = OpLabel
+         %46 = OpFunctionCall %void %doTextureLoad
+               OpReturnValue %47
+               OpFunctionEnd
+%fragment_main = OpFunction %void None %35
+         %49 = OpLabel
+         %50 = OpFunctionCall %void %doTextureLoad
                OpReturn
                OpFunctionEnd
-%vertex_main = OpFunction %void None %22
-         %42 = OpLabel
-         %43 = OpFunctionCall %v4float %vertex_main_inner
-               OpStore %vertex_main_position_Output %43 None
+%compute_main = OpFunction %void None %35
+         %52 = OpLabel
+         %53 = OpFunctionCall %void %doTextureLoad
+               OpReturn
+               OpFunctionEnd
+%vertex_main = OpFunction %void None %35
+         %55 = OpLabel
+         %56 = OpFunctionCall %v4float %vertex_main_inner
+               OpStore %vertex_main_position_Output %56 None
                OpStore %vertex_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.ir.msl b/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.ir.msl
index 7325f09..c0a5876 100644
--- a/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.ir.msl
+++ b/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.ir.msl
@@ -5,10 +5,14 @@
   texture2d<int, access::read_write> tex;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void foo(tint_module_vars_struct tint_module_vars) {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 3)) {
       } else {
         break;
diff --git a/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.msl b/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.msl
index 355f8e0..9fe0a5f 100644
--- a/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.msl
+++ b/test/tint/builtins/textureStore/loop_continuing_read_write_texture.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void foo(texture2d<int, access::read_write> tint_symbol) {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       if (!((i < 3))) {
         break;
       }
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.glsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.glsl
index e3adf9d..77f84c3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.glsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.glsl
@@ -5,7 +5,7 @@
   barrier();
   int v_1[128] = v;
   barrier();
-  return v_1[0];
+  return v_1[0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.dxc.hlsl
index a141b9d..90773f3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.dxc.hlsl
@@ -4,7 +4,7 @@
   GroupMemoryBarrierWithGroupSync();
   int v_1[128] = v;
   GroupMemoryBarrierWithGroupSync();
-  return v_1[int(0)];
+  return v_1[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.fxc.hlsl
index a141b9d..90773f3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.fxc.hlsl
@@ -4,7 +4,7 @@
   GroupMemoryBarrierWithGroupSync();
   int v_1[128] = v;
   GroupMemoryBarrierWithGroupSync();
-  return v_1[int(0)];
+  return v_1[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.msl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.msl
index 7d3bdfe..0295257 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.msl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count.wgsl.expected.ir.msl
@@ -21,5 +21,5 @@
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_array<int, 128> const v_1 = (*tint_module_vars.v);
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  return v_1[0];
+  return v_1[0u];
 }
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.glsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.glsl
index e3adf9d..77f84c3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.glsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.glsl
@@ -5,7 +5,7 @@
   barrier();
   int v_1[128] = v;
   barrier();
-  return v_1[0];
+  return v_1[0u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.dxc.hlsl
index a141b9d..90773f3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.dxc.hlsl
@@ -4,7 +4,7 @@
   GroupMemoryBarrierWithGroupSync();
   int v_1[128] = v;
   GroupMemoryBarrierWithGroupSync();
-  return v_1[int(0)];
+  return v_1[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.fxc.hlsl
index a141b9d..90773f3 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.fxc.hlsl
@@ -4,7 +4,7 @@
   GroupMemoryBarrierWithGroupSync();
   int v_1[128] = v;
   GroupMemoryBarrierWithGroupSync();
-  return v_1[int(0)];
+  return v_1[0u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.msl b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.msl
index 7d3bdfe..0295257 100644
--- a/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.msl
+++ b/test/tint/builtins/workgroupUniformLoad/array_overridable_count_aliased.wgsl.expected.ir.msl
@@ -21,5 +21,5 @@
   threadgroup_barrier(mem_flags::mem_threadgroup);
   tint_array<int, 128> const v_1 = (*tint_module_vars.v);
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  return v_1[0];
+  return v_1[0u];
 }
diff --git a/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.ir.msl b/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.ir.msl
index 71a4c7a..df06f9b 100644
--- a/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.ir.msl
+++ b/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.ir.msl
@@ -6,10 +6,14 @@
   threadgroup int* b;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void foo(tint_module_vars_struct tint_module_vars) {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       int const v = i;
       threadgroup_barrier(mem_flags::mem_threadgroup);
       int const v_1 = (*tint_module_vars.a);
diff --git a/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.msl b/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.msl
index 6985a31..3ae8c42 100644
--- a/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.msl
+++ b/test/tint/builtins/workgroupUniformLoad/for_loop.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int tint_workgroupUniformLoad(threadgroup int* const p) {
   threadgroup_barrier(mem_flags::mem_threadgroup);
   int const result = *(p);
@@ -12,6 +16,7 @@
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       int const tint_symbol = i;
       int const tint_symbol_1 = tint_workgroupUniformLoad(tint_symbol_4);
       if (!((tint_symbol < tint_symbol_1))) {
diff --git a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.glsl b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.glsl
index 96cbd7c..913b2ab 100644
--- a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.glsl
+++ b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.glsl
@@ -8,7 +8,7 @@
   return v_1;
 }
 int bar() {
-  return foo(uint[1](uint(0)));
+  return foo(uint[1](0u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.dxc.hlsl b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.dxc.hlsl
index 1b92454..c5d369f 100644
--- a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.dxc.hlsl
@@ -8,7 +8,7 @@
 }
 
 int bar() {
-  uint v_2[1] = {uint(int(0))};
+  uint v_2[1] = {0u};
   return foo(v_2);
 }
 
diff --git a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.fxc.hlsl b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.fxc.hlsl
index 1b92454..c5d369f 100644
--- a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.fxc.hlsl
@@ -8,7 +8,7 @@
 }
 
 int bar() {
-  uint v_2[1] = {uint(int(0))};
+  uint v_2[1] = {0u};
   return foo(v_2);
 }
 
diff --git a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.msl b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.msl
index 1341be2..cf3b556 100644
--- a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.msl
+++ b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.ir.msl
@@ -25,5 +25,5 @@
 }
 
 int bar(tint_module_vars_struct tint_module_vars) {
-  return foo((&(*tint_module_vars.v)[0]));
+  return foo((&(*tint_module_vars.v)[0u]));
 }
diff --git a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.spvasm b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.spvasm
index 25664f2..c62a013 100644
--- a/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.spvasm
+++ b/test/tint/builtins/workgroupUniformLoad/via_param.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -28,8 +28,8 @@
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
          %23 = OpTypeFunction %int
-      %int_0 = OpConstant %int 0
-         %30 = OpTypeFunction %void
+     %uint_0 = OpConstant %uint 0
+         %29 = OpTypeFunction %void
         %foo = OpFunction %int None %11
   %p_indices = OpFunctionParameter %_arr_uint_uint_1
          %12 = OpLabel
@@ -42,12 +42,11 @@
                OpFunctionEnd
         %bar = OpFunction %int None %23
          %24 = OpLabel
-         %25 = OpBitcast %uint %int_0
-         %27 = OpCompositeConstruct %_arr_uint_uint_1 %25
-         %28 = OpFunctionCall %int %foo %27
-               OpReturnValue %28
+         %25 = OpCompositeConstruct %_arr_uint_uint_1 %uint_0
+         %27 = OpFunctionCall %int %foo %25
+               OpReturnValue %27
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %30
-         %31 = OpLabel
+%unused_entry_point = OpFunction %void None %29
+         %30 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.ir.msl
index e736db7..49b79da 100644
--- a/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -21,6 +24,7 @@
   float4 v = float4(0.0f);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       bool v_1 = false;
       if ((x > v[0u])) {
         v_1 = (dfdx(1.0f) > 0.0f);
diff --git a/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.msl
index 011bb34..7c3a9fa 100644
--- a/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/for_loop_attribute.wgsl.expected.msl
@@ -13,6 +13,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_4 {
   float x [[user(locn0)]];
 };
@@ -20,6 +24,7 @@
 void tint_symbol_inner(float x) {
   float4 v = float4(0.0f);
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     bool tint_symbol_1 = (x > v[0]);
     if (tint_symbol_1) {
       float const tint_symbol_2 = dfdx(1.0f);
diff --git a/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.ir.msl
index 34ccd45..7d349b6 100644
--- a/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   sampler s;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -26,6 +29,7 @@
   float4 v = float4(0.0f);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((x > v[0u])) {
       } else {
         break;
diff --git a/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.msl
index 4335d2f..119f37e 100644
--- a/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/for_loop_body_attribute.wgsl.expected.msl
@@ -13,6 +13,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   float x [[user(locn0)]];
 };
@@ -20,6 +24,7 @@
 void tint_symbol_inner(float x, texture2d<float, access::sample> tint_symbol_3, sampler tint_symbol_4) {
   float4 v = float4(0.0f);
   for(; (x > v[0]); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     v = tint_symbol_3.sample(tint_symbol_4, float2(0.0f));
   }
 }
diff --git a/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.ir.msl
index 507f55c..de7b62f 100644
--- a/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -20,6 +23,7 @@
 void tint_symbol_inner(float x) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       dfdx(1.0f);
       {
         if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.msl
index e08ba7d..6cf6c95 100644
--- a/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/loop_attribute.wgsl.expected.msl
@@ -13,12 +13,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   float x [[user(locn0)]];
 };
 
 void tint_symbol_inner(float x) {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     float const tint_phony = dfdx(1.0f);
     {
       if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.ir.msl
index 8d45d19..18c03d7 100644
--- a/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -20,6 +23,7 @@
 void tint_symbol_inner(float x) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       dfdx(1.0f);
       {
         if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.msl
index 5826002..cf466f9 100644
--- a/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/loop_body_attribute.wgsl.expected.msl
@@ -13,12 +13,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   float x [[user(locn0)]];
 };
 
 void tint_symbol_inner(float x) {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     float const tint_phony = dfdx(1.0f);
     {
       if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.ir.msl
index 8501abe..efa9d91 100644
--- a/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -20,6 +23,7 @@
 void tint_symbol_inner(float x) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       {
         dfdx(1.0f);
         if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.msl
index a46a495..06c50d7 100644
--- a/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/loop_continuing_attribute.wgsl.expected.msl
@@ -13,12 +13,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   float x [[user(locn0)]];
 };
 
 void tint_symbol_inner(float x) {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     {
       float const tint_phony = dfdx(1.0f);
       if ((x > 0.0f)) { break; }
diff --git a/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.ir.msl
index 246451e..4c7af50 100644
--- a/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.ir.msl
@@ -13,6 +13,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -21,6 +24,7 @@
   float4 v = float4(0.0f);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       bool v_1 = false;
       if ((x > 0.0f)) {
         v_1 = (dfdx(1.0f) > 0.0f);
diff --git a/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.msl
index c0755d1..96b069d 100644
--- a/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/while_loop_attribute.wgsl.expected.msl
@@ -13,6 +13,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_4 {
   float x [[user(locn0)]];
 };
@@ -20,6 +24,7 @@
 void tint_symbol_inner(float x) {
   float4 v = float4(0.0f);
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     bool tint_symbol_1 = (x > 0.0f);
     if (tint_symbol_1) {
       float const tint_symbol_2 = dfdx(1.0f);
diff --git a/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.ir.msl b/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.ir.msl
index beef7de..93cc724 100644
--- a/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.ir.msl
+++ b/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.ir.msl
@@ -18,6 +18,9 @@
   sampler s;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_inputs {
   float x [[user(locn0)]];
 };
@@ -26,6 +29,7 @@
   float4 v = float4(0.0f);
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((x > v[0u])) {
       } else {
         break;
diff --git a/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.msl b/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.msl
index 657eb2d..9551cf0 100644
--- a/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.msl
+++ b/test/tint/diagnostic_filtering/while_loop_body_attribute.wgsl.expected.msl
@@ -13,6 +13,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   float x [[user(locn0)]];
 };
@@ -20,6 +24,7 @@
 void tint_symbol_inner(float x, texture2d<float, access::sample> tint_symbol_3, sampler tint_symbol_4) {
   float4 v = float4(0.0f);
   while((x > v[0])) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     v = tint_symbol_3.sample(tint_symbol_4, float2(0.0f));
   }
 }
diff --git a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.glsl b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.glsl
index 6f9d164..1dd0921 100644
--- a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 uint f() {
   S a[2] = S[2](S(0, uint[4](0u, 0u, 0u, 0u)), S(0, uint[4](0u, 0u, 0u, 0u)));
-  return a[1].n[1];
+  return a[1u].n[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.dxc.hlsl
index 913da7f..fa7b3e9 100644
--- a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a[2] = (S[2])0;
-  return a[int(1)].n[int(1)];
+  return a[1u].n[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.fxc.hlsl
index 913da7f..fa7b3e9 100644
--- a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a[2] = (S[2])0;
-  return a[int(1)].n[int(1)];
+  return a[1u].n[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.msl b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.msl
index de0cc8e..7a0a4c0 100644
--- a/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/array_nested_struct.wgsl.expected.ir.msl
@@ -20,5 +20,5 @@
 
 uint f() {
   tint_array<S, 2> const a = tint_array<S, 2>{};
-  return a[1].n[1];
+  return a[1u].n[1u];
 }
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.dxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.fxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.glsl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.glsl
index 95de7b1..05aa203 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 int f() {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.dxc.hlsl
index d4902b4..317db4e 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.fxc.hlsl
index d4902b4..317db4e 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.msl
index 72f3cc6..2b38131 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 int f() {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.msl b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.msl
index f999fd1..cefa306 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.msl
@@ -17,6 +17,6 @@
 int f() {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.spvasm
index 93ee50e..53cad17 100644
--- a/test/tint/expressions/index/let/let/literal/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/literal/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -27,18 +28,21 @@
       %int_8 = OpConstant %int 8
           %a = OpConstantComposite %_arr_int_uint_8 %i %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
 %_ptr_Function__arr_int_uint_8 = OpTypePointer Function %_arr_int_uint_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
           %f = OpFunction %int None %3
           %4 = OpLabel
          %17 = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %17 %a
-         %19 = OpAccessChain %_ptr_Function_int %17 %i
-         %21 = OpLoad %int %19 None
-               OpReturnValue %21
+         %19 = OpBitcast %uint %i
+         %20 = OpExtInst %uint %21 UMin %19 %uint_7
+         %23 = OpAccessChain %_ptr_Function_int %17 %20
+         %25 = OpLoad %int %23 None
+               OpReturnValue %25
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %24
-         %25 = OpLabel
+%unused_entry_point = OpFunction %void None %28
+         %29 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.dxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.fxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl
index a2f275f..ad157d6 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 vec3 f() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
index 67c1f60..df784e3 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
index 67c1f60..df784e3 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.msl
index 4c8cb95..d579202 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float3 f() {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl
index ca9238e..09fbd17 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float3 f() {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm
index 6ef3a97..6414ff1 100644
--- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -31,18 +32,22 @@
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %4
           %5 = OpLabel
          %20 = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %20 %m
-         %24 = OpAccessChain %_ptr_Function_v3float %20 %i
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %i
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %20 %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.dxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.fxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl
index b6cfdca..40a4687 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 float f() {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.dxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.fxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.msl
index faececb..f67afea 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float f() {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int const i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl
index 587f5cf..c59fe84 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float f() {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int const i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm
index 16ede29..a2cc14c 100644
--- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 17
+; Bound: 22
 ; Schema: 0
                OpCapability Shader
+         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -20,14 +21,18 @@
           %v = OpConstantComposite %v3float %float_1 %float_2 %float_3
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
-         %15 = OpTypeFunction %void
+         %20 = OpTypeFunction %void
           %f = OpFunction %float None %3
           %4 = OpLabel
-         %12 = OpVectorExtractDynamic %float %v %i
-               OpReturnValue %12
+         %13 = OpBitcast %uint %i
+         %14 = OpExtInst %uint %15 UMin %13 %uint_2
+         %17 = OpVectorExtractDynamic %float %v %14
+               OpReturnValue %17
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %15
-         %16 = OpLabel
+%unused_entry_point = OpFunction %void None %20
+         %21 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.dxc.hlsl
index 5c4041c..2db30d2 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 int f(int x) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.fxc.hlsl
index 5c4041c..2db30d2 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 int f(int x) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.glsl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.glsl
index 4938464..fa10752 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 int f(int x) {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.dxc.hlsl
index 69ee417..3c73ea0 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 int f(int x) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.fxc.hlsl
index 69ee417..3c73ea0 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 int f(int x) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.msl
index 91fdaf1..7e892b3 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 int f(int x) {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.msl b/test/tint/expressions/index/let/let/param/array.wgsl.expected.msl
index 11906e9..8f06ed2 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.msl
@@ -17,6 +17,6 @@
 int f(int x) {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/param/array.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/param/array.wgsl.expected.spvasm
index 68a875e..0e434fc 100644
--- a/test/tint/expressions/index/let/let/param/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/param/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -28,19 +29,22 @@
       %int_8 = OpConstant %int 8
           %a = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
 %_ptr_Function__arr_int_uint_8 = OpTypePointer Function %_arr_int_uint_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
           %f = OpFunction %int None %4
           %x = OpFunctionParameter %int
           %5 = OpLabel
          %18 = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %18 %a
-         %20 = OpAccessChain %_ptr_Function_int %18 %x
-         %22 = OpLoad %int %20 None
-               OpReturnValue %22
+         %20 = OpBitcast %uint %x
+         %21 = OpExtInst %uint %22 UMin %20 %uint_7
+         %24 = OpAccessChain %_ptr_Function_int %18 %21
+         %26 = OpLoad %int %24 None
+               OpReturnValue %26
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %25
-         %26 = OpLabel
+%unused_entry_point = OpFunction %void None %29
+         %30 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.dxc.hlsl
index 6296b13..2422082 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.fxc.hlsl
index 6296b13..2422082 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.glsl
index 16b363c..04f5d66 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 vec3 f(int x) {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.dxc.hlsl
index 4d80cf8..a80357a 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.fxc.hlsl
index 4d80cf8..a80357a 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.msl
index acea5f3..5cfac3d 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float3 f(int x) {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.msl
index 647d17a..bb35914 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float3 f(int x) {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.spvasm
index 0e3bf8c..43ebe1d 100644
--- a/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/param/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -31,19 +32,23 @@
          %18 = OpConstantComposite %v3float %float_7 %float_8 %float_9
           %m = OpConstantComposite %mat3v3float %10 %14 %18
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %6
           %x = OpFunctionParameter %int
           %7 = OpLabel
          %22 = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %22 %m
-         %24 = OpAccessChain %_ptr_Function_v3float %22 %x
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %x
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %22 %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.dxc.hlsl
index a0099e2..9ae77d4 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.fxc.hlsl
index a0099e2..9ae77d4 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.glsl
index 69600ec..359523f 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 float f(int x) {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.dxc.hlsl
index cdda7a2..dbc1165 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.fxc.hlsl
index cdda7a2..dbc1165 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.msl
index d0c764d..c535eed 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float f(int x) {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int const i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.msl b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.msl
index b0d8ca9..f4958df 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float f(int x) {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int const i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.spvasm
index 001edfb..3230ece 100644
--- a/test/tint/expressions/index/let/let/param/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/let/param/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 17
+; Bound: 22
 ; Schema: 0
                OpCapability Shader
+         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -20,15 +21,19 @@
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %v = OpConstantComposite %v3float %float_1 %float_2 %float_3
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
-         %15 = OpTypeFunction %void
+         %20 = OpTypeFunction %void
           %f = OpFunction %float None %5
           %x = OpFunctionParameter %int
           %6 = OpLabel
-         %12 = OpVectorExtractDynamic %float %v %x
-               OpReturnValue %12
+         %13 = OpBitcast %uint %x
+         %14 = OpExtInst %uint %15 UMin %13 %uint_2
+         %17 = OpVectorExtractDynamic %float %v %14
+               OpReturnValue %17
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %15
-         %16 = OpLabel
+%unused_entry_point = OpFunction %void None %20
+         %21 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/literal/array.wgsl.expected.glsl b/test/tint/expressions/index/let/literal/array.wgsl.expected.glsl
index d31d251..8295549 100644
--- a/test/tint/expressions/index/let/literal/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/literal/array.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 int f() {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
-  return a[1];
+  return a[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.dxc.hlsl
index 29308c6..da2c25a 100644
--- a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[int(1)];
+  return a[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.fxc.hlsl
index 29308c6..da2c25a 100644
--- a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[int(1)];
+  return a[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.msl
index 74cd769..8050c19 100644
--- a/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/literal/array.wgsl.expected.ir.msl
@@ -15,5 +15,5 @@
 
 int f() {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[1];
+  return a[1u];
 }
diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl
index 9f05a7f..01158e6 100644
--- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 vec3 f() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  return m[1];
+  return m[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
index 0937c50..6d30cdc 100644
--- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[int(1)];
+  return m[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
index 0937c50..6d30cdc 100644
--- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[int(1)];
+  return m[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.msl
index 5ebac5f..dbe1234 100644
--- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float3 f() {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[1];
+  return m[1u];
 }
diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl
index 0abf8a1..2382c41 100644
--- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 float f() {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
-  return v[1];
+  return v[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/literal/vector.wgsl.expected.ir.msl
index c1607bd..244477b 100644
--- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float f() {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
-  return v[1];
+  return v[1u];
 }
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/param/array.wgsl.expected.dxc.hlsl
index f0e32a0..3c759ff 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 int f(int i) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/param/array.wgsl.expected.fxc.hlsl
index f0e32a0..3c759ff 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 int f(int i) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.glsl b/test/tint/expressions/index/let/param/array.wgsl.expected.glsl
index 547232f..405a7a8 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 int f(int i) {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.dxc.hlsl
index 22b57d3..6df480f 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 int f(int i) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.fxc.hlsl
index 22b57d3..6df480f 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 int f(int i) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.msl
index 80b89a3..6901bbd 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.ir.msl
@@ -15,5 +15,5 @@
 
 int f(int i) {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.msl b/test/tint/expressions/index/let/param/array.wgsl.expected.msl
index d3bbdae..e8be7ed 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.msl
@@ -16,6 +16,6 @@
 
 int f(int i) {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/let/param/array.wgsl.expected.spvasm b/test/tint/expressions/index/let/param/array.wgsl.expected.spvasm
index 61f7a20..02847c4 100644
--- a/test/tint/expressions/index/let/param/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/param/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -27,19 +28,22 @@
       %int_8 = OpConstant %int 8
           %a = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
 %_ptr_Function__arr_int_uint_8 = OpTypePointer Function %_arr_int_uint_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
           %f = OpFunction %int None %4
           %i = OpFunctionParameter %int
           %5 = OpLabel
          %18 = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %18 %a
-         %20 = OpAccessChain %_ptr_Function_int %18 %i
-         %22 = OpLoad %int %20 None
-               OpReturnValue %22
+         %20 = OpBitcast %uint %i
+         %21 = OpExtInst %uint %22 UMin %20 %uint_7
+         %24 = OpAccessChain %_ptr_Function_int %18 %21
+         %26 = OpLoad %int %24 None
+               OpReturnValue %26
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %25
-         %26 = OpLabel
+%unused_entry_point = OpFunction %void None %29
+         %30 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.dxc.hlsl
index 724ad88..6bdc009 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.fxc.hlsl
index 724ad88..6bdc009 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.glsl
index 04e225a..147016b 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 vec3 f(int i) {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.dxc.hlsl
index abb3a66..2916862 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.fxc.hlsl
index abb3a66..2916862 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.msl
index 9be4acf..6168cf3 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float3 f(int i) {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/param/matrix.wgsl.expected.msl
index 49218fd..622dbc1 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 float3 f(int i) {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/param/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/param/matrix.wgsl.expected.spvasm
index 402965a..2afe9ec 100644
--- a/test/tint/expressions/index/let/param/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/param/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -30,19 +31,23 @@
          %18 = OpConstantComposite %v3float %float_7 %float_8 %float_9
           %m = OpConstantComposite %mat3v3float %10 %14 %18
 %_ptr_Function_mat3v3float = OpTypePointer Function %mat3v3float
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %6
           %i = OpFunctionParameter %int
           %7 = OpLabel
          %22 = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %22 %m
-         %24 = OpAccessChain %_ptr_Function_v3float %22 %i
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %i
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %22 %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/param/vector.wgsl.expected.dxc.hlsl
index d046c84..4e84c0b 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/param/vector.wgsl.expected.fxc.hlsl
index d046c84..4e84c0b 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/param/vector.wgsl.expected.glsl
index 9ad3700..9edd7e2 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 float f(int i) {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.dxc.hlsl
index adceace..dd18b2b 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.fxc.hlsl
index adceace..dd18b2b 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.msl
index 8b1dd00..8407b89 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float f(int i) {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.msl b/test/tint/expressions/index/let/param/vector.wgsl.expected.msl
index 4d45110..1da6068 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 float f(int i) {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/param/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/param/vector.wgsl.expected.spvasm
index 28e924a..4c0fced 100644
--- a/test/tint/expressions/index/let/param/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/param/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 17
+; Bound: 22
 ; Schema: 0
                OpCapability Shader
+         %15 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -19,15 +20,19 @@
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
           %v = OpConstantComposite %v3float %float_1 %float_2 %float_3
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
-         %15 = OpTypeFunction %void
+         %20 = OpTypeFunction %void
           %f = OpFunction %float None %5
           %i = OpFunctionParameter %int
           %6 = OpLabel
-         %12 = OpVectorExtractDynamic %float %v %i
-               OpReturnValue %12
+         %13 = OpBitcast %uint %i
+         %14 = OpExtInst %uint %15 UMin %13 %uint_2
+         %17 = OpVectorExtractDynamic %float %v %14
+               OpReturnValue %17
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %15
-         %16 = OpLabel
+%unused_entry_point = OpFunction %void None %20
+         %21 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.glsl b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.glsl
index c254b04..90d245a 100644
--- a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 uint f() {
   S a = S(0, uint[4](0u, 0u, 0u, 0u));
-  return a.n[2];
+  return a.n[2u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.dxc.hlsl
index a5ab48c..5a62104 100644
--- a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)];
+  return a.n[2u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.fxc.hlsl
index a5ab48c..5a62104 100644
--- a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)];
+  return a.n[2u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.msl
index 44943de..7a86032 100644
--- a/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/struct_nested_array.wgsl.expected.ir.msl
@@ -20,5 +20,5 @@
 
 uint f() {
   S const a = S{};
-  return a.n[2];
+  return a.n[2u];
 }
diff --git a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.glsl b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.glsl
index 0c6c6c5..c3a9958 100644
--- a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 
 uint f() {
   S a = S(0, T[4](T(uint[2](0u, 0u)), T(uint[2](0u, 0u)), T(uint[2](0u, 0u)), T(uint[2](0u, 0u))));
-  return a.n[2].k[1];
+  return a.n[2u].k[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
index e79f41d..e0e060a 100644
--- a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)].k[int(1)];
+  return a.n[2u].k[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
index e79f41d..e0e060a 100644
--- a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)].k[int(1)];
+  return a.n[2u].k[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.msl b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.msl
index 2e1ed8f..9e8921b 100644
--- a/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/struct_nested_multiple.wgsl.expected.ir.msl
@@ -24,5 +24,5 @@
 
 uint f() {
   S const a = S{};
-  return a.n[2].k[1];
+  return a.n[2u].k[1u];
 }
diff --git a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.glsl
index b15d600..96d7754 100644
--- a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 float f() {
   S a = S(0, mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f)));
-  return a.n[2][1];
+  return a.n[2u][1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
index 0a128c8..89ec140 100644
--- a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 float f() {
   S a = (S)0;
-  return a.n[int(2)].y;
+  return a.n[2u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
index 0a128c8..89ec140 100644
--- a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 float f() {
   S a = (S)0;
-  return a.n[int(2)].y;
+  return a.n[2u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.msl
index bf48e9e..06a5784 100644
--- a/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/struct_with_matrix.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 
 float f() {
   S const a = S{};
-  return a.n[2][1];
+  return a.n[2u][1u];
 }
diff --git a/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.glsl b/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.glsl
index 71d2e5c..d646d9b 100644
--- a/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 uint f() {
   S a = S(0, uvec3(0u));
-  return a.n[2];
+  return a.n[2u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.ir.msl
index 8dbe9f3..ccc5e24 100644
--- a/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/struct_with_vector.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 
 uint f() {
   S const a = S{};
-  return a.n[2];
+  return a.n[2u];
 }
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.dxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.fxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.glsl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.glsl
index 95de7b1..05aa203 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 int f() {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.dxc.hlsl
index d4902b4..317db4e 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.fxc.hlsl
index d4902b4..317db4e 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.msl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.msl
index a16c2c2..163fe7c 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 int f() {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.msl b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.msl
index 462ae1a..61c70fe 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.msl
@@ -17,6 +17,6 @@
 int f() {
   tint_array<int, 8> const a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.spvasm b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.spvasm
index 02a04a9..634eab6 100644
--- a/test/tint/expressions/index/let/var/literal/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/var/literal/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 32
 ; Schema: 0
                OpCapability Shader
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -28,8 +29,9 @@
           %a = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
 %_ptr_Function__arr_int_uint_8 = OpTypePointer Function %_arr_int_uint_8
 %_ptr_Function_int = OpTypePointer Function %int
+     %uint_7 = OpConstant %uint 7
        %void = OpTypeVoid
-         %26 = OpTypeFunction %void
+         %30 = OpTypeFunction %void
           %f = OpFunction %int None %3
           %4 = OpLabel
          %17 = OpVariable %_ptr_Function__arr_int_uint_8 Function
@@ -37,11 +39,13 @@
                OpStore %17 %a
                OpStore %i %int_1
          %21 = OpLoad %int %i None
-         %22 = OpAccessChain %_ptr_Function_int %17 %21
-         %23 = OpLoad %int %22 None
-               OpReturnValue %23
+         %22 = OpBitcast %uint %21
+         %23 = OpExtInst %uint %24 UMin %22 %uint_7
+         %26 = OpAccessChain %_ptr_Function_int %17 %23
+         %27 = OpLoad %int %26 None
+               OpReturnValue %27
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %26
-         %27 = OpLabel
+%unused_entry_point = OpFunction %void None %30
+         %31 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.dxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.fxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.glsl
index a2f275f..ad157d6 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 vec3 f() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
index 67c1f60..df784e3 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
index 67c1f60..df784e3 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.msl
index 11877c2..1e9bd72 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float3 f() {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.msl
index 298cde8..a528563b 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float3 f() {
   float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.spvasm
index 859578e..58ca078 100644
--- a/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/var/literal/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 34
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -32,9 +33,11 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %32 = OpTypeFunction %void
+         %37 = OpTypeFunction %void
           %f = OpFunction %v3float None %4
           %5 = OpLabel
          %20 = OpVariable %_ptr_Function_mat3v3float Function
@@ -42,11 +45,13 @@
                OpStore %20 %m
                OpStore %i %int_1
          %26 = OpLoad %int %i None
-         %27 = OpAccessChain %_ptr_Function_v3float %20 %26
-         %29 = OpLoad %v3float %27 None
-               OpReturnValue %29
+         %28 = OpBitcast %uint %26
+         %29 = OpExtInst %uint %30 UMin %28 %uint_2
+         %32 = OpAccessChain %_ptr_Function_v3float %20 %29
+         %34 = OpLoad %v3float %32 None
+               OpReturnValue %34
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %32
-         %33 = OpLabel
+%unused_entry_point = OpFunction %void None %37
+         %38 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.dxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.fxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.glsl
index b6cfdca..40a4687 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 float f() {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.dxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.fxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.msl
index 24357aa..b4e45de 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float f() {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.msl b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.msl
index 3ff740d..70305fe 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float f() {
   float3 const v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.spvasm
index aac19d5..52f0918 100644
--- a/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/let/var/literal/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 20
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -21,17 +22,21 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
-         %18 = OpTypeFunction %void
+         %23 = OpTypeFunction %void
           %f = OpFunction %float None %3
           %4 = OpLabel
           %i = OpVariable %_ptr_Function_int Function
                OpStore %i %int_1
          %14 = OpLoad %int %i None
-         %15 = OpVectorExtractDynamic %float %v %14
-               OpReturnValue %15
+         %16 = OpBitcast %uint %14
+         %17 = OpExtInst %uint %18 UMin %16 %uint_2
+         %20 = OpVectorExtractDynamic %float %v %17
+               OpReturnValue %20
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %18
-         %19 = OpLabel
+%unused_entry_point = OpFunction %void None %23
+         %24 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.glsl b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.glsl
index 6f9d164..1dd0921 100644
--- a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 uint f() {
   S a[2] = S[2](S(0, uint[4](0u, 0u, 0u, 0u)), S(0, uint[4](0u, 0u, 0u, 0u)));
-  return a[1].n[1];
+  return a[1u].n[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.dxc.hlsl
index 913da7f..fa7b3e9 100644
--- a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a[2] = (S[2])0;
-  return a[int(1)].n[int(1)];
+  return a[1u].n[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.fxc.hlsl
index 913da7f..fa7b3e9 100644
--- a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a[2] = (S[2])0;
-  return a[int(1)].n[int(1)];
+  return a[1u].n[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.msl b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.msl
index dc8d5cf..3400bbd 100644
--- a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.ir.msl
@@ -20,5 +20,5 @@
 
 uint f() {
   tint_array<S, 2> a = tint_array<S, 2>{};
-  return a[1].n[1];
+  return a[1u].n[1u];
 }
diff --git a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.spvasm b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.spvasm
index babcaf6..f8dcd74 100644
--- a/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/array_nested_struct.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 23
+; Bound: 22
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -28,19 +28,18 @@
 %_ptr_Function__arr_S_uint_2 = OpTypePointer Function %_arr_S_uint_2
          %13 = OpConstantNull %_arr_S_uint_2
 %_ptr_Function_uint = OpTypePointer Function %uint
-      %int_1 = OpConstant %int 1
      %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %21 = OpTypeFunction %void
+         %20 = OpTypeFunction %void
           %f = OpFunction %uint None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function__arr_S_uint_2 Function
                OpStore %a %13
-         %14 = OpAccessChain %_ptr_Function_uint %a %int_1 %uint_1 %int_1
-         %18 = OpLoad %uint %14 None
-               OpReturnValue %18
+         %14 = OpAccessChain %_ptr_Function_uint %a %uint_1 %uint_1 %uint_1
+         %17 = OpLoad %uint %14 None
+               OpReturnValue %17
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %21
-         %22 = OpLabel
+%unused_entry_point = OpFunction %void None %20
+         %21 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.dxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.fxc.hlsl
index 05fa120..6156aa3 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 int f() {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.glsl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.glsl
index 95de7b1..0a27c54 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.glsl
@@ -3,7 +3,8 @@
 int f() {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
   int i = 1;
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.dxc.hlsl
index d4902b4..06f09e2 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,8 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.fxc.hlsl
index d4902b4..06f09e2 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,8 @@
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = int(1);
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.msl
index 993e5f5..a12e0f5 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 int f() {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.msl b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.msl
index a435dac..3255c3b 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.msl
@@ -17,6 +17,6 @@
 int f() {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = 1;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.spvasm
index a3de68e..8bcf5e9 100644
--- a/test/tint/expressions/index/var/let/literal/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/literal/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -27,18 +28,21 @@
       %int_7 = OpConstant %int 7
       %int_8 = OpConstant %int 8
          %10 = OpConstantComposite %_arr_int_uint_8 %i %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %28 = OpTypeFunction %void
           %f = OpFunction %int None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %a %10
-         %19 = OpAccessChain %_ptr_Function_int %a %i
-         %21 = OpLoad %int %19 None
-               OpReturnValue %21
+         %19 = OpBitcast %uint %i
+         %20 = OpExtInst %uint %21 UMin %19 %uint_7
+         %23 = OpAccessChain %_ptr_Function_int %a %20
+         %25 = OpLoad %int %23 None
+               OpReturnValue %25
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %24
-         %25 = OpLabel
+%unused_entry_point = OpFunction %void None %28
+         %29 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.dxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.fxc.hlsl
index 57214c7..f39b04c 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.glsl
index a2f275f..b884ca8 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.glsl
@@ -3,7 +3,8 @@
 vec3 f() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
   int i = 1;
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
index 67c1f60..cbf6bfa 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,8 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
index 67c1f60..cbf6bfa 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,8 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = int(1);
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.msl
index 11f6252..2cd11c8 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.msl b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.msl
index 0536bc1..084e80f 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = 1;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.spvasm
index bec0998..dbfd46d 100644
--- a/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/literal/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -31,18 +32,22 @@
           %9 = OpConstantComposite %mat3v3float %10 %14 %18
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %4
           %5 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %9
-         %24 = OpAccessChain %_ptr_Function_v3float %m %i
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %i
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %m %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.dxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.fxc.hlsl
index 0f4070c..0cdcaab4 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.glsl
index b6cfdca..40a4687 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 float f() {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
   int i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.dxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.fxc.hlsl
index a2f375b..ef93205 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = int(1);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.msl
index a335fb6..56be2c5 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int const i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.msl b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.msl
index 07ca4fb..9cbae4b 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int const i = 1;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.spvasm
index 9911b09..8749330 100644
--- a/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/literal/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -21,18 +22,22 @@
           %8 = OpConstantComposite %v3float %float_1 %float_2 %float_3
         %int = OpTypeInt 32 1
           %i = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %19 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
           %f = OpFunction %float None %3
           %4 = OpLabel
           %v = OpVariable %_ptr_Function_v3float Function
                OpStore %v %8
-         %14 = OpAccessChain %_ptr_Function_float %v %i
-         %16 = OpLoad %float %14 None
-               OpReturnValue %16
+         %15 = OpBitcast %uint %i
+         %16 = OpExtInst %uint %17 UMin %15 %uint_2
+         %19 = OpAccessChain %_ptr_Function_float %v %16
+         %21 = OpLoad %float %19 None
+               OpReturnValue %21
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %19
-         %20 = OpLabel
+%unused_entry_point = OpFunction %void None %24
+         %25 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.dxc.hlsl
index 5c4041c..2db30d2 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 int f(int x) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.fxc.hlsl
index 5c4041c..2db30d2 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 int f(int x) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
   int i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.glsl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.glsl
index 4938464..8476cf6 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.glsl
@@ -3,7 +3,8 @@
 int f(int x) {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
   int i = x;
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.dxc.hlsl
index 69ee417..5ffd4a7 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,8 @@
 int f(int x) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = x;
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.fxc.hlsl
index 69ee417..5ffd4a7 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,8 @@
 int f(int x) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
   int i = x;
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.msl
index e90e938..f8508cd 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 int f(int x) {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.msl b/test/tint/expressions/index/var/let/param/array.wgsl.expected.msl
index 970f617..049376f 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.msl
@@ -17,6 +17,6 @@
 int f(int x) {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
   int const i = x;
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/param/array.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/param/array.wgsl.expected.spvasm
index a8445f9..d38bfdf 100644
--- a/test/tint/expressions/index/var/let/param/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/param/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -28,19 +29,22 @@
       %int_7 = OpConstant %int 7
       %int_8 = OpConstant %int 8
          %11 = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
           %f = OpFunction %int None %4
           %x = OpFunctionParameter %int
           %5 = OpLabel
           %a = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %a %11
-         %20 = OpAccessChain %_ptr_Function_int %a %x
-         %22 = OpLoad %int %20 None
-               OpReturnValue %22
+         %20 = OpBitcast %uint %x
+         %21 = OpExtInst %uint %22 UMin %20 %uint_7
+         %24 = OpAccessChain %_ptr_Function_int %a %21
+         %26 = OpLoad %int %24 None
+               OpReturnValue %26
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %25
-         %26 = OpLabel
+%unused_entry_point = OpFunction %void None %29
+         %30 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.dxc.hlsl
index 6296b13..2422082 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.fxc.hlsl
index 6296b13..2422082 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.glsl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.glsl
index 16b363c..8ee21ff 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.glsl
@@ -3,7 +3,8 @@
 vec3 f(int x) {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.dxc.hlsl
index 4d80cf8..f9cc6c1 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,8 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.fxc.hlsl
index 4d80cf8..f9cc6c1 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,8 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int i = x;
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.msl
index d9ece0b..ef40cb9 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.msl b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.msl
index f282e52..ee2ee61 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float3 f(int x) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
   int const i = x;
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.spvasm
index 2878e53..9fc8e7e 100644
--- a/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/param/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -31,19 +32,23 @@
     %float_9 = OpConstant %float 9
          %20 = OpConstantComposite %v3float %float_7 %float_8 %float_9
          %11 = OpConstantComposite %mat3v3float %12 %16 %20
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %6
           %x = OpFunctionParameter %int
           %7 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %11
-         %24 = OpAccessChain %_ptr_Function_v3float %m %x
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %x
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %m %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.dxc.hlsl
index a0099e2..9ae77d4 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.dxc.hlsl
@@ -6,5 +6,5 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.fxc.hlsl
index a0099e2..9ae77d4 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.fxc.hlsl
@@ -6,5 +6,5 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.glsl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.glsl
index 69600ec..359523f 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.glsl
@@ -3,7 +3,7 @@
 float f(int x) {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.dxc.hlsl
index cdda7a2..dbc1165 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.fxc.hlsl
index cdda7a2..dbc1165 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.msl
index e7c6bc8..206c213 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.ir.msl
@@ -4,5 +4,5 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int const i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.msl b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.msl
index 374fe2c..def2c0d 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.msl
@@ -4,6 +4,6 @@
 float f(int x) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
   int const i = x;
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.spvasm b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.spvasm
index 505c334..5a1cb17 100644
--- a/test/tint/expressions/index/var/let/param/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/let/param/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -21,19 +22,23 @@
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
          %10 = OpConstantComposite %v3float %float_1 %float_2 %float_3
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %19 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
           %f = OpFunction %float None %5
           %x = OpFunctionParameter %int
           %6 = OpLabel
           %v = OpVariable %_ptr_Function_v3float Function
                OpStore %v %10
-         %14 = OpAccessChain %_ptr_Function_float %v %x
-         %16 = OpLoad %float %14 None
-               OpReturnValue %16
+         %15 = OpBitcast %uint %x
+         %16 = OpExtInst %uint %17 UMin %15 %uint_2
+         %19 = OpAccessChain %_ptr_Function_float %v %16
+         %21 = OpLoad %float %19 None
+               OpReturnValue %21
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %19
-         %20 = OpLabel
+%unused_entry_point = OpFunction %void None %24
+         %25 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/literal/array.wgsl.expected.glsl b/test/tint/expressions/index/var/literal/array.wgsl.expected.glsl
index d31d251..8295549 100644
--- a/test/tint/expressions/index/var/literal/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/literal/array.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 int f() {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
-  return a[1];
+  return a[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.dxc.hlsl
index 29308c6..da2c25a 100644
--- a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[int(1)];
+  return a[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.fxc.hlsl
index 29308c6..da2c25a 100644
--- a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 int f() {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[int(1)];
+  return a[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.msl b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.msl
index 8bb73af..64fab13 100644
--- a/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/literal/array.wgsl.expected.ir.msl
@@ -15,5 +15,5 @@
 
 int f() {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[1];
+  return a[1u];
 }
diff --git a/test/tint/expressions/index/var/literal/array.wgsl.expected.spvasm b/test/tint/expressions/index/var/literal/array.wgsl.expected.spvasm
index 690ac52..9a3b4e6 100644
--- a/test/tint/expressions/index/var/literal/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/literal/array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -27,17 +27,18 @@
       %int_8 = OpConstant %int 8
          %10 = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
 %_ptr_Function_int = OpTypePointer Function %int
+     %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %25 = OpTypeFunction %void
           %f = OpFunction %int None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %a %10
-         %19 = OpAccessChain %_ptr_Function_int %a %int_1
-         %21 = OpLoad %int %19 None
-               OpReturnValue %21
+         %19 = OpAccessChain %_ptr_Function_int %a %uint_1
+         %22 = OpLoad %int %19 None
+               OpReturnValue %22
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %24
-         %25 = OpLabel
+%unused_entry_point = OpFunction %void None %25
+         %26 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.glsl
index 9f05a7f..01158e6 100644
--- a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 vec3 f() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  return m[1];
+  return m[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
index 0937c50..6d30cdc 100644
--- a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[int(1)];
+  return m[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
index 0937c50..6d30cdc 100644
--- a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[int(1)];
+  return m[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.msl
index 9983768..ca33472 100644
--- a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float3 f() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[1];
+  return m[1u];
 }
diff --git a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.spvasm
index 2fab4e7..3b1cb81 100644
--- a/test/tint/expressions/index/var/literal/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/literal/matrix.wgsl.expected.spvasm
@@ -29,15 +29,15 @@
          %18 = OpConstantComposite %v3float %float_7 %float_8 %float_9
           %9 = OpConstantComposite %mat3v3float %10 %14 %18
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
          %29 = OpTypeFunction %void
           %f = OpFunction %v3float None %4
           %5 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %9
-         %22 = OpAccessChain %_ptr_Function_v3float %m %int_1
+         %22 = OpAccessChain %_ptr_Function_v3float %m %uint_1
          %26 = OpLoad %v3float %22 None
                OpReturnValue %26
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/literal/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/var/literal/vector.wgsl.expected.ir.msl
index faad1ff..e37e801 100644
--- a/test/tint/expressions/index/var/literal/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/literal/vector.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float f() {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[1];
+  return v[1u];
 }
diff --git a/test/tint/expressions/index/var/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/var/literal/vector.wgsl.expected.spvasm
index 473540d..49d4c4b 100644
--- a/test/tint/expressions/index/var/literal/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/literal/vector.wgsl.expected.spvasm
@@ -19,15 +19,15 @@
     %float_3 = OpConstant %float 3
           %8 = OpConstantComposite %v3float %float_1 %float_2 %float_3
 %_ptr_Function_float = OpTypePointer Function %float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
        %void = OpTypeVoid
          %19 = OpTypeFunction %void
           %f = OpFunction %float None %3
           %4 = OpLabel
           %v = OpVariable %_ptr_Function_v3float Function
                OpStore %v %8
-         %12 = OpAccessChain %_ptr_Function_float %v %int_1
+         %12 = OpAccessChain %_ptr_Function_float %v %uint_1
          %16 = OpLoad %float %12 None
                OpReturnValue %16
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/param/array.wgsl.expected.dxc.hlsl
index f0e32a0..3c759ff 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 int f(int i) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/param/array.wgsl.expected.fxc.hlsl
index f0e32a0..3c759ff 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 int f(int i) {
   int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.glsl b/test/tint/expressions/index/var/param/array.wgsl.expected.glsl
index 547232f..11341b6 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.glsl
@@ -2,7 +2,8 @@
 
 int f(int i) {
   int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.dxc.hlsl
index 22b57d3..6ba7245 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,8 @@
 
 int f(int i) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.fxc.hlsl
index 22b57d3..6ba7245 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,8 @@
 
 int f(int i) {
   int a[8] = {int(1), int(2), int(3), int(4), int(5), int(6), int(7), int(8)};
-  return a[i];
+  uint v = min(uint(i), 7u);
+  return a[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.msl b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.msl
index 08d2a88..d4f7e1a 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.ir.msl
@@ -15,5 +15,5 @@
 
 int f(int i) {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.msl b/test/tint/expressions/index/var/param/array.wgsl.expected.msl
index 918a63b..ccf26f7 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.msl
@@ -16,6 +16,6 @@
 
 int f(int i) {
   tint_array<int, 8> a = tint_array<int, 8>{1, 2, 3, 4, 5, 6, 7, 8};
-  return a[i];
+  return a[min(uint(i), 7u)];
 }
 
diff --git a/test/tint/expressions/index/var/param/array.wgsl.expected.spvasm b/test/tint/expressions/index/var/param/array.wgsl.expected.spvasm
index 1ab81db..eeca5bc 100644
--- a/test/tint/expressions/index/var/param/array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/param/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -27,19 +28,22 @@
       %int_7 = OpConstant %int 7
       %int_8 = OpConstant %int 8
          %11 = OpConstantComposite %_arr_int_uint_8 %int_1 %int_2 %int_3 %int_4 %int_5 %int_6 %int_7 %int_8
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_int = OpTypePointer Function %int
        %void = OpTypeVoid
-         %25 = OpTypeFunction %void
+         %29 = OpTypeFunction %void
           %f = OpFunction %int None %4
           %i = OpFunctionParameter %int
           %5 = OpLabel
           %a = OpVariable %_ptr_Function__arr_int_uint_8 Function
                OpStore %a %11
-         %20 = OpAccessChain %_ptr_Function_int %a %i
-         %22 = OpLoad %int %20 None
-               OpReturnValue %22
+         %20 = OpBitcast %uint %i
+         %21 = OpExtInst %uint %22 UMin %20 %uint_7
+         %24 = OpAccessChain %_ptr_Function_int %a %21
+         %26 = OpLoad %int %24 None
+               OpReturnValue %26
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %25
-         %26 = OpLabel
+%unused_entry_point = OpFunction %void None %29
+         %30 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.dxc.hlsl
index 724ad88..6bdc009 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.fxc.hlsl
index 724ad88..6bdc009 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.glsl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.glsl
index 04e225a..cf1c19f 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.glsl
@@ -2,7 +2,8 @@
 
 vec3 f(int i) {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.dxc.hlsl
index abb3a66..ec33112 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,8 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.fxc.hlsl
index abb3a66..ec33112 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,8 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  uint v = min(uint(i), 2u);
+  return m[v];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.msl
index 9a144f5..f478660 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.msl b/test/tint/expressions/index/var/param/matrix.wgsl.expected.msl
index 3826f12..a6e1fa4 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 float3 f(int i) {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  return m[i];
+  return m[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/param/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/var/param/matrix.wgsl.expected.spvasm
index 442670b..286a377 100644
--- a/test/tint/expressions/index/var/param/matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/param/matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -30,19 +31,23 @@
     %float_9 = OpConstant %float 9
          %20 = OpConstantComposite %v3float %float_7 %float_8 %float_9
          %11 = OpConstantComposite %mat3v3float %12 %16 %20
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_v3float = OpTypePointer Function %v3float
        %void = OpTypeVoid
-         %29 = OpTypeFunction %void
+         %34 = OpTypeFunction %void
           %f = OpFunction %v3float None %6
           %i = OpFunctionParameter %int
           %7 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %11
-         %24 = OpAccessChain %_ptr_Function_v3float %m %i
-         %26 = OpLoad %v3float %24 None
-               OpReturnValue %26
+         %25 = OpBitcast %uint %i
+         %26 = OpExtInst %uint %27 UMin %25 %uint_2
+         %29 = OpAccessChain %_ptr_Function_v3float %m %26
+         %31 = OpLoad %v3float %29 None
+               OpReturnValue %31
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %29
-         %30 = OpLabel
+%unused_entry_point = OpFunction %void None %34
+         %35 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.dxc.hlsl b/test/tint/expressions/index/var/param/vector.wgsl.expected.dxc.hlsl
index d046c84..4e84c0b 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.dxc.hlsl
@@ -5,5 +5,5 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.fxc.hlsl b/test/tint/expressions/index/var/param/vector.wgsl.expected.fxc.hlsl
index d046c84..4e84c0b 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.fxc.hlsl
@@ -5,5 +5,5 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.glsl b/test/tint/expressions/index/var/param/vector.wgsl.expected.glsl
index 9ad3700..9edd7e2 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.glsl
@@ -2,7 +2,7 @@
 
 float f(int i) {
   vec3 v = vec3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.dxc.hlsl
index adceace..dd18b2b 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,7 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.fxc.hlsl
index adceace..dd18b2b 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,7 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.msl b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.msl
index cceb94d..37240fe 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.ir.msl
@@ -3,5 +3,5 @@
 
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.msl b/test/tint/expressions/index/var/param/vector.wgsl.expected.msl
index 15f873e..59d1b8d 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.msl
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.msl
@@ -3,6 +3,6 @@
 using namespace metal;
 float f(int i) {
   float3 v = float3(1.0f, 2.0f, 3.0f);
-  return v[i];
+  return v[min(uint(i), 2u)];
 }
 
diff --git a/test/tint/expressions/index/var/param/vector.wgsl.expected.spvasm b/test/tint/expressions/index/var/param/vector.wgsl.expected.spvasm
index 17b1ca6..94f2e6d 100644
--- a/test/tint/expressions/index/var/param/vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/param/vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
+         %17 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -20,19 +21,23 @@
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
          %10 = OpConstantComposite %v3float %float_1 %float_2 %float_3
+       %uint = OpTypeInt 32 0
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
        %void = OpTypeVoid
-         %19 = OpTypeFunction %void
+         %24 = OpTypeFunction %void
           %f = OpFunction %float None %5
           %i = OpFunctionParameter %int
           %6 = OpLabel
           %v = OpVariable %_ptr_Function_v3float Function
                OpStore %v %10
-         %14 = OpAccessChain %_ptr_Function_float %v %i
-         %16 = OpLoad %float %14 None
-               OpReturnValue %16
+         %15 = OpBitcast %uint %i
+         %16 = OpExtInst %uint %17 UMin %15 %uint_2
+         %19 = OpAccessChain %_ptr_Function_float %v %16
+         %21 = OpLoad %float %19 None
+               OpReturnValue %21
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %19
-         %20 = OpLabel
+%unused_entry_point = OpFunction %void None %24
+         %25 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.glsl b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.glsl
index c254b04..90d245a 100644
--- a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 uint f() {
   S a = S(0, uint[4](0u, 0u, 0u, 0u));
-  return a.n[2];
+  return a.n[2u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.dxc.hlsl
index a5ab48c..5a62104 100644
--- a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)];
+  return a.n[2u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.fxc.hlsl
index a5ab48c..5a62104 100644
--- a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)];
+  return a.n[2u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.msl b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.msl
index 3892b5d..41b1223 100644
--- a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.ir.msl
@@ -20,5 +20,5 @@
 
 uint f() {
   S a = S{};
-  return a.n[2];
+  return a.n[2u];
 }
diff --git a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.spvasm b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.spvasm
index d7608fa..6d15c16 100644
--- a/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/struct_nested_array.wgsl.expected.spvasm
@@ -26,14 +26,14 @@
          %11 = OpConstantNull %S
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
          %19 = OpTypeFunction %void
           %f = OpFunction %uint None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_S Function
                OpStore %a %11
-         %12 = OpAccessChain %_ptr_Function_uint %a %uint_1 %int_2
+         %12 = OpAccessChain %_ptr_Function_uint %a %uint_1 %uint_2
          %16 = OpLoad %uint %12 None
                OpReturnValue %16
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.glsl b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.glsl
index 0c6c6c5..c3a9958 100644
--- a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.glsl
@@ -12,7 +12,7 @@
 
 uint f() {
   S a = S(0, T[4](T(uint[2](0u, 0u)), T(uint[2](0u, 0u)), T(uint[2](0u, 0u)), T(uint[2](0u, 0u))));
-  return a.n[2].k[1];
+  return a.n[2u].k[1u];
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
index e79f41d..e0e060a 100644
--- a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)].k[int(1)];
+  return a.n[2u].k[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
index e79f41d..e0e060a 100644
--- a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 
 uint f() {
   S a = (S)0;
-  return a.n[int(2)].k[int(1)];
+  return a.n[2u].k[1u];
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.msl b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.msl
index c1d91f1..1466b3b 100644
--- a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.ir.msl
@@ -24,5 +24,5 @@
 
 uint f() {
   S a = S{};
-  return a.n[2].k[1];
+  return a.n[2u].k[1u];
 }
diff --git a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.spvasm b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.spvasm
index fab35ed..fbab1ca 100644
--- a/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/struct_nested_multiple.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -33,20 +33,18 @@
          %14 = OpConstantNull %S
 %_ptr_Function_uint = OpTypePointer Function %uint
      %uint_1 = OpConstant %uint 1
-      %int_2 = OpConstant %int 2
      %uint_0 = OpConstant %uint 0
-      %int_1 = OpConstant %int 1
        %void = OpTypeVoid
-         %24 = OpTypeFunction %void
+         %22 = OpTypeFunction %void
           %f = OpFunction %uint None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_S Function
                OpStore %a %14
-         %15 = OpAccessChain %_ptr_Function_uint %a %uint_1 %int_2 %uint_0 %int_1
-         %21 = OpLoad %uint %15 None
-               OpReturnValue %21
+         %15 = OpAccessChain %_ptr_Function_uint %a %uint_1 %uint_2 %uint_0 %uint_1
+         %19 = OpLoad %uint %15 None
+               OpReturnValue %19
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %24
-         %25 = OpLabel
+%unused_entry_point = OpFunction %void None %22
+         %23 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.glsl b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.glsl
index c5bf8be..a28da5b 100644
--- a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.glsl
+++ b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.glsl
@@ -8,7 +8,7 @@
 
 float f() {
   S a = S(0, mat4(vec4(0.0f), vec4(0.0f), vec4(0.0f), vec4(0.0f)));
-  return a.n[2].y;
+  return a.n[2u].y;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
index 0a128c8..89ec140 100644
--- a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 float f() {
   S a = (S)0;
-  return a.n[int(2)].y;
+  return a.n[2u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
index 0a128c8..89ec140 100644
--- a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 float f() {
   S a = (S)0;
-  return a.n[int(2)].y;
+  return a.n[2u].y;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.msl b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.msl
index 0c60c32..0a2f120 100644
--- a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 
 float f() {
   S a = S{};
-  return a.n[2][1];
+  return a.n[2u][1u];
 }
diff --git a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.spvasm b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.spvasm
index 74b2dec..0a9aaee 100644
--- a/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/struct_with_matrix.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 25
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -28,21 +28,20 @@
 %_ptr_Function_v4float = OpTypePointer Function %v4float
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
-      %int_1 = OpConstant %int 1
        %void = OpTypeVoid
-         %23 = OpTypeFunction %void
+         %22 = OpTypeFunction %void
           %f = OpFunction %float None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_S Function
                OpStore %a %11
-         %12 = OpAccessChain %_ptr_Function_v4float %a %uint_1 %int_2
-         %17 = OpAccessChain %_ptr_Function_float %12 %int_1
-         %20 = OpLoad %float %17 None
-               OpReturnValue %20
+         %12 = OpAccessChain %_ptr_Function_v4float %a %uint_1 %uint_2
+         %17 = OpAccessChain %_ptr_Function_float %12 %uint_1
+         %19 = OpLoad %float %17 None
+               OpReturnValue %19
                OpFunctionEnd
-%unused_entry_point = OpFunction %void None %23
-         %24 = OpLabel
+%unused_entry_point = OpFunction %void None %22
+         %23 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.ir.msl b/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.ir.msl
index 558552b..831fd6b 100644
--- a/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.ir.msl
+++ b/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.ir.msl
@@ -8,5 +8,5 @@
 
 uint f() {
   S a = S{};
-  return a.n[2];
+  return a.n[2u];
 }
diff --git a/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.spvasm b/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.spvasm
index 5dba9a7..afca173 100644
--- a/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.spvasm
+++ b/test/tint/expressions/index/var/struct_with_vector.wgsl.expected.spvasm
@@ -25,7 +25,7 @@
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
      %uint_1 = OpConstant %uint 1
 %_ptr_Function_uint = OpTypePointer Function %uint
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %void = OpTypeVoid
          %20 = OpTypeFunction %void
           %f = OpFunction %uint None %3
@@ -33,7 +33,7 @@
           %a = OpVariable %_ptr_Function_S Function
                OpStore %a %10
          %11 = OpAccessChain %_ptr_Function_v3uint %a %uint_1
-         %14 = OpAccessChain %_ptr_Function_uint %11 %int_2
+         %14 = OpAccessChain %_ptr_Function_uint %11 %uint_2
          %17 = OpLoad %uint %14 None
                OpReturnValue %17
                OpFunctionEnd
diff --git a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.glsl b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.glsl
index 6d4e35c..32558d4 100644
--- a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.glsl
+++ b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.glsl
@@ -10,7 +10,7 @@
   int b = a_1.x;
   ivec4 c = a_1.zzyy;
   S d = S(vec3[3](vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  vec3 e = d.val[2].yzx;
+  vec3 e = d.val[2u].yzx;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.dxc.hlsl
index d04fb33..32b8918 100644
--- a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.dxc.hlsl
@@ -8,7 +8,7 @@
   int b = a_1.x;
   int4 c = a_1.zzyy;
   S d = (S)0;
-  float3 e = d.val[int(2)].yzx;
+  float3 e = d.val[2u].yzx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.fxc.hlsl
index d04fb33..32b8918 100644
--- a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.fxc.hlsl
@@ -8,7 +8,7 @@
   int b = a_1.x;
   int4 c = a_1.zzyy;
   S d = (S)0;
-  float3 e = d.val[int(2)].yzx;
+  float3 e = d.val[2u].yzx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.msl b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.msl
index 9e90281..73d3c17 100644
--- a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.msl
+++ b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.ir.msl
@@ -22,5 +22,5 @@
   int const b = a_1[0u];
   int4 const c = a_1.zzyy;
   S d = S{};
-  float3 const e = d.val[2].yzx;
+  float3 const e = d.val[2u].yzx;
 }
diff --git a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.spvasm b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.spvasm
index ef094ea..ffc993b 100644
--- a/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.spvasm
+++ b/test/tint/expressions/swizzle/read/swizzle.wgsl.expected.spvasm
@@ -35,7 +35,7 @@
 %_ptr_Function_S = OpTypePointer Function %S
          %24 = OpConstantNull %S
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
           %a = OpFunction %void None %3
           %4 = OpLabel
         %a_0 = OpVariable %_ptr_Function_v4int Function
@@ -46,7 +46,7 @@
          %15 = OpLoad %v4int %a_0 None
           %c = OpVectorShuffle %v4int %15 %15 2 2 1 1
                OpStore %d %24
-         %25 = OpAccessChain %_ptr_Function_v3float %d %uint_0 %int_2
+         %25 = OpAccessChain %_ptr_Function_v3float %d %uint_0 %uint_2
          %28 = OpLoad %v3float %25 None
           %e = OpVectorShuffle %v3float %28 %28 1 2 0
                OpReturn
diff --git a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.glsl b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.glsl
index dc1c0e1..5b0c681 100644
--- a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.glsl
+++ b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.glsl
@@ -10,7 +10,7 @@
   a_1[0u] = 1;
   a_1[2u] = 2;
   S d = S(vec3[3](vec3(0.0f), vec3(0.0f), vec3(0.0f)));
-  d.val[2][1u] = 3.0f;
+  d.val[2u][1u] = 3.0f;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.dxc.hlsl b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.dxc.hlsl
index fbc5020..669cc3e 100644
--- a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.dxc.hlsl
@@ -8,7 +8,7 @@
   a_1.x = int(1);
   a_1.z = int(2);
   S d = (S)0;
-  d.val[int(2)].y = 3.0f;
+  d.val[2u].y = 3.0f;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.fxc.hlsl b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.fxc.hlsl
index fbc5020..669cc3e 100644
--- a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.fxc.hlsl
@@ -8,7 +8,7 @@
   a_1.x = int(1);
   a_1.z = int(2);
   S d = (S)0;
-  d.val[int(2)].y = 3.0f;
+  d.val[2u].y = 3.0f;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.msl b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.msl
index c67d066..34a15ac 100644
--- a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.msl
+++ b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.ir.msl
@@ -22,5 +22,5 @@
   a_1[0u] = 1;
   a_1[2u] = 2;
   S d = S{};
-  d.val[2][1u] = 3.0f;
+  d.val[2u][1u] = 3.0f;
 }
diff --git a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.spvasm b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.spvasm
index 361e878..cd1bcca 100644
--- a/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.spvasm
+++ b/test/tint/expressions/swizzle/write/swizzle.wgsl.expected.spvasm
@@ -48,7 +48,7 @@
          %15 = OpAccessChain %_ptr_Function_int %a_0 %uint_2
                OpStore %15 %int_2 None
                OpStore %d %25
-         %26 = OpAccessChain %_ptr_Function_v3float %d %uint_0 %int_2
+         %26 = OpAccessChain %_ptr_Function_v3float %d %uint_0 %uint_2
          %28 = OpAccessChain %_ptr_Function_float %26 %uint_1
                OpStore %28 %float_3 None
                OpReturn
diff --git a/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.ir.msl b/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.ir.msl
index e23ac2f..6a9c791 100644
--- a/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.ir.msl
+++ b/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.ir.msl
@@ -18,6 +18,9 @@
   /* 0x0008 */ tint_array<int8_t, 8> tint_pad;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct SSBO {
   /* 0x0000 */ tint_array<strided_arr, 2> m;
 };
@@ -44,6 +47,7 @@
     uint v_1 = 0u;
     v_1 = 0u;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_2 = v_1;
       if ((v_2 >= 2u)) {
         break;
diff --git a/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.msl b/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.msl
index d387e3d..7c2ac9a 100644
--- a/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.msl
+++ b/test/tint/layout/storage/mat2x2/stride/16.spvasm.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct strided_arr {
   /* 0x0000 */ float2 el;
   /* 0x0008 */ tint_array<int8_t, 8> tint_pad;
@@ -40,7 +43,8 @@
 
 void assign_and_preserve_padding(device tint_array<strided_arr, 2>* const dest, tint_array<strided_arr, 2> value) {
   for(uint i = 0u; (i < 2u); i = (i + 1u)) {
-    assign_and_preserve_padding_1(&((*(dest))[i]), value[i]);
+    TINT_ISOLATE_UB(tint_volatile_false);
+    assign_and_preserve_padding_1(&((*(dest))[min(i, 1u)]), value[min(i, 1u)]);
   }
 }
 
diff --git a/test/tint/loops/continue_in_switch.wgsl.expected.msl b/test/tint/loops/continue_in_switch.wgsl.expected.msl
index 61eeef4..93cfb99 100644
--- a/test/tint/loops/continue_in_switch.wgsl.expected.msl
+++ b/test/tint/loops/continue_in_switch.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void f() {
   bool tint_continue = false;
   for(int i = 0; (i < 4); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i) {
       case 0: {
diff --git a/test/tint/loops/continue_in_switch_robustness.wgsl b/test/tint/loops/continue_in_switch_robustness.wgsl
index 78431c9..475964a 100644
--- a/test/tint/loops/continue_in_switch_robustness.wgsl
+++ b/test/tint/loops/continue_in_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn f() {
     for (var i : i32 = 0; i < 4; i = i + 1) {
diff --git a/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.ir.msl b/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.ir.msl
index 93ba5b0..d9fbf58 100644
--- a/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.ir.msl
+++ b/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       bool tint_continue = false;
       switch(i) {
         case 0:
diff --git a/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.msl b/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.msl
index cbdd77e..e944287 100644
--- a/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.msl
+++ b/test/tint/loops/continue_in_switch_with_breakif.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void f() {
   int i = 0;
   bool tint_continue = false;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i) {
       case 0: {
diff --git a/test/tint/loops/continue_in_switch_with_breakif_robustness.wgsl b/test/tint/loops/continue_in_switch_with_breakif_robustness.wgsl
index 7e91c7e..0b65b9c 100644
--- a/test/tint/loops/continue_in_switch_with_breakif_robustness.wgsl
+++ b/test/tint/loops/continue_in_switch_with_breakif_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn f() {
     var i : i32 = 0;
diff --git a/test/tint/loops/loop.wgsl.expected.ir.msl b/test/tint/loops/loop.wgsl.expected.ir.msl
index e7096c8..d5e5fa2 100644
--- a/test/tint/loops/loop.wgsl.expected.ir.msl
+++ b/test/tint/loops/loop.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       if ((i > 4)) {
         return i;
diff --git a/test/tint/loops/loop.wgsl.expected.msl b/test/tint/loops/loop.wgsl.expected.msl
index 0fd592a..e641dc5 100644
--- a/test/tint/loops/loop.wgsl.expected.msl
+++ b/test/tint/loops/loop.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
     if ((i > 4)) {
       return i;
diff --git a/test/tint/loops/loop_robustness.wgsl b/test/tint/loops/loop_robustness.wgsl
index ba0aecf..63cd5ec 100644
--- a/test/tint/loops/loop_robustness.wgsl
+++ b/test/tint/loops/loop_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     loop {
diff --git a/test/tint/loops/loop_with_break_if.wgsl.expected.ir.msl b/test/tint/loops/loop_with_break_if.wgsl.expected.ir.msl
index fafe76e..b32bbacb 100644
--- a/test/tint/loops/loop_with_break_if.wgsl.expected.ir.msl
+++ b/test/tint/loops/loop_with_break_if.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i > 4)) {
         return i;
       }
diff --git a/test/tint/loops/loop_with_break_if.wgsl.expected.msl b/test/tint/loops/loop_with_break_if.wgsl.expected.msl
index 502c3eb..e97f8c6 100644
--- a/test/tint/loops/loop_with_break_if.wgsl.expected.msl
+++ b/test/tint/loops/loop_with_break_if.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i > 4)) {
       return i;
     }
diff --git a/test/tint/loops/loop_with_break_if_robustness.wgsl b/test/tint/loops/loop_with_break_if_robustness.wgsl
index e8dab8c..d97cc69 100644
--- a/test/tint/loops/loop_with_break_if_robustness.wgsl
+++ b/test/tint/loops/loop_with_break_if_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     loop {
diff --git a/test/tint/loops/loop_with_continuing.wgsl.expected.ir.msl b/test/tint/loops/loop_with_continuing.wgsl.expected.ir.msl
index 4a2baf2..e21dbe4 100644
--- a/test/tint/loops/loop_with_continuing.wgsl.expected.ir.msl
+++ b/test/tint/loops/loop_with_continuing.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i > 4)) {
         return i;
       }
diff --git a/test/tint/loops/loop_with_continuing.wgsl.expected.msl b/test/tint/loops/loop_with_continuing.wgsl.expected.msl
index c1f831d..78da287 100644
--- a/test/tint/loops/loop_with_continuing.wgsl.expected.msl
+++ b/test/tint/loops/loop_with_continuing.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i > 4)) {
       return i;
     }
diff --git a/test/tint/loops/loop_with_continuing_robustness.wgsl b/test/tint/loops/loop_with_continuing_robustness.wgsl
index b8c588e..862a53d 100644
--- a/test/tint/loops/loop_with_continuing_robustness.wgsl
+++ b/test/tint/loops/loop_with_continuing_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     loop {
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.msl b/test/tint/loops/multiple_continues.wgsl.expected.msl
index 8dc7a34..73cc270 100644
--- a/test/tint/loops/multiple_continues.wgsl.expected.msl
+++ b/test/tint/loops/multiple_continues.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   bool tint_continue = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i) {
       case 0: {
diff --git a/test/tint/loops/multiple_continues_robustness.wgsl b/test/tint/loops/multiple_continues_robustness.wgsl
index 87d2142..a57f773 100644
--- a/test/tint/loops/multiple_continues_robustness.wgsl
+++ b/test/tint/loops/multiple_continues_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   for (var i = 0; i < 2; i += 1) {
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.msl b/test/tint/loops/multiple_switch.wgsl.expected.msl
index 5d1af22..8dd8fe4 100644
--- a/test/tint/loops/multiple_switch.wgsl.expected.msl
+++ b/test/tint/loops/multiple_switch.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   int i = 0;
   bool tint_continue = false;
   for(int i_1 = 0; (i_1 < 2); i_1 = as_type<int>((as_type<uint>(i_1) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i_1) {
       case 0: {
diff --git a/test/tint/loops/multiple_switch_robustness.wgsl b/test/tint/loops/multiple_switch_robustness.wgsl
index b9ac712..b3acc1f 100644
--- a/test/tint/loops/multiple_switch_robustness.wgsl
+++ b/test/tint/loops/multiple_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   var i = 0;
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
index 0033d1e..3090c93 100644
--- a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 2)) {
       } else {
         break;
@@ -12,6 +16,7 @@
       {
         int j = 0;
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false_1)
           if ((j < 2)) {
           } else {
             break;
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl
index c322503..5b0f057 100644
--- a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl
@@ -1,10 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     bool tint_continue = false;
     for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       tint_continue = false;
       switch(i) {
         case 0: {
diff --git a/test/tint/loops/nested_loop_loop_switch_robustness.wgsl b/test/tint/loops/nested_loop_loop_switch_robustness.wgsl
index adddf2d..f925971 100644
--- a/test/tint/loops/nested_loop_loop_switch_robustness.wgsl
+++ b/test/tint/loops/nested_loop_loop_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   for (var i = 0; i < 2; i += 2) {
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
index 3ab376f..caf7752 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 2)) {
       } else {
         break;
@@ -16,6 +20,7 @@
           {
             int j = 0;
             while(true) {
+              TINT_ISOLATE_UB(tint_volatile_false_1)
               if ((j < 2)) {
               } else {
                 break;
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl
index d5e0375..0455c39 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl
@@ -1,14 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   bool tint_continue_1 = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue_1 = false;
     switch(i) {
       case 0: {
         bool tint_continue = false;
         for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+          TINT_ISOLATE_UB(tint_volatile_false_1);
           tint_continue = false;
           switch(j) {
             case 0: {
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_robustness.wgsl b/test/tint/loops/nested_loop_switch_loop_switch_robustness.wgsl
index cf31edc..020d6df 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch_robustness.wgsl
+++ b/test/tint/loops/nested_loop_switch_loop_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   for (var i = 0; i < 2; i += 2) {
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
index b1bbdfa..0bb8ce8 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
@@ -1,11 +1,15 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   int k = 0;
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 2)) {
       } else {
         break;
@@ -17,6 +21,7 @@
           {
             int j = 0;
             while(true) {
+              TINT_ISOLATE_UB(tint_volatile_false_1)
               if ((j < 2)) {
               } else {
                 break;
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl
index 3e06efd..3cfa334 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl
@@ -1,15 +1,21 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   int k = 0;
   bool tint_continue_1 = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue_1 = false;
     switch(i) {
       case 0: {
         bool tint_continue = false;
         for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+          TINT_ISOLATE_UB(tint_volatile_false_1);
           tint_continue = false;
           switch(j) {
             case 0: {
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch_robustness.wgsl b/test/tint/loops/nested_loop_switch_loop_switch_switch_robustness.wgsl
index fa780e1..c152681 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch_switch_robustness.wgsl
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   var k = 0;
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
index 877f5e5..208823c 100644
--- a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
@@ -1,11 +1,15 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   int j = 0;
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 2)) {
       } else {
         break;
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl
index 8fb8424..8564b09 100644
--- a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl
@@ -1,10 +1,15 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   int j = 0;
   bool tint_continue = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i) {
       case 0: {
diff --git a/test/tint/loops/nested_loop_switch_switch_robustness.wgsl b/test/tint/loops/nested_loop_switch_switch_robustness.wgsl
index 58660c0..9949f96 100644
--- a/test/tint/loops/nested_loop_switch_switch_robustness.wgsl
+++ b/test/tint/loops/nested_loop_switch_switch_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   var j = 0;
diff --git a/test/tint/loops/nested_loops.wgsl.expected.ir.msl b/test/tint/loops/nested_loops.wgsl.expected.ir.msl
index 2803e68..daa4a15 100644
--- a/test/tint/loops/nested_loops.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loops.wgsl.expected.ir.msl
@@ -1,17 +1,22 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   int j = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       if ((i > 4)) {
         return 1;
       }
       {
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false_1)
           j = as_type<int>((as_type<uint>(j) + as_type<uint>(1)));
           if ((j > 4)) {
             return 2;
diff --git a/test/tint/loops/nested_loops.wgsl.expected.msl b/test/tint/loops/nested_loops.wgsl.expected.msl
index 17ea289..d3f2bcf 100644
--- a/test/tint/loops/nested_loops.wgsl.expected.msl
+++ b/test/tint/loops/nested_loops.wgsl.expected.msl
@@ -1,15 +1,21 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   int j = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
     if ((i > 4)) {
       return 1;
     }
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       j = as_type<int>((as_type<uint>(j) + as_type<uint>(1)));
       if ((j > 4)) {
         return 2;
diff --git a/test/tint/loops/nested_loops_robustness.wgsl b/test/tint/loops/nested_loops_robustness.wgsl
index d07b42f..3a093e7 100644
--- a/test/tint/loops/nested_loops_robustness.wgsl
+++ b/test/tint/loops/nested_loops_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     var j : i32;
diff --git a/test/tint/loops/nested_loops_with_continuing.wgsl.expected.ir.msl b/test/tint/loops/nested_loops_with_continuing.wgsl.expected.ir.msl
index 33045de..8d2609f 100644
--- a/test/tint/loops/nested_loops_with_continuing.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loops_with_continuing.wgsl.expected.ir.msl
@@ -1,16 +1,21 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   int j = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i > 4)) {
         return 1;
       }
       {
         while(true) {
+          TINT_ISOLATE_UB(tint_volatile_false_1)
           if ((j > 4)) {
             return 2;
           }
diff --git a/test/tint/loops/nested_loops_with_continuing.wgsl.expected.msl b/test/tint/loops/nested_loops_with_continuing.wgsl.expected.msl
index cbb1c0f..d0155f3 100644
--- a/test/tint/loops/nested_loops_with_continuing.wgsl.expected.msl
+++ b/test/tint/loops/nested_loops_with_continuing.wgsl.expected.msl
@@ -1,14 +1,20 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   int j = 0;
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i > 4)) {
       return 1;
     }
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false_1);
       if ((j > 4)) {
         return 2;
       }
diff --git a/test/tint/loops/nested_loops_with_continuing_robustness.wgsl b/test/tint/loops/nested_loops_with_continuing_robustness.wgsl
index 9c12a05..9fa77ef 100644
--- a/test/tint/loops/nested_loops_with_continuing_robustness.wgsl
+++ b/test/tint/loops/nested_loops_with_continuing_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     var j : i32;
diff --git a/test/tint/loops/single_continue.wgsl.expected.msl b/test/tint/loops/single_continue.wgsl.expected.msl
index f547474..d095344 100644
--- a/test/tint/loops/single_continue.wgsl.expected.msl
+++ b/test/tint/loops/single_continue.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol() {
   bool tint_continue = false;
   for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     tint_continue = false;
     switch(i) {
       case 0: {
diff --git a/test/tint/loops/single_continue_robustness.wgsl b/test/tint/loops/single_continue_robustness.wgsl
index 1e0150b..d59d2fa 100644
--- a/test/tint/loops/single_continue_robustness.wgsl
+++ b/test/tint/loops/single_continue_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 @compute @workgroup_size(1)
 fn main() {
   for (var i = 0; i < 2; i += 1) {
diff --git a/test/tint/loops/while.wgsl.expected.ir.msl b/test/tint/loops/while.wgsl.expected.ir.msl
index d5d4d6f..62623af 100644
--- a/test/tint/loops/while.wgsl.expected.ir.msl
+++ b/test/tint/loops/while.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 4)) {
       } else {
         break;
diff --git a/test/tint/loops/while.wgsl.expected.msl b/test/tint/loops/while.wgsl.expected.msl
index bd8f450..1d8717d 100644
--- a/test/tint/loops/while.wgsl.expected.msl
+++ b/test/tint/loops/while.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   while((i < 4)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
   }
   return i;
diff --git a/test/tint/loops/while_robustness.wgsl b/test/tint/loops/while_robustness.wgsl
index 413a848..e2694d0 100644
--- a/test/tint/loops/while_robustness.wgsl
+++ b/test/tint/loops/while_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     while (i < 4) {
diff --git a/test/tint/loops/while_with_continue.wgsl.expected.ir.msl b/test/tint/loops/while_with_continue.wgsl.expected.ir.msl
index d5d4d6f..62623af 100644
--- a/test/tint/loops/while_with_continue.wgsl.expected.ir.msl
+++ b/test/tint/loops/while_with_continue.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 4)) {
       } else {
         break;
diff --git a/test/tint/loops/while_with_continue.wgsl.expected.msl b/test/tint/loops/while_with_continue.wgsl.expected.msl
index 7fee4b0..6827095 100644
--- a/test/tint/loops/while_with_continue.wgsl.expected.msl
+++ b/test/tint/loops/while_with_continue.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int f() {
   int i = 0;
   while((i < 4)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
     continue;
   }
diff --git a/test/tint/loops/while_with_continue_robustness.wgsl b/test/tint/loops/while_with_continue_robustness.wgsl
index c44bf0f..8193a02 100644
--- a/test/tint/loops/while_with_continue_robustness.wgsl
+++ b/test/tint/loops/while_with_continue_robustness.wgsl
@@ -1,4 +1,3 @@
-// flags: --transform robustness
 fn f() -> i32 {
     var i : i32;
     while (i < 4) {
diff --git a/test/tint/out_of_order_decls/array/alias.wgsl.expected.glsl b/test/tint/out_of_order_decls/array/alias.wgsl.expected.glsl
index af466ef..67922a1 100644
--- a/test/tint/out_of_order_decls/array/alias.wgsl.expected.glsl
+++ b/test/tint/out_of_order_decls/array/alias.wgsl.expected.glsl
@@ -4,5 +4,5 @@
 
 int A[4] = int[4](0, 0, 0, 0);
 void main() {
-  A[0] = 1;
+  A[0u] = 1;
 }
diff --git a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.dxc.hlsl b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.dxc.hlsl
index 3f50913..61915b7 100644
--- a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.dxc.hlsl
@@ -1,6 +1,6 @@
 
 static int A[4] = (int[4])0;
 void f() {
-  A[int(0)] = int(1);
+  A[0u] = int(1);
 }
 
diff --git a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.fxc.hlsl b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.fxc.hlsl
index 3f50913..61915b7 100644
--- a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.fxc.hlsl
@@ -1,6 +1,6 @@
 
 static int A[4] = (int[4])0;
 void f() {
-  A[int(0)] = int(1);
+  A[0u] = int(1);
 }
 
diff --git a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.msl b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.msl
index 79a009b..9e800da 100644
--- a/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.msl
+++ b/test/tint/out_of_order_decls/array/alias.wgsl.expected.ir.msl
@@ -20,5 +20,5 @@
 fragment void f() {
   thread tint_array<int, 4> A = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.A=(&A)};
-  (*tint_module_vars.A)[0] = 1;
+  (*tint_module_vars.A)[0u] = 1;
 }
diff --git a/test/tint/out_of_order_decls/array/alias.wgsl.expected.spvasm b/test/tint/out_of_order_decls/array/alias.wgsl.expected.spvasm
index 14adac0..a244c58 100644
--- a/test/tint/out_of_order_decls/array/alias.wgsl.expected.spvasm
+++ b/test/tint/out_of_order_decls/array/alias.wgsl.expected.spvasm
@@ -20,11 +20,11 @@
        %void = OpTypeVoid
          %10 = OpTypeFunction %void
 %_ptr_Private_int = OpTypePointer Private %int
-      %int_0 = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
       %int_1 = OpConstant %int 1
           %f = OpFunction %void None %10
          %11 = OpLabel
-         %12 = OpAccessChain %_ptr_Private_int %A %int_0
+         %12 = OpAccessChain %_ptr_Private_int %A %uint_0
                OpStore %12 %int_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/out_of_order_decls/array/struct.wgsl.expected.glsl b/test/tint/out_of_order_decls/array/struct.wgsl.expected.glsl
index 4886dfa..db64394 100644
--- a/test/tint/out_of_order_decls/array/struct.wgsl.expected.glsl
+++ b/test/tint/out_of_order_decls/array/struct.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 
 S A[4] = S[4](S(0), S(0), S(0), S(0));
 void main() {
-  A[0] = S(1);
+  A[0u] = S(1);
 }
diff --git a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.dxc.hlsl b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.dxc.hlsl
index 389b701..6128e7b 100644
--- a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 static S A[4] = (S[4])0;
 void f() {
   S v = {int(1)};
-  A[int(0)] = v;
+  A[0u] = v;
 }
 
diff --git a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.fxc.hlsl b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.fxc.hlsl
index 389b701..6128e7b 100644
--- a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 static S A[4] = (S[4])0;
 void f() {
   S v = {int(1)};
-  A[int(0)] = v;
+  A[0u] = v;
 }
 
diff --git a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.msl b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.msl
index 6ba8eb3..a261da6 100644
--- a/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.msl
+++ b/test/tint/out_of_order_decls/array/struct.wgsl.expected.ir.msl
@@ -24,5 +24,5 @@
 fragment void f() {
   thread tint_array<S, 4> A = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.A=(&A)};
-  (*tint_module_vars.A)[0] = S{.m=1};
+  (*tint_module_vars.A)[0u] = S{.m=1};
 }
diff --git a/test/tint/out_of_order_decls/array/struct.wgsl.expected.spvasm b/test/tint/out_of_order_decls/array/struct.wgsl.expected.spvasm
index af20b5b..04c59cd 100644
--- a/test/tint/out_of_order_decls/array/struct.wgsl.expected.spvasm
+++ b/test/tint/out_of_order_decls/array/struct.wgsl.expected.spvasm
@@ -24,12 +24,12 @@
        %void = OpTypeVoid
          %11 = OpTypeFunction %void
 %_ptr_Private_S = OpTypePointer Private %S
-      %int_0 = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
       %int_1 = OpConstant %int 1
          %16 = OpConstantComposite %S %int_1
           %f = OpFunction %void None %11
          %12 = OpLabel
-         %13 = OpAccessChain %_ptr_Private_S %A %int_0
+         %13 = OpAccessChain %_ptr_Private_S %A %uint_0
                OpStore %13 %16 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/access/matrix.spvasm.expected.glsl b/test/tint/ptr_ref/access/matrix.spvasm.expected.glsl
index 3303f50..3704776 100644
--- a/test/tint/ptr_ref/access/matrix.spvasm.expected.glsl
+++ b/test/tint/ptr_ref/access/matrix.spvasm.expected.glsl
@@ -3,7 +3,7 @@
 void main_1() {
   mat3 m = mat3(vec3(0.0f), vec3(0.0f), vec3(0.0f));
   m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  m[1] = vec3(5.0f);
+  m[1u] = vec3(5.0f);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.dxc.hlsl b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.dxc.hlsl
index 8704264..c18911c 100644
--- a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.dxc.hlsl
@@ -2,7 +2,7 @@
 void main_1() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
   m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  m[int(1)] = (5.0f).xxx;
+  m[1u] = (5.0f).xxx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.fxc.hlsl b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.fxc.hlsl
index 8704264..c18911c 100644
--- a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.fxc.hlsl
@@ -2,7 +2,7 @@
 void main_1() {
   float3x3 m = float3x3((0.0f).xxx, (0.0f).xxx, (0.0f).xxx);
   m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  m[int(1)] = (5.0f).xxx;
+  m[1u] = (5.0f).xxx;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.msl b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.msl
index 6612e0d..d1235e7 100644
--- a/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.msl
+++ b/test/tint/ptr_ref/access/matrix.spvasm.expected.ir.msl
@@ -4,7 +4,7 @@
 void main_1() {
   float3x3 m = float3x3(float3(0.0f), float3(0.0f), float3(0.0f));
   m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  m[1] = float3(5.0f);
+  m[1u] = float3(5.0f);
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_ref/access/matrix.spvasm.expected.spvasm b/test/tint/ptr_ref/access/matrix.spvasm.expected.spvasm
index 8a41cc4..6267de1 100644
--- a/test/tint/ptr_ref/access/matrix.spvasm.expected.spvasm
+++ b/test/tint/ptr_ref/access/matrix.spvasm.expected.spvasm
@@ -31,15 +31,15 @@
          %20 = OpConstantComposite %v3float %float_7 %float_8 %float_9
          %11 = OpConstantComposite %mat3v3float %12 %16 %20
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
          %28 = OpConstantComposite %v3float %float_5 %float_5 %float_5
      %main_1 = OpFunction %void None %3
           %4 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %10
                OpStore %m %11 None
-         %24 = OpAccessChain %_ptr_Function_v3float %m %int_1
+         %24 = OpAccessChain %_ptr_Function_v3float %m %uint_1
                OpStore %24 %28 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/access/matrix.wgsl.expected.glsl b/test/tint/ptr_ref/access/matrix.wgsl.expected.glsl
index 6f4fd8d..d75f343 100644
--- a/test/tint/ptr_ref/access/matrix.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/access/matrix.wgsl.expected.glsl
@@ -3,5 +3,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
-  m[1] = vec3(5.0f);
+  m[1u] = vec3(5.0f);
 }
diff --git a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.dxc.hlsl
index d9c180e..38eb901 100644
--- a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.dxc.hlsl
@@ -2,6 +2,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  m[int(1)] = (5.0f).xxx;
+  m[1u] = (5.0f).xxx;
 }
 
diff --git a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.fxc.hlsl
index d9c180e..38eb901 100644
--- a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.fxc.hlsl
@@ -2,6 +2,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  m[int(1)] = (5.0f).xxx;
+  m[1u] = (5.0f).xxx;
 }
 
diff --git a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.msl b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.msl
index f50b494..6d62f58 100644
--- a/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/access/matrix.wgsl.expected.ir.msl
@@ -3,6 +3,6 @@
 
 kernel void tint_symbol() {
   float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
-  thread float3* const v = (&m[1]);
+  thread float3* const v = (&m[1u]);
   (*v) = float3(5.0f);
 }
diff --git a/test/tint/ptr_ref/access/matrix.wgsl.expected.spvasm b/test/tint/ptr_ref/access/matrix.wgsl.expected.spvasm
index e0e8016..84f608d 100644
--- a/test/tint/ptr_ref/access/matrix.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/access/matrix.wgsl.expected.spvasm
@@ -30,14 +30,14 @@
          %19 = OpConstantComposite %v3float %float_7 %float_8 %float_9
          %10 = OpConstantComposite %mat3v3float %11 %15 %19
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
+       %uint = OpTypeInt 32 0
+     %uint_1 = OpConstant %uint 1
          %27 = OpConstantComposite %v3float %float_5 %float_5 %float_5
        %main = OpFunction %void None %3
           %4 = OpLabel
           %m = OpVariable %_ptr_Function_mat3v3float Function
                OpStore %m %10
-          %v = OpAccessChain %_ptr_Function_v3float %m %int_1
+          %v = OpAccessChain %_ptr_Function_v3float %m %uint_1
                OpStore %v %27 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.glsl
index 35a0051..e5b07a9 100644
--- a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   str F[4] = str[4](str(0), str(0), str(0), str(0));
-  str r = func(F[2]);
+  str r = func(F[2u]);
 }
diff --git a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 7c983a6..a540949 100644
--- a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   str F[4] = (str[4])0;
-  str r = func(F[int(2)]);
+  str r = func(F[2u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 7c983a6..a540949 100644
--- a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   str F[4] = (str[4])0;
-  str r = func(F[int(2)]);
+  str r = func(F[2u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.msl
index f747a73..44f25d0 100644
--- a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.ir.msl
@@ -23,5 +23,5 @@
 
 kernel void tint_symbol() {
   tint_array<str, 4> F = {};
-  str const r = func((&F[2]));
+  str const r = func((&F[2u]));
 }
diff --git a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.spvasm
index 148333b..7005d45 100644
--- a/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/function/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -31,7 +31,7 @@
        %void = OpTypeVoid
          %20 = OpTypeFunction %void
          %23 = OpConstantNull %_arr_str_uint_4
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %str None %12
 %pointer_root = OpFunctionParameter %_ptr_Function__arr_str_uint_4
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -44,8 +44,7 @@
        %main = OpFunction %void None %20
          %21 = OpLabel
           %F = OpVariable %_ptr_Function__arr_str_uint_4 Function %23
-         %24 = OpBitcast %uint %int_2
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %24
-          %r = OpFunctionCall %str %func %F %26
+         %24 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+          %r = OpFunctionCall %str %func %F %24
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 7422123..641e3e2 100644
--- a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2 F = mat2(vec2(0.0f), vec2(0.0f));
-  vec2 r = func(F[1]);
+  vec2 r = func(F[1u]);
 }
diff --git a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 330e9ea..cb73e7f 100644
--- a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x2 F = float2x2((0.0f).xx, (0.0f).xx);
-  float2 r = func(F[int(1)]);
+  float2 r = func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 330e9ea..cb73e7f 100644
--- a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x2 F = float2x2((0.0f).xx, (0.0f).xx);
-  float2 r = func(F[int(1)]);
+  float2 r = func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 44a80e4..70cd3ec 100644
--- a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -7,5 +7,5 @@
 
 kernel void tint_symbol() {
   float2x2 F = float2x2(0.0f);
-  float2 const r = func((&F[1]));
+  float2 const r = func((&F[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index 64449c9..56d6069 100644
--- a/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
        %void = OpTypeVoid
          %19 = OpTypeFunction %void
          %22 = OpConstantNull %mat2v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v2float None %11
 %pointer_root = OpFunctionParameter %_ptr_Function_mat2v2float
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -40,8 +38,7 @@
        %main = OpFunction %void None %19
          %20 = OpLabel
           %F = OpVariable %_ptr_Function_mat2v2float Function %22
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %v2float %func %F %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v2float %func %F %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 002fb37..d5d881d 100644
--- a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 F = mat2x4(vec4(0.0f), vec4(0.0f));
-  vec4 r = func(F[1]);
+  vec4 r = func(F[1u]);
 }
diff --git a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index e898997..8dc1f85 100644
--- a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 F = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  float4 r = func(F[int(1)]);
+  float4 r = func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index e898997..8dc1f85 100644
--- a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 F = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  float4 r = func(F[int(1)]);
+  float4 r = func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index 6abeaa0..2e99e08 100644
--- a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -7,5 +7,5 @@
 
 kernel void tint_symbol() {
   float2x4 F = float2x4(0.0f);
-  float4 const r = func((&F[1]));
+  float4 const r = func((&F[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 371cb6d..e4837b0 100644
--- a/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
        %void = OpTypeVoid
          %19 = OpTypeFunction %void
          %22 = OpConstantNull %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v4float None %11
 %pointer_root = OpFunctionParameter %_ptr_Function_mat2v4float
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -40,8 +38,7 @@
        %main = OpFunction %void None %19
          %20 = OpLabel
           %F = OpVariable %_ptr_Function_mat2v4float Function %22
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %v4float %func %F %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v4float %func %F %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.glsl
index d5fbe02..fde5f96 100644
--- a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  str r = func(P[2]);
+  str r = func(P[2u]);
 }
diff --git a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 883fe15..33c8958 100644
--- a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  str r = func(P[int(2)]);
+  str r = func(P[2u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 883fe15..33c8958 100644
--- a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  str r = func(P[int(2)]);
+  str r = func(P[2u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.msl
index caaa21f..22339aa 100644
--- a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.ir.msl
@@ -28,5 +28,5 @@
 kernel void tint_symbol() {
   thread tint_array<str, 4> P = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  str const r = func((&(*tint_module_vars.P)[2]));
+  str const r = func((&(*tint_module_vars.P)[2u]));
 }
diff --git a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.spvasm
index 5bdbc8f..171caf0a 100644
--- a/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/private/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -31,7 +31,7 @@
 %_ptr_Private_str = OpTypePointer Private %str
        %void = OpTypeVoid
          %21 = OpTypeFunction %void
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %str None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -42,8 +42,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_2
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %str %func %25
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+          %r = OpFunctionCall %str %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 4cd1e6d..7c7fd7c 100644
--- a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec2 r = func(P[1]);
+  vec2 r = func(P[1u]);
 }
diff --git a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 3e9741c..b14a291 100644
--- a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  float2 r = func(P[int(1)]);
+  float2 r = func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 3e9741c..b14a291 100644
--- a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  float2 r = func(P[int(1)]);
+  float2 r = func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index f3f415e..a32ddb0 100644
--- a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -12,5 +12,5 @@
 kernel void tint_symbol() {
   thread float2x2 P = float2x2(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  float2 const r = func((&(*tint_module_vars.P)[1]));
+  float2 const r = func((&(*tint_module_vars.P)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index 949fbdf..b7da96e 100644
--- a/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
 %_ptr_Private_v2float = OpTypePointer Private %v2float
        %void = OpTypeVoid
          %20 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v2float None %12
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %13 = OpLabel
@@ -38,8 +36,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %20
          %21 = OpLabel
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %22
-          %r = OpFunctionCall %v2float %func %25
+         %22 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v2float %func %22
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
index f8863ef..c7a49ba 100644
--- a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec4 r = func(P[1]);
+  vec4 r = func(P[1u]);
 }
diff --git a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index 937c624..39f036f 100644
--- a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  float4 r = func(P[int(1)]);
+  float4 r = func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index 937c624..39f036f 100644
--- a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  float4 r = func(P[int(1)]);
+  float4 r = func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index 77c2b0c..658ea65 100644
--- a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -12,5 +12,5 @@
 kernel void tint_symbol() {
   thread float2x4 P = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  float4 const r = func((&(*tint_module_vars.P)[1]));
+  float4 const r = func((&(*tint_module_vars.P)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index d9bb911..f4c4395 100644
--- a/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
 %_ptr_Private_v4float = OpTypePointer Private %v4float
        %void = OpTypeVoid
          %20 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v4float None %12
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %13 = OpLabel
@@ -38,8 +36,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %20
          %21 = OpLabel
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %22
-          %r = OpFunctionCall %v4float %func %25
+         %22 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v4float %func %22
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.glsl
index b74a9f4..271d8fd 100644
--- a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.glsl
@@ -14,5 +14,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  str r = func(uint[1](uint(2)));
+  str r = func(uint[1](2u));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 9b159eb..d7c6d52 100644
--- a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -16,7 +16,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_3[1] = {uint(int(2))};
+  uint v_3[1] = {2u};
   str r = func(v_3);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 9b159eb..d7c6d52 100644
--- a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -16,7 +16,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_3[1] = {uint(int(2))};
+  uint v_3[1] = {2u};
   str r = func(v_3);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.msl
index 621667c..ca042b30 100644
--- a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.ir.msl
@@ -27,5 +27,5 @@
 
 kernel void tint_symbol(const device tint_array<str, 4>* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  str const r = func((&(*tint_module_vars.S)[2]));
+  str const r = func((&(*tint_module_vars.S)[2u]));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.spvasm
index f5dcb52..6860c96 100644
--- a/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/storage/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,7 +38,7 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %22 = OpTypeFunction %void
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %str None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -49,8 +49,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %22
          %23 = OpLabel
-         %24 = OpBitcast %uint %int_2
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %24
-          %r = OpFunctionCall %str %func %26
+         %24 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+          %r = OpFunctionCall %str %func %24
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
index e35d112..66db30a 100644
--- a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec2 r = func(uint[1](uint(1)));
+  vec2 r = func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index cfb8784..f19a39e 100644
--- a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float2 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index cfb8784..f19a39e 100644
--- a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float2 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 013ae36..ed00a06 100644
--- a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(const device float2x2* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  float2 const r = func((&(*tint_module_vars.S)[1]));
+  float2 const r = func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index f6d99d6..9759888 100644
--- a/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,8 +35,6 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %21 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v2float None %12
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %13 = OpLabel
@@ -47,8 +45,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %v2float %func %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v2float %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 2f2a803..92ae529 100644
--- a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec4 r = func(uint[1](uint(1)));
+  vec4 r = func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index daafc36..b52f504 100644
--- a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float4 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index daafc36..b52f504 100644
--- a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float4 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index 690f075..49f3edc 100644
--- a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(const device float2x4* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  float4 const r = func((&(*tint_module_vars.S)[1]));
+  float4 const r = func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 999ad3a..23d8418 100644
--- a/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,8 +35,6 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %21 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v4float None %12
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %13 = OpLabel
@@ -47,8 +45,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %v4float %func %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v4float %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.glsl
index a79c8cc..24f8cb4 100644
--- a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.glsl
@@ -14,5 +14,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  str r = func(uint[1](uint(2)));
+  str r = func(uint[1](2u));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 5be51ef..3bcc911 100644
--- a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -18,7 +18,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_3[1] = {uint(int(2))};
+  uint v_3[1] = {2u};
   str r = func(v_3);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 5be51ef..3bcc911 100644
--- a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -18,7 +18,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_3[1] = {uint(int(2))};
+  uint v_3[1] = {2u};
   str r = func(v_3);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.msl
index 5c99fa3..28234f4 100644
--- a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.ir.msl
@@ -27,5 +27,5 @@
 
 kernel void tint_symbol(const constant tint_array<str, 4>* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  str const r = func((&(*tint_module_vars.S)[2]));
+  str const r = func((&(*tint_module_vars.S)[2u]));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.spvasm
index 2c26bd2..7526dac 100644
--- a/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/uniform/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -39,7 +39,7 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %23 = OpTypeFunction %void
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %str None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -50,8 +50,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %23
          %24 = OpLabel
-         %25 = OpBitcast %uint %int_2
-         %27 = OpCompositeConstruct %_arr_uint_uint_1 %25
-          %r = OpFunctionCall %str %func %27
+         %25 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+          %r = OpFunctionCall %str %func %25
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.glsl
index a913705..7094f28 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -10,5 +10,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec2 r = func(uint[1](uint(1)));
+  vec2 r = func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 806bfe4..e18f06d 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -10,7 +10,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_2[1] = {uint(int(1))};
+  uint v_2[1] = {1u};
   float2 r = func(v_2);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 806bfe4..e18f06d 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -10,7 +10,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_2[1] = {uint(int(1))};
+  uint v_2[1] = {1u};
   float2 r = func(v_2);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 13167e8..c9a1444 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(const constant float2x2* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  float2 const r = func((&(*tint_module_vars.S)[1]));
+  float2 const r = func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index b88a3d1..c6fd004 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/uniform/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 36
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -37,8 +37,6 @@
 %_ptr_Function_v2float = OpTypePointer Function %v2float
        %void = OpTypeVoid
          %29 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v2float None %11
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %12 = OpLabel
@@ -56,8 +54,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %29
          %30 = OpLabel
-         %31 = OpBitcast %uint %int_1
-         %34 = OpCompositeConstruct %_arr_uint_uint_1 %31
-          %r = OpFunctionCall %v2float %func %34
+         %31 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v2float %func %31
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 52d326e..d6076fc 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  vec4 r = func(uint[1](uint(1)));
+  vec4 r = func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index c7b2dde..8634ddd 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -9,7 +9,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_1[1] = {uint(int(1))};
+  uint v_1[1] = {1u};
   float4 r = func(v_1);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index c7b2dde..8634ddd 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -9,7 +9,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_1[1] = {uint(int(1))};
+  uint v_1[1] = {1u};
   float4 r = func(v_1);
 }
 
diff --git a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index da6c468..778f458 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(const constant float2x4* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  float4 const r = func((&(*tint_module_vars.S)[1]));
+  float4 const r = func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 0a53aa3..1858614 100644
--- a/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/uniform/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,8 +35,6 @@
      %uint_0 = OpConstant %uint 0
        %void = OpTypeVoid
          %21 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %v4float None %12
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %13 = OpLabel
@@ -47,8 +45,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-          %r = OpFunctionCall %v4float %func %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v4float %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.ir.msl
index 0301bb0..fbcdcaa 100644
--- a/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   threadgroup str* S;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   str tint_symbol_1;
 };
@@ -34,6 +37,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.msl b/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.msl
index ce8a583..479e0f5 100644
--- a/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/array_in_struct.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct str {
   tint_array<int, 4> arr;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup str* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_1)).arr[i] = 0;
   }
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.glsl
index b13edc3..1af54ba 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.glsl
@@ -26,7 +26,7 @@
     }
   }
   barrier();
-  str r = func(uint[1](uint(2)));
+  str r = func(uint[1](2u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
index e8486b6..68723d1 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v_4[1] = {uint(int(2))};
+  uint v_4[1] = {2u};
   str r = func(v_4);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
index e8486b6..68723d1 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -31,7 +31,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v_4[1] = {uint(int(2))};
+  uint v_4[1] = {2u};
   str r = func(v_4);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.msl
index 021d045..f2fb702 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   threadgroup tint_array<str, 4>* S;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<str, 4> tint_symbol_1;
 };
@@ -34,6 +37,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -46,7 +50,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  str const r = func((&(*tint_module_vars.S)[2]));
+  str const r = func((&(*tint_module_vars.S)[2u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.msl b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.msl
index 1d8928a..c8a00fd 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct str {
   int i;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<str, 4>* const tint_symbol_2) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i_1 = idx;
     str const tint_symbol_1 = str{};
     (*(tint_symbol_2))[i_1] = tint_symbol_1;
diff --git a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.spvasm
index c3d0ea6..b87e52d 100644
--- a/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/workgroup/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 50
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -40,8 +40,7 @@
          %37 = OpConstantNull %str
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-      %int_2 = OpConstant %int 2
-         %46 = OpTypeFunction %void
+         %44 = OpTypeFunction %void
        %func = OpFunction %str None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -75,14 +74,13 @@
                OpBranch %28
          %29 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %41 = OpBitcast %uint %int_2
-         %43 = OpCompositeConstruct %_arr_uint_uint_1 %41
-          %r = OpFunctionCall %str %func %43
+         %41 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+          %r = OpFunctionCall %str %func %41
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %46
-         %47 = OpLabel
-         %48 = OpLoad %uint %main_local_invocation_index_Input None
-         %49 = OpFunctionCall %void %main_inner %48
+       %main = OpFunction %void None %44
+         %45 = OpLabel
+         %46 = OpLoad %uint %main_local_invocation_index_Input None
+         %47 = OpFunctionCall %void %main_inner %46
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
index bd7a2c1..1373abe 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -9,7 +9,7 @@
     S = mat2(vec2(0.0f), vec2(0.0f));
   }
   barrier();
-  vec2 r = func(uint[1](uint(1)));
+  vec2 r = func(uint[1](1u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 16d87a0..8378b97 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float2 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 16d87a0..8378b97 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float2 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index ad1c36d..703d247 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
     (*tint_module_vars.S) = float2x2(float2(0.0f), float2(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  float2 const r = func((&(*tint_module_vars.S)[1]));
+  float2 const r = func((&(*tint_module_vars.S)[1u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index 095d53d..eee70a1 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,9 +35,7 @@
          %28 = OpConstantNull %mat2v2float
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %38 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
        %func = OpFunction %v2float None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -57,14 +55,13 @@
                OpBranch %26
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpBitcast %uint %int_1
-         %35 = OpCompositeConstruct %_arr_uint_uint_1 %32
-          %r = OpFunctionCall %v2float %func %35
+         %32 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v2float %func %32
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpLoad %uint %main_local_invocation_index_Input None
-         %41 = OpFunctionCall %void %main_inner %40
+       %main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpLoad %uint %main_local_invocation_index_Input None
+         %38 = OpFunctionCall %void %main_inner %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 711ba0e..387ca98 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -9,7 +9,7 @@
     S = mat2x4(vec4(0.0f), vec4(0.0f));
   }
   barrier();
-  vec4 r = func(uint[1](uint(1)));
+  vec4 r = func(uint[1](1u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index a7d7607..ff50909 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x4((0.0f).xxxx, (0.0f).xxxx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float4 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index a7d7607..ff50909 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x4((0.0f).xxxx, (0.0f).xxxx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   float4 r = func(v);
 }
 
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index ced2bd1..7c3e62d 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
     (*tint_module_vars.S) = float2x4(float4(0.0f), float4(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  float4 const r = func((&(*tint_module_vars.S)[1]));
+  float4 const r = func((&(*tint_module_vars.S)[1u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 7329b65..efabffa 100644
--- a/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/load/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,9 +35,7 @@
          %28 = OpConstantNull %mat2v4float
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %38 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
        %func = OpFunction %v4float None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -57,14 +55,13 @@
                OpBranch %26
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpBitcast %uint %int_1
-         %35 = OpCompositeConstruct %_arr_uint_uint_1 %32
-          %r = OpFunctionCall %v4float %func %35
+         %32 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+          %r = OpFunctionCall %v4float %func %32
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpLoad %uint %main_local_invocation_index_Input None
-         %41 = OpFunctionCall %void %main_inner %40
+       %main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpLoad %uint %main_local_invocation_index_Input None
+         %38 = OpFunctionCall %void %main_inner %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.glsl
index 6589969..31143f2 100644
--- a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   str F[4] = str[4](str(0), str(0), str(0), str(0));
-  func(F[2]);
+  func(F[2u]);
 }
diff --git a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 1e2c73b..e6ce47f 100644
--- a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   str F[4] = (str[4])0;
-  func(F[int(2)]);
+  func(F[2u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 1e2c73b..e6ce47f 100644
--- a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -11,6 +11,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   str F[4] = (str[4])0;
-  func(F[int(2)]);
+  func(F[2u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.msl
index 36b615c..04ad25a 100644
--- a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.ir.msl
@@ -23,5 +23,5 @@
 
 kernel void tint_symbol() {
   tint_array<str, 4> F = {};
-  func((&F[2]));
+  func((&F[2u]));
 }
diff --git a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.spvasm
index d48e694..ccf516c 100644
--- a/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/function/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -31,7 +31,7 @@
          %18 = OpConstantNull %str
          %20 = OpTypeFunction %void
          %23 = OpConstantNull %_arr_str_uint_4
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %void None %13
 %pointer_root = OpFunctionParameter %_ptr_Function__arr_str_uint_4
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -44,8 +44,7 @@
        %main = OpFunction %void None %20
          %21 = OpLabel
           %F = OpVariable %_ptr_Function__arr_str_uint_4 Function %23
-         %24 = OpBitcast %uint %int_2
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %24
-         %27 = OpFunctionCall %void %func %F %26
+         %24 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+         %26 = OpFunctionCall %void %func %F %24
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 0d45ad7..d413180 100644
--- a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2 F = mat2(vec2(0.0f), vec2(0.0f));
-  func(F[1]);
+  func(F[1u]);
 }
diff --git a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 99304f1..5c6c477 100644
--- a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x2 F = float2x2((0.0f).xx, (0.0f).xx);
-  func(F[int(1)]);
+  func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 99304f1..5c6c477 100644
--- a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x2 F = float2x2((0.0f).xx, (0.0f).xx);
-  func(F[int(1)]);
+  func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 68be9c6..8e01a00 100644
--- a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -7,5 +7,5 @@
 
 kernel void tint_symbol() {
   float2x2 F = float2x2(0.0f);
-  func((&F[1]));
+  func((&F[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index 75329ef..01d7214 100644
--- a/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/function/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
          %17 = OpConstantNull %v2float
          %19 = OpTypeFunction %void
          %22 = OpConstantNull %mat2v2float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %12
 %pointer_root = OpFunctionParameter %_ptr_Function_mat2v2float
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -40,8 +38,7 @@
        %main = OpFunction %void None %19
          %20 = OpLabel
           %F = OpVariable %_ptr_Function_mat2v2float Function %22
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-         %27 = OpFunctionCall %void %func %F %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %24 = OpFunctionCall %void %func %F %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 6d025d6..dcebd97 100644
--- a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   mat2x4 F = mat2x4(vec4(0.0f), vec4(0.0f));
-  func(F[1]);
+  func(F[1u]);
 }
diff --git a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index 2bd3240..189a3a0 100644
--- a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 F = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  func(F[int(1)]);
+  func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index 2bd3240..189a3a0 100644
--- a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   float2x4 F = float2x4((0.0f).xxxx, (0.0f).xxxx);
-  func(F[int(1)]);
+  func(F[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index c2263bb..c187b7d 100644
--- a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -7,5 +7,5 @@
 
 kernel void tint_symbol() {
   float2x4 F = float2x4(0.0f);
-  func((&F[1]));
+  func((&F[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index b4f1a6d..0ab663a 100644
--- a/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/function/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
          %17 = OpConstantNull %v4float
          %19 = OpTypeFunction %void
          %22 = OpConstantNull %mat2v4float
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %12
 %pointer_root = OpFunctionParameter %_ptr_Function_mat2v4float
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
@@ -40,8 +38,7 @@
        %main = OpFunction %void None %19
          %20 = OpLabel
           %F = OpVariable %_ptr_Function_mat2v4float Function %22
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-         %27 = OpFunctionCall %void %func %F %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %24 = OpFunctionCall %void %func %F %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.glsl
index ca9fe3b..49018d5 100644
--- a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.glsl
@@ -11,5 +11,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(P[2]);
+  func(P[2u]);
 }
diff --git a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
index a85768d..1495b16 100644
--- a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(2)]);
+  func(P[2u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
index a85768d..1495b16 100644
--- a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -11,6 +11,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(2)]);
+  func(P[2u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.msl
index af81aec..37aa09a 100644
--- a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.ir.msl
@@ -28,5 +28,5 @@
 kernel void tint_symbol() {
   thread tint_array<str, 4> P = {};
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  func((&(*tint_module_vars.P)[2]));
+  func((&(*tint_module_vars.P)[2u]));
 }
diff --git a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.spvasm
index 6496858..f1973e1 100644
--- a/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/private/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 26
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -31,7 +31,7 @@
 %_ptr_Private_str = OpTypePointer Private %str
          %19 = OpConstantNull %str
          %21 = OpTypeFunction %void
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %void None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -42,8 +42,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_2
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %23
-         %26 = OpFunctionCall %void %func %25
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+         %25 = OpFunctionCall %void %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 78babbf..39862fb 100644
--- a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(P[1]);
+  func(P[1u]);
 }
diff --git a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index ed2fab7..676105a 100644
--- a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(1)]);
+  func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index ed2fab7..676105a 100644
--- a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(1)]);
+  func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 93a4e13..eea3a26 100644
--- a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -12,5 +12,5 @@
 kernel void tint_symbol() {
   thread float2x2 P = float2x2(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  func((&(*tint_module_vars.P)[1]));
+  func((&(*tint_module_vars.P)[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index d7239b9..7df1011 100644
--- a/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/private/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
 %_ptr_Private_v2float = OpTypePointer Private %v2float
          %18 = OpConstantNull %v2float
          %20 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -38,8 +36,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %20
          %21 = OpLabel
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %22
-         %26 = OpFunctionCall %void %func %25
+         %22 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %23 = OpFunctionCall %void %func %22
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
index fb76858..12f7657 100644
--- a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -6,5 +6,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(P[1]);
+  func(P[1u]);
 }
diff --git a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index bf6639d..5ace356 100644
--- a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(1)]);
+  func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index bf6639d..5ace356 100644
--- a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,6 +6,6 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  func(P[int(1)]);
+  func(P[1u]);
 }
 
diff --git a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index 0cbe6d9..4d7f1d7 100644
--- a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -12,5 +12,5 @@
 kernel void tint_symbol() {
   thread float2x4 P = float2x4(0.0f);
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.P=(&P)};
-  func((&(*tint_module_vars.P)[1]));
+  func((&(*tint_module_vars.P)[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 36d9713..83861e8 100644
--- a/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/private/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,8 +26,6 @@
 %_ptr_Private_v4float = OpTypePointer Private %v4float
          %18 = OpConstantNull %v4float
          %20 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -38,8 +36,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %20
          %21 = OpLabel
-         %22 = OpBitcast %uint %int_1
-         %25 = OpCompositeConstruct %_arr_uint_uint_1 %22
-         %26 = OpFunctionCall %void %func %25
+         %22 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %23 = OpFunctionCall %void %func %22
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.glsl
index 3140dfb..61652ab 100644
--- a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.glsl
@@ -14,5 +14,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(uint[1](uint(2)));
+  func(uint[1](2u));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 9be45eb..6c91981 100644
--- a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -15,7 +15,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_2[1] = {uint(int(2))};
+  uint v_2[1] = {2u};
   func(v_2);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 9be45eb..6c91981 100644
--- a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -15,7 +15,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v_2[1] = {uint(int(2))};
+  uint v_2[1] = {2u};
   func(v_2);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.msl
index 8fa57fc..bd3a08e 100644
--- a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.ir.msl
@@ -27,5 +27,5 @@
 
 kernel void tint_symbol(device tint_array<str, 4>* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  func((&(*tint_module_vars.S)[2]));
+  func((&(*tint_module_vars.S)[2u]));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.spvasm
index 605cded..9090f59 100644
--- a/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/storage/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -38,7 +38,7 @@
      %uint_0 = OpConstant %uint 0
          %20 = OpConstantNull %str
          %22 = OpTypeFunction %void
-      %int_2 = OpConstant %int 2
+     %uint_2 = OpConstant %uint 2
        %func = OpFunction %void None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -49,8 +49,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %22
          %23 = OpLabel
-         %24 = OpBitcast %uint %int_2
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %24
-         %27 = OpFunctionCall %void %func %26
+         %24 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+         %26 = OpFunctionCall %void %func %24
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 85667f7..a185066 100644
--- a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(uint[1](uint(1)));
+  func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 91a2ae9..873d49b 100644
--- a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 91a2ae9..873d49b 100644
--- a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 33dbc56..3469dd0 100644
--- a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(device float2x2* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  func((&(*tint_module_vars.S)[1]));
+  func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index fdcfa69..dfe8b7d 100644
--- a/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/storage/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,8 +35,6 @@
      %uint_0 = OpConstant %uint 0
          %19 = OpConstantNull %v2float
          %21 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -47,8 +45,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-         %27 = OpFunctionCall %void %func %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %24 = OpFunctionCall %void %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 3c3b840..687a6e4 100644
--- a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -9,5 +9,5 @@
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  func(uint[1](uint(1)));
+  func(uint[1](1u));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index 0318dcc..e101875 100644
--- a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index 0318dcc..e101875 100644
--- a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -6,7 +6,7 @@
 
 [numthreads(1, 1, 1)]
 void main() {
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index d1174cd..5f46d9f 100644
--- a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -11,5 +11,5 @@
 
 kernel void tint_symbol(device float2x4* S [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.S=S};
-  func((&(*tint_module_vars.S)[1]));
+  func((&(*tint_module_vars.S)[1u]));
 }
diff --git a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index b9b470a..d1bfb59 100644
--- a/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/storage/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,8 +35,6 @@
      %uint_0 = OpConstant %uint 0
          %19 = OpConstantNull %v4float
          %21 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
        %func = OpFunction %void None %13
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %14 = OpLabel
@@ -47,8 +45,7 @@
                OpFunctionEnd
        %main = OpFunction %void None %21
          %22 = OpLabel
-         %23 = OpBitcast %uint %int_1
-         %26 = OpCompositeConstruct %_arr_uint_uint_1 %23
-         %27 = OpFunctionCall %void %func %26
+         %23 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %24 = OpFunctionCall %void %func %23
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.ir.msl
index 2b87be7..e3a3a94 100644
--- a/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   threadgroup str* S;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   str tint_symbol_1;
 };
@@ -34,6 +37,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
diff --git a/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.msl b/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.msl
index 7600ada..669dc4c 100644
--- a/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/array_in_struct.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct str {
   tint_array<int, 4> arr;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup str* const tint_symbol_2) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_2)).arr[i] = 0;
   }
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.glsl
index d611a88..0f7d093 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.glsl
@@ -26,7 +26,7 @@
     }
   }
   barrier();
-  func(uint[1](uint(2)));
+  func(uint[1](2u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
index 3fcc5aa..532cf51 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.dxc.hlsl
@@ -31,7 +31,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v_4[1] = {uint(int(2))};
+  uint v_4[1] = {2u};
   func(v_4);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
index 3fcc5aa..532cf51 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.fxc.hlsl
@@ -31,7 +31,7 @@
     }
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v_4[1] = {uint(int(2))};
+  uint v_4[1] = {2u};
   func(v_4);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.msl
index 8b0bbca..7c64eae 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.ir.msl
@@ -21,6 +21,9 @@
   threadgroup tint_array<str, 4>* S;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<str, 4> tint_symbol_1;
 };
@@ -34,6 +37,7 @@
     uint v = 0u;
     v = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_1 = v;
       if ((v_1 >= 4u)) {
         break;
@@ -46,7 +50,7 @@
     }
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  func((&(*tint_module_vars.S)[2]));
+  func((&(*tint_module_vars.S)[2u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v_2 [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.msl b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.msl
index d56db2e..5d52a1f 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct str {
   int i;
 };
 
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<str, 4>* const tint_symbol_3) {
   for(uint idx = local_idx; (idx < 4u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i_1 = idx;
     str const tint_symbol_1 = str{};
     (*(tint_symbol_3))[i_1] = tint_symbol_1;
diff --git a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.spvasm
index f3e7036..b0f6698 100644
--- a/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/workgroup/struct_in_array.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 49
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -39,8 +39,7 @@
        %bool = OpTypeBool
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-      %int_2 = OpConstant %int 2
-         %45 = OpTypeFunction %void
+         %43 = OpTypeFunction %void
        %func = OpFunction %void None %15
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %16 = OpLabel
@@ -74,14 +73,13 @@
                OpBranch %28
          %29 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %40 = OpBitcast %uint %int_2
-         %42 = OpCompositeConstruct %_arr_uint_uint_1 %40
-         %43 = OpFunctionCall %void %func %42
+         %40 = OpCompositeConstruct %_arr_uint_uint_1 %uint_2
+         %41 = OpFunctionCall %void %func %40
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %45
-         %46 = OpLabel
-         %47 = OpLoad %uint %main_local_invocation_index_Input None
-         %48 = OpFunctionCall %void %main_inner %47
+       %main = OpFunction %void None %43
+         %44 = OpLabel
+         %45 = OpLoad %uint %main_local_invocation_index_Input None
+         %46 = OpFunctionCall %void %main_inner %45
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
index 468c8fe..41f4ee4 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.glsl
@@ -9,7 +9,7 @@
     S = mat2(vec2(0.0f), vec2(0.0f));
   }
   barrier();
-  func(uint[1](uint(1)));
+  func(uint[1](1u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
index 924c11b..dc0b9d2 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
index 924c11b..dc0b9d2 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
index 01602c0..649ccb7 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
     (*tint_module_vars.S) = float2x2(float2(0.0f), float2(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  func((&(*tint_module_vars.S)[1]));
+  func((&(*tint_module_vars.S)[1u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
index 87ed8ad..31d289b 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/workgroup/vec2_f32_in_mat2x2.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,9 +35,7 @@
          %28 = OpConstantNull %mat2v2float
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %38 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
        %func = OpFunction %void None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -57,14 +55,13 @@
                OpBranch %26
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpBitcast %uint %int_1
-         %35 = OpCompositeConstruct %_arr_uint_uint_1 %32
-         %36 = OpFunctionCall %void %func %35
+         %32 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %33 = OpFunctionCall %void %func %32
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpLoad %uint %main_local_invocation_index_Input None
-         %41 = OpFunctionCall %void %main_inner %40
+       %main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpLoad %uint %main_local_invocation_index_Input None
+         %38 = OpFunctionCall %void %main_inner %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
index 14563c9..4626d3f 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.glsl
@@ -9,7 +9,7 @@
     S = mat2x4(vec4(0.0f), vec4(0.0f));
   }
   barrier();
-  func(uint[1](uint(1)));
+  func(uint[1](1u));
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
index afb2e6f..a139706 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x4((0.0f).xxxx, (0.0f).xxxx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
index afb2e6f..a139706 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
     S = float2x4((0.0f).xxxx, (0.0f).xxxx);
   }
   GroupMemoryBarrierWithGroupSync();
-  uint v[1] = {uint(int(1))};
+  uint v[1] = {1u};
   func(v);
 }
 
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
index 0104573..936e906 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
+++ b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.ir.msl
@@ -18,7 +18,7 @@
     (*tint_module_vars.S) = float2x4(float4(0.0f), float4(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  func((&(*tint_module_vars.S)[1]));
+  func((&(*tint_module_vars.S)[1u]));
 }
 
 kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v [[threadgroup(0)]]) {
diff --git a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
index 93f1c44..75ca6eb 100644
--- a/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
+++ b/test/tint/ptr_ref/store/param/workgroup/vec4_f32_in_mat2x4.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 42
+; Bound: 39
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -35,9 +35,7 @@
          %28 = OpConstantNull %mat2v4float
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
-         %38 = OpTypeFunction %void
+         %35 = OpTypeFunction %void
        %func = OpFunction %void None %14
 %pointer_indices = OpFunctionParameter %_arr_uint_uint_1
          %15 = OpLabel
@@ -57,14 +55,13 @@
                OpBranch %26
          %26 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %32 = OpBitcast %uint %int_1
-         %35 = OpCompositeConstruct %_arr_uint_uint_1 %32
-         %36 = OpFunctionCall %void %func %35
+         %32 = OpCompositeConstruct %_arr_uint_uint_1 %uint_1
+         %33 = OpFunctionCall %void %func %32
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpLoad %uint %main_local_invocation_index_Input None
-         %41 = OpFunctionCall %void %main_inner %40
+       %main = OpFunction %void None %35
+         %36 = OpLabel
+         %37 = OpLoad %uint %main_local_invocation_index_Input None
+         %38 = OpFunctionCall %void %main_inner %37
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.dxc.hlsl b/test/tint/ptr_sugar/array.wgsl.expected.dxc.hlsl
index ed5097a..5b283fd 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.dxc.hlsl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.dxc.hlsl
@@ -13,28 +13,28 @@
 void deref_let() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void deref_var() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.fxc.hlsl b/test/tint/ptr_sugar/array.wgsl.expected.fxc.hlsl
index ed5097a..5b283fd 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.fxc.hlsl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.fxc.hlsl
@@ -13,28 +13,28 @@
 void deref_let() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void deref_var() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   int a[10] = (int[10])0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.glsl b/test/tint/ptr_sugar/array.wgsl.expected.glsl
index e675cbf..33cbaea 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.glsl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.glsl
@@ -2,39 +2,41 @@
 
 void deref_const() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-  int b = a[0];
-  a[0] = 42;
+  int b = a[0u];
+  a[0u] = 42;
 }
 void no_deref_const() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-  int b = a[0];
-  a[0] = 42;
+  int b = a[0u];
+  a[0u] = 42;
 }
 void deref_let() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  uint v = min(uint(i), 9u);
+  int b = a[v];
+  a[0u] = 42;
 }
 void no_deref_let() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  uint v_1 = min(uint(i), 9u);
+  int b = a[v_1];
+  a[0u] = 42;
 }
 void deref_var() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   int i = 0;
-  int v = i;
-  int b = a[v];
-  a[0] = 42;
+  uint v_2 = min(uint(i), 9u);
+  int b = a[v_2];
+  a[0u] = 42;
 }
 void no_deref_var() {
   int a[10] = int[10](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
   int i = 0;
-  int v_1 = i;
-  int b = a[v_1];
-  a[0] = 42;
+  uint v_3 = min(uint(i), 9u);
+  int b = a[v_3];
+  a[0u] = 42;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_sugar/array.wgsl.expected.ir.dxc.hlsl
index 69bd634..937a626 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.ir.dxc.hlsl
@@ -1,44 +1,46 @@
 
 void deref_const() {
   int a[10] = (int[10])0;
-  int b = a[int(0)];
-  a[int(0)] = int(42);
+  int b = a[0u];
+  a[0u] = int(42);
 }
 
 void no_deref_const() {
   int a[10] = (int[10])0;
-  int b = a[int(0)];
-  a[int(0)] = int(42);
+  int b = a[0u];
+  a[0u] = int(42);
 }
 
 void deref_let() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int b = a[i];
-  a[int(0)] = int(42);
+  uint v = min(uint(i), 9u);
+  int b = a[v];
+  a[0u] = int(42);
 }
 
 void no_deref_let() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int b = a[i];
-  a[int(0)] = int(42);
+  uint v_1 = min(uint(i), 9u);
+  int b = a[v_1];
+  a[0u] = int(42);
 }
 
 void deref_var() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int v = i;
-  int b = a[v];
-  a[int(0)] = int(42);
+  uint v_2 = min(uint(i), 9u);
+  int b = a[v_2];
+  a[0u] = int(42);
 }
 
 void no_deref_var() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int v_1 = i;
-  int b = a[v_1];
-  a[int(0)] = int(42);
+  uint v_3 = min(uint(i), 9u);
+  int b = a[v_3];
+  a[0u] = int(42);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_sugar/array.wgsl.expected.ir.fxc.hlsl
index 69bd634..937a626 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.ir.fxc.hlsl
@@ -1,44 +1,46 @@
 
 void deref_const() {
   int a[10] = (int[10])0;
-  int b = a[int(0)];
-  a[int(0)] = int(42);
+  int b = a[0u];
+  a[0u] = int(42);
 }
 
 void no_deref_const() {
   int a[10] = (int[10])0;
-  int b = a[int(0)];
-  a[int(0)] = int(42);
+  int b = a[0u];
+  a[0u] = int(42);
 }
 
 void deref_let() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int b = a[i];
-  a[int(0)] = int(42);
+  uint v = min(uint(i), 9u);
+  int b = a[v];
+  a[0u] = int(42);
 }
 
 void no_deref_let() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int b = a[i];
-  a[int(0)] = int(42);
+  uint v_1 = min(uint(i), 9u);
+  int b = a[v_1];
+  a[0u] = int(42);
 }
 
 void deref_var() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int v = i;
-  int b = a[v];
-  a[int(0)] = int(42);
+  uint v_2 = min(uint(i), 9u);
+  int b = a[v_2];
+  a[0u] = int(42);
 }
 
 void no_deref_var() {
   int a[10] = (int[10])0;
   int i = int(0);
-  int v_1 = i;
-  int b = a[v_1];
-  a[int(0)] = int(42);
+  uint v_3 = min(uint(i), 9u);
+  int b = a[v_3];
+  a[0u] = int(42);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.ir.msl b/test/tint/ptr_sugar/array.wgsl.expected.ir.msl
index e1f2b99..11882be 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.ir.msl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.ir.msl
@@ -16,47 +16,47 @@
 void deref_const() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
-  int b = (*p)[0];
-  (*p)[0] = 42;
+  int b = (*p)[0u];
+  (*p)[0u] = 42;
 }
 
 void no_deref_const() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
-  int b = (*p)[0];
-  (*p)[0] = 42;
+  int b = (*p)[0u];
+  (*p)[0u] = 42;
 }
 
 void deref_let() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
   int const i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 9u)];
+  (*p)[0u] = 42;
 }
 
 void no_deref_let() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
   int const i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 9u)];
+  (*p)[0u] = 42;
 }
 
 void deref_var() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
   int i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 9u)];
+  (*p)[0u] = 42;
 }
 
 void no_deref_var() {
   tint_array<int, 10> a = {};
   thread tint_array<int, 10>* const p = (&a);
   int i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 9u)];
+  (*p)[0u] = 42;
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.msl b/test/tint/ptr_sugar/array.wgsl.expected.msl
index 9bd0861..049cec2 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.msl
+++ b/test/tint/ptr_sugar/array.wgsl.expected.msl
@@ -29,28 +29,28 @@
 void deref_let() {
   tint_array<int, 10> a = {};
   int const i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   tint_array<int, 10> a = {};
   int const i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void deref_var() {
   tint_array<int, 10> a = {};
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   tint_array<int, 10> a = {};
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 9u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/array.wgsl.expected.spvasm b/test/tint/ptr_sugar/array.wgsl.expected.spvasm
index 88851ec..f2fce3f 100644
--- a/test/tint/ptr_sugar/array.wgsl.expected.spvasm
+++ b/test/tint/ptr_sugar/array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 77
 ; Schema: 0
                OpCapability Shader
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -46,16 +47,18 @@
 %_ptr_Function__arr_int_uint_10 = OpTypePointer Function %_arr_int_uint_10
          %11 = OpConstantNull %_arr_int_uint_10
 %_ptr_Function_int = OpTypePointer Function %int
-          %i = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
      %int_42 = OpConstant %int 42
+          %i = OpConstant %int 0
+     %uint_9 = OpConstant %uint 9
 %deref_const = OpFunction %void None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
           %b = OpVariable %_ptr_Function_int Function
-         %12 = OpAccessChain %_ptr_Function_int %a %i
+         %12 = OpAccessChain %_ptr_Function_int %a %uint_0
          %15 = OpLoad %int %12 None
                OpStore %b %15
-         %17 = OpAccessChain %_ptr_Function_int %a %i
+         %17 = OpAccessChain %_ptr_Function_int %a %uint_0
                OpStore %17 %int_42 None
                OpReturn
                OpFunctionEnd
@@ -63,10 +66,10 @@
          %20 = OpLabel
         %a_0 = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
         %b_0 = OpVariable %_ptr_Function_int Function
-         %22 = OpAccessChain %_ptr_Function_int %a_0 %i
+         %22 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
          %23 = OpLoad %int %22 None
                OpStore %b_0 %23
-         %25 = OpAccessChain %_ptr_Function_int %a_0 %i
+         %25 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
                OpStore %25 %int_42 None
                OpReturn
                OpFunctionEnd
@@ -74,59 +77,67 @@
          %27 = OpLabel
         %a_1 = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
         %b_1 = OpVariable %_ptr_Function_int Function
-         %29 = OpAccessChain %_ptr_Function_int %a_1 %i
-         %30 = OpLoad %int %29 None
-               OpStore %b_1 %30
-         %32 = OpAccessChain %_ptr_Function_int %a_1 %i
-               OpStore %32 %int_42 None
+         %30 = OpBitcast %uint %i
+         %31 = OpExtInst %uint %32 UMin %30 %uint_9
+         %34 = OpAccessChain %_ptr_Function_int %a_1 %31
+         %35 = OpLoad %int %34 None
+               OpStore %b_1 %35
+         %37 = OpAccessChain %_ptr_Function_int %a_1 %uint_0
+               OpStore %37 %int_42 None
                OpReturn
                OpFunctionEnd
 %no_deref_let = OpFunction %void None %3
-         %34 = OpLabel
+         %39 = OpLabel
         %a_2 = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
         %b_2 = OpVariable %_ptr_Function_int Function
-         %36 = OpAccessChain %_ptr_Function_int %a_2 %i
-         %37 = OpLoad %int %36 None
-               OpStore %b_2 %37
-         %39 = OpAccessChain %_ptr_Function_int %a_2 %i
-               OpStore %39 %int_42 None
+         %41 = OpBitcast %uint %i
+         %42 = OpExtInst %uint %32 UMin %41 %uint_9
+         %43 = OpAccessChain %_ptr_Function_int %a_2 %42
+         %44 = OpLoad %int %43 None
+               OpStore %b_2 %44
+         %46 = OpAccessChain %_ptr_Function_int %a_2 %uint_0
+               OpStore %46 %int_42 None
                OpReturn
                OpFunctionEnd
   %deref_var = OpFunction %void None %3
-         %41 = OpLabel
+         %48 = OpLabel
         %a_3 = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
         %i_0 = OpVariable %_ptr_Function_int Function
         %b_3 = OpVariable %_ptr_Function_int Function
                OpStore %i_0 %i
-         %44 = OpLoad %int %i_0 None
-         %45 = OpAccessChain %_ptr_Function_int %a_3 %44
-         %46 = OpLoad %int %45 None
-               OpStore %b_3 %46
-         %48 = OpAccessChain %_ptr_Function_int %a_3 %i
-               OpStore %48 %int_42 None
+         %51 = OpLoad %int %i_0 None
+         %52 = OpBitcast %uint %51
+         %53 = OpExtInst %uint %32 UMin %52 %uint_9
+         %54 = OpAccessChain %_ptr_Function_int %a_3 %53
+         %55 = OpLoad %int %54 None
+               OpStore %b_3 %55
+         %57 = OpAccessChain %_ptr_Function_int %a_3 %uint_0
+               OpStore %57 %int_42 None
                OpReturn
                OpFunctionEnd
 %no_deref_var = OpFunction %void None %3
-         %50 = OpLabel
+         %59 = OpLabel
         %a_4 = OpVariable %_ptr_Function__arr_int_uint_10 Function %11
         %i_1 = OpVariable %_ptr_Function_int Function
         %b_4 = OpVariable %_ptr_Function_int Function
                OpStore %i_1 %i
-         %53 = OpLoad %int %i_1 None
-         %54 = OpAccessChain %_ptr_Function_int %a_4 %53
-         %55 = OpLoad %int %54 None
-               OpStore %b_4 %55
-         %57 = OpAccessChain %_ptr_Function_int %a_4 %i
-               OpStore %57 %int_42 None
+         %62 = OpLoad %int %i_1 None
+         %63 = OpBitcast %uint %62
+         %64 = OpExtInst %uint %32 UMin %63 %uint_9
+         %65 = OpAccessChain %_ptr_Function_int %a_4 %64
+         %66 = OpLoad %int %65 None
+               OpStore %b_4 %66
+         %68 = OpAccessChain %_ptr_Function_int %a_4 %uint_0
+               OpStore %68 %int_42 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %3
-         %59 = OpLabel
-         %60 = OpFunctionCall %void %deref_const
-         %61 = OpFunctionCall %void %no_deref_const
-         %62 = OpFunctionCall %void %deref_let
-         %63 = OpFunctionCall %void %no_deref_let
-         %64 = OpFunctionCall %void %deref_var
-         %65 = OpFunctionCall %void %no_deref_var
+         %70 = OpLabel
+         %71 = OpFunctionCall %void %deref_const
+         %72 = OpFunctionCall %void %no_deref_const
+         %73 = OpFunctionCall %void %deref_let
+         %74 = OpFunctionCall %void %no_deref_let
+         %75 = OpFunctionCall %void %deref_var
+         %76 = OpFunctionCall %void %no_deref_var
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.dxc.hlsl b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.dxc.hlsl
index a42bc9d..4d46e79 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.dxc.hlsl
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.dxc.hlsl
@@ -5,25 +5,25 @@
 void deref() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_1 = 0;
-  set_vector_element(a, tint_symbol_1, (a[tint_symbol_1] + 42));
+  set_vector_element(a, min(uint(tint_symbol_1), 2u), (a[min(uint(tint_symbol_1), 2u)] + 42));
 }
 
 void no_deref() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_3 = 0;
-  set_vector_element(a, tint_symbol_3, (a[tint_symbol_3] + 42));
+  set_vector_element(a, min(uint(tint_symbol_3), 2u), (a[min(uint(tint_symbol_3), 2u)] + 42));
 }
 
 void deref_inc() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_5 = 0;
-  set_vector_element(a, tint_symbol_5, (a[tint_symbol_5] + 1));
+  set_vector_element(a, min(uint(tint_symbol_5), 2u), (a[min(uint(tint_symbol_5), 2u)] + 1));
 }
 
 void no_deref_inc() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_7 = 0;
-  set_vector_element(a, tint_symbol_7, (a[tint_symbol_7] + 1));
+  set_vector_element(a, min(uint(tint_symbol_7), 2u), (a[min(uint(tint_symbol_7), 2u)] + 1));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.fxc.hlsl b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.fxc.hlsl
index a42bc9d..4d46e79 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.fxc.hlsl
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.fxc.hlsl
@@ -5,25 +5,25 @@
 void deref() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_1 = 0;
-  set_vector_element(a, tint_symbol_1, (a[tint_symbol_1] + 42));
+  set_vector_element(a, min(uint(tint_symbol_1), 2u), (a[min(uint(tint_symbol_1), 2u)] + 42));
 }
 
 void no_deref() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_3 = 0;
-  set_vector_element(a, tint_symbol_3, (a[tint_symbol_3] + 42));
+  set_vector_element(a, min(uint(tint_symbol_3), 2u), (a[min(uint(tint_symbol_3), 2u)] + 42));
 }
 
 void deref_inc() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_5 = 0;
-  set_vector_element(a, tint_symbol_5, (a[tint_symbol_5] + 1));
+  set_vector_element(a, min(uint(tint_symbol_5), 2u), (a[min(uint(tint_symbol_5), 2u)] + 1));
 }
 
 void no_deref_inc() {
   int3 a = int3(0, 0, 0);
   int tint_symbol_7 = 0;
-  set_vector_element(a, tint_symbol_7, (a[tint_symbol_7] + 1));
+  set_vector_element(a, min(uint(tint_symbol_7), 2u), (a[min(uint(tint_symbol_7), 2u)] + 1));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.glsl b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.glsl
index d7ca299..d2f5092 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.glsl
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.glsl
@@ -2,19 +2,19 @@
 
 void deref() {
   ivec3 a = ivec3(0);
-  a[0] = (a.x + 42);
+  a[0u] = (a.x + 42);
 }
 void no_deref() {
   ivec3 a = ivec3(0);
-  a[0] = (a.x + 42);
+  a[0u] = (a.x + 42);
 }
 void deref_inc() {
   ivec3 a = ivec3(0);
-  a[0] = (a.x + 1);
+  a[0u] = (a.x + 1);
 }
 void no_deref_inc() {
   ivec3 a = ivec3(0);
-  a[0] = (a.x + 1);
+  a[0u] = (a.x + 1);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.ir.msl b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.ir.msl
index 9d528ba..1bb5827 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.ir.msl
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.ir.msl
@@ -4,25 +4,25 @@
 void deref() {
   int3 a = 0;
   thread int3* const p = (&a);
-  (*p)[0] = as_type<int>((as_type<uint>((*p)[0]) + as_type<uint>(42)));
+  (*p)[0u] = as_type<int>((as_type<uint>((*p)[0u]) + as_type<uint>(42)));
 }
 
 void no_deref() {
   int3 a = 0;
   thread int3* const p = (&a);
-  (*p)[0] = as_type<int>((as_type<uint>((*p)[0]) + as_type<uint>(42)));
+  (*p)[0u] = as_type<int>((as_type<uint>((*p)[0u]) + as_type<uint>(42)));
 }
 
 void deref_inc() {
   int3 a = 0;
   thread int3* const p = (&a);
-  (*p)[0] = as_type<int>((as_type<uint>((*p)[0]) + as_type<uint>(1)));
+  (*p)[0u] = as_type<int>((as_type<uint>((*p)[0u]) + as_type<uint>(1)));
 }
 
 void no_deref_inc() {
   int3 a = 0;
   thread int3* const p = (&a);
-  (*p)[0] = as_type<int>((as_type<uint>((*p)[0]) + as_type<uint>(1)));
+  (*p)[0u] = as_type<int>((as_type<uint>((*p)[0u]) + as_type<uint>(1)));
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.msl b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.msl
index 0a18439..9eb0f26 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.msl
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.msl
@@ -4,25 +4,25 @@
 void deref() {
   int3 a = 0;
   int const tint_symbol_2 = 0;
-  a[tint_symbol_2] = as_type<int>((as_type<uint>(a[tint_symbol_2]) + as_type<uint>(42)));
+  a[min(uint(tint_symbol_2), 2u)] = as_type<int>((as_type<uint>(a[min(uint(tint_symbol_2), 2u)]) + as_type<uint>(42)));
 }
 
 void no_deref() {
   int3 a = 0;
   int const tint_symbol_4 = 0;
-  a[tint_symbol_4] = as_type<int>((as_type<uint>(a[tint_symbol_4]) + as_type<uint>(42)));
+  a[min(uint(tint_symbol_4), 2u)] = as_type<int>((as_type<uint>(a[min(uint(tint_symbol_4), 2u)]) + as_type<uint>(42)));
 }
 
 void deref_inc() {
   int3 a = 0;
   int const tint_symbol_6 = 0;
-  a[tint_symbol_6] = as_type<int>((as_type<uint>(a[tint_symbol_6]) + as_type<uint>(1)));
+  a[min(uint(tint_symbol_6), 2u)] = as_type<int>((as_type<uint>(a[min(uint(tint_symbol_6), 2u)]) + as_type<uint>(1)));
 }
 
 void no_deref_inc() {
   int3 a = 0;
   int const tint_symbol_8 = 0;
-  a[tint_symbol_8] = as_type<int>((as_type<uint>(a[tint_symbol_8]) + as_type<uint>(1)));
+  a[min(uint(tint_symbol_8), 2u)] = as_type<int>((as_type<uint>(a[min(uint(tint_symbol_8), 2u)]) + as_type<uint>(1)));
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.spvasm b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.spvasm
index 54ce6c6..1a48662 100644
--- a/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.spvasm
+++ b/test/tint/ptr_sugar/compound_assign_index.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 46
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -27,54 +27,55 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
           %9 = OpConstantNull %v3int
 %_ptr_Function_int = OpTypePointer Function %int
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
      %int_42 = OpConstant %int 42
       %int_1 = OpConstant %int 1
       %deref = OpFunction %void None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_v3int Function %9
-         %10 = OpAccessChain %_ptr_Function_int %a %int_0
-         %13 = OpLoad %int %10 None
-         %14 = OpIAdd %int %13 %int_42
-         %16 = OpAccessChain %_ptr_Function_int %a %int_0
-               OpStore %16 %14 None
+         %10 = OpAccessChain %_ptr_Function_int %a %uint_0
+         %14 = OpLoad %int %10 None
+         %15 = OpIAdd %int %14 %int_42
+         %17 = OpAccessChain %_ptr_Function_int %a %uint_0
+               OpStore %17 %15 None
                OpReturn
                OpFunctionEnd
    %no_deref = OpFunction %void None %3
-         %18 = OpLabel
+         %19 = OpLabel
         %a_0 = OpVariable %_ptr_Function_v3int Function %9
-         %20 = OpAccessChain %_ptr_Function_int %a_0 %int_0
-         %21 = OpLoad %int %20 None
-         %22 = OpIAdd %int %21 %int_42
-         %23 = OpAccessChain %_ptr_Function_int %a_0 %int_0
-               OpStore %23 %22 None
+         %21 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
+         %22 = OpLoad %int %21 None
+         %23 = OpIAdd %int %22 %int_42
+         %24 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
+               OpStore %24 %23 None
                OpReturn
                OpFunctionEnd
   %deref_inc = OpFunction %void None %3
-         %25 = OpLabel
+         %26 = OpLabel
         %a_1 = OpVariable %_ptr_Function_v3int Function %9
-         %27 = OpAccessChain %_ptr_Function_int %a_1 %int_0
-         %28 = OpLoad %int %27 None
-         %29 = OpIAdd %int %28 %int_1
-         %31 = OpAccessChain %_ptr_Function_int %a_1 %int_0
-               OpStore %31 %29 None
+         %28 = OpAccessChain %_ptr_Function_int %a_1 %uint_0
+         %29 = OpLoad %int %28 None
+         %30 = OpIAdd %int %29 %int_1
+         %32 = OpAccessChain %_ptr_Function_int %a_1 %uint_0
+               OpStore %32 %30 None
                OpReturn
                OpFunctionEnd
 %no_deref_inc = OpFunction %void None %3
-         %33 = OpLabel
+         %34 = OpLabel
         %a_2 = OpVariable %_ptr_Function_v3int Function %9
-         %35 = OpAccessChain %_ptr_Function_int %a_2 %int_0
-         %36 = OpLoad %int %35 None
-         %37 = OpIAdd %int %36 %int_1
-         %38 = OpAccessChain %_ptr_Function_int %a_2 %int_0
-               OpStore %38 %37 None
+         %36 = OpAccessChain %_ptr_Function_int %a_2 %uint_0
+         %37 = OpLoad %int %36 None
+         %38 = OpIAdd %int %37 %int_1
+         %39 = OpAccessChain %_ptr_Function_int %a_2 %uint_0
+               OpStore %39 %38 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %3
-         %40 = OpLabel
-         %41 = OpFunctionCall %void %deref
-         %42 = OpFunctionCall %void %no_deref
-         %43 = OpFunctionCall %void %deref_inc
-         %44 = OpFunctionCall %void %no_deref_inc
+         %41 = OpLabel
+         %42 = OpFunctionCall %void %deref
+         %43 = OpFunctionCall %void %no_deref
+         %44 = OpFunctionCall %void %deref_inc
+         %45 = OpFunctionCall %void %no_deref_inc
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_sugar/matrix.wgsl.expected.glsl b/test/tint/ptr_sugar/matrix.wgsl.expected.glsl
index 964efca..b40c6a7 100644
--- a/test/tint/ptr_sugar/matrix.wgsl.expected.glsl
+++ b/test/tint/ptr_sugar/matrix.wgsl.expected.glsl
@@ -2,13 +2,13 @@
 
 void deref() {
   mat2x3 a = mat2x3(vec3(0.0f), vec3(0.0f));
-  vec3 b = a[0];
-  a[0] = vec3(1.0f, 2.0f, 3.0f);
+  vec3 b = a[0u];
+  a[0u] = vec3(1.0f, 2.0f, 3.0f);
 }
 void no_deref() {
   mat2x3 a = mat2x3(vec3(0.0f), vec3(0.0f));
-  vec3 b = a[0];
-  a[0] = vec3(1.0f, 2.0f, 3.0f);
+  vec3 b = a[0u];
+  a[0u] = vec3(1.0f, 2.0f, 3.0f);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.dxc.hlsl
index fc5524e..5d86873 100644
--- a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.dxc.hlsl
@@ -1,14 +1,14 @@
 
 void deref() {
   float2x3 a = float2x3((0.0f).xxx, (0.0f).xxx);
-  float3 b = a[int(0)];
-  a[int(0)] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = a[0u];
+  a[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 void no_deref() {
   float2x3 a = float2x3((0.0f).xxx, (0.0f).xxx);
-  float3 b = a[int(0)];
-  a[int(0)] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = a[0u];
+  a[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.fxc.hlsl
index fc5524e..5d86873 100644
--- a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.fxc.hlsl
@@ -1,14 +1,14 @@
 
 void deref() {
   float2x3 a = float2x3((0.0f).xxx, (0.0f).xxx);
-  float3 b = a[int(0)];
-  a[int(0)] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = a[0u];
+  a[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 void no_deref() {
   float2x3 a = float2x3((0.0f).xxx, (0.0f).xxx);
-  float3 b = a[int(0)];
-  a[int(0)] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = a[0u];
+  a[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.msl b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.msl
index 148236a..ee54bb2 100644
--- a/test/tint/ptr_sugar/matrix.wgsl.expected.ir.msl
+++ b/test/tint/ptr_sugar/matrix.wgsl.expected.ir.msl
@@ -4,15 +4,15 @@
 void deref() {
   float2x3 a = float2x3(0.0f);
   thread float2x3* const p = (&a);
-  float3 b = (*p)[0];
-  (*p)[0] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = (*p)[0u];
+  (*p)[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 void no_deref() {
   float2x3 a = float2x3(0.0f);
   thread float2x3* const p = (&a);
-  float3 b = (*p)[0];
-  (*p)[0] = float3(1.0f, 2.0f, 3.0f);
+  float3 b = (*p)[0u];
+  (*p)[0u] = float3(1.0f, 2.0f, 3.0f);
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_sugar/matrix.wgsl.expected.spvasm b/test/tint/ptr_sugar/matrix.wgsl.expected.spvasm
index 0d57083..7c202d4 100644
--- a/test/tint/ptr_sugar/matrix.wgsl.expected.spvasm
+++ b/test/tint/ptr_sugar/matrix.wgsl.expected.spvasm
@@ -24,8 +24,8 @@
 %_ptr_Function_mat2v3float = OpTypePointer Function %mat2v3float
          %10 = OpConstantNull %mat2v3float
 %_ptr_Function_v3float = OpTypePointer Function %v3float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
     %float_1 = OpConstant %float 1
     %float_2 = OpConstant %float 2
     %float_3 = OpConstant %float 3
@@ -34,10 +34,10 @@
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_mat2v3float Function %10
           %b = OpVariable %_ptr_Function_v3float Function
-         %11 = OpAccessChain %_ptr_Function_v3float %a %int_0
+         %11 = OpAccessChain %_ptr_Function_v3float %a %uint_0
          %15 = OpLoad %v3float %11 None
                OpStore %b %15
-         %17 = OpAccessChain %_ptr_Function_v3float %a %int_0
+         %17 = OpAccessChain %_ptr_Function_v3float %a %uint_0
                OpStore %17 %18 None
                OpReturn
                OpFunctionEnd
@@ -45,10 +45,10 @@
          %23 = OpLabel
         %a_0 = OpVariable %_ptr_Function_mat2v3float Function %10
         %b_0 = OpVariable %_ptr_Function_v3float Function
-         %25 = OpAccessChain %_ptr_Function_v3float %a_0 %int_0
+         %25 = OpAccessChain %_ptr_Function_v3float %a_0 %uint_0
          %26 = OpLoad %v3float %25 None
                OpStore %b_0 %26
-         %28 = OpAccessChain %_ptr_Function_v3float %a_0 %int_0
+         %28 = OpAccessChain %_ptr_Function_v3float %a_0 %uint_0
                OpStore %28 %18 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.dxc.hlsl b/test/tint/ptr_sugar/vector_index.wgsl.expected.dxc.hlsl
index 72fa55c..b43a6db 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.dxc.hlsl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.dxc.hlsl
@@ -13,28 +13,28 @@
 void deref_let() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void deref_var() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.fxc.hlsl b/test/tint/ptr_sugar/vector_index.wgsl.expected.fxc.hlsl
index 72fa55c..b43a6db 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.fxc.hlsl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.fxc.hlsl
@@ -13,28 +13,28 @@
 void deref_let() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void deref_var() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   int3 a = int3(0, 0, 0);
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.glsl b/test/tint/ptr_sugar/vector_index.wgsl.expected.glsl
index 355df83..7e02ebd1 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.glsl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.glsl
@@ -3,36 +3,36 @@
 void deref_const() {
   ivec3 a = ivec3(0);
   int b = a.x;
-  a[0] = 42;
+  a[0u] = 42;
 }
 void no_deref_const() {
   ivec3 a = ivec3(0);
   int b = a.x;
-  a[0] = 42;
+  a[0u] = 42;
 }
 void deref_let() {
   ivec3 a = ivec3(0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  int b = a[min(uint(i), 2u)];
+  a[0u] = 42;
 }
 void no_deref_let() {
   ivec3 a = ivec3(0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  int b = a[min(uint(i), 2u)];
+  a[0u] = 42;
 }
 void deref_var() {
   ivec3 a = ivec3(0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  int b = a[min(uint(i), 2u)];
+  a[0u] = 42;
 }
 void no_deref_var() {
   ivec3 a = ivec3(0);
   int i = 0;
-  int b = a[i];
-  a[0] = 42;
+  int b = a[min(uint(i), 2u)];
+  a[0u] = 42;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.dxc.hlsl b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.dxc.hlsl
index 6b8b321..b145b7a 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.dxc.hlsl
@@ -14,28 +14,28 @@
 void deref_let() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void no_deref_let() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void deref_var() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void no_deref_var() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.fxc.hlsl b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.fxc.hlsl
index 6b8b321..b145b7a 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.fxc.hlsl
@@ -14,28 +14,28 @@
 void deref_let() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void no_deref_let() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void deref_var() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
 void no_deref_var() {
   int3 a = (int(0)).xxx;
   int i = int(0);
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a.x = int(42);
 }
 
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.msl b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.msl
index 28f1ea6..60e7ab6 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.msl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.ir.msl
@@ -4,47 +4,47 @@
 void deref_const() {
   int3 a = 0;
   thread int3* const p = (&a);
-  int b = (*p)[0];
-  (*p)[0] = 42;
+  int b = (*p)[0u];
+  (*p)[0u] = 42;
 }
 
 void no_deref_const() {
   int3 a = 0;
   thread int3* const p = (&a);
-  int b = (*p)[0];
-  (*p)[0] = 42;
+  int b = (*p)[0u];
+  (*p)[0u] = 42;
 }
 
 void deref_let() {
   int3 a = 0;
   thread int3* const p = (&a);
   int const i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 2u)];
+  (*p)[0u] = 42;
 }
 
 void no_deref_let() {
   int3 a = 0;
   thread int3* const p = (&a);
   int const i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 2u)];
+  (*p)[0u] = 42;
 }
 
 void deref_var() {
   int3 a = 0;
   thread int3* const p = (&a);
   int i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 2u)];
+  (*p)[0u] = 42;
 }
 
 void no_deref_var() {
   int3 a = 0;
   thread int3* const p = (&a);
   int const i = 0;
-  int b = (*p)[i];
-  (*p)[0] = 42;
+  int b = (*p)[min(uint(i), 2u)];
+  (*p)[0u] = 42;
 }
 
 kernel void tint_symbol() {
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.msl b/test/tint/ptr_sugar/vector_index.wgsl.expected.msl
index 2d99f38..dbb1053 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.msl
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.msl
@@ -16,28 +16,28 @@
 void deref_let() {
   int3 a = 0;
   int const i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_let() {
   int3 a = 0;
   int const i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void deref_var() {
   int3 a = 0;
   int i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
 void no_deref_var() {
   int3 a = 0;
   int const i = 0;
-  int b = a[i];
+  int b = a[min(uint(i), 2u)];
   a[0] = 42;
 }
 
diff --git a/test/tint/ptr_sugar/vector_index.wgsl.expected.spvasm b/test/tint/ptr_sugar/vector_index.wgsl.expected.spvasm
index f7747b6..9827c24 100644
--- a/test/tint/ptr_sugar/vector_index.wgsl.expected.spvasm
+++ b/test/tint/ptr_sugar/vector_index.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 62
+; Bound: 74
 ; Schema: 0
                OpCapability Shader
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -43,84 +44,95 @@
 %_ptr_Function_v3int = OpTypePointer Function %v3int
           %9 = OpConstantNull %v3int
 %_ptr_Function_int = OpTypePointer Function %int
-          %i = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %uint_0 = OpConstant %uint 0
      %int_42 = OpConstant %int 42
+          %i = OpConstant %int 0
+     %uint_2 = OpConstant %uint 2
 %deref_const = OpFunction %void None %3
           %4 = OpLabel
           %a = OpVariable %_ptr_Function_v3int Function %9
           %b = OpVariable %_ptr_Function_int Function
-         %10 = OpAccessChain %_ptr_Function_int %a %i
-         %13 = OpLoad %int %10 None
-               OpStore %b %13
-         %15 = OpAccessChain %_ptr_Function_int %a %i
-               OpStore %15 %int_42 None
+         %10 = OpAccessChain %_ptr_Function_int %a %uint_0
+         %14 = OpLoad %int %10 None
+               OpStore %b %14
+         %16 = OpAccessChain %_ptr_Function_int %a %uint_0
+               OpStore %16 %int_42 None
                OpReturn
                OpFunctionEnd
 %no_deref_const = OpFunction %void None %3
-         %18 = OpLabel
+         %19 = OpLabel
         %a_0 = OpVariable %_ptr_Function_v3int Function %9
         %b_0 = OpVariable %_ptr_Function_int Function
-         %20 = OpAccessChain %_ptr_Function_int %a_0 %i
-         %21 = OpLoad %int %20 None
-               OpStore %b_0 %21
-         %23 = OpAccessChain %_ptr_Function_int %a_0 %i
-               OpStore %23 %int_42 None
+         %21 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
+         %22 = OpLoad %int %21 None
+               OpStore %b_0 %22
+         %24 = OpAccessChain %_ptr_Function_int %a_0 %uint_0
+               OpStore %24 %int_42 None
                OpReturn
                OpFunctionEnd
   %deref_let = OpFunction %void None %3
-         %25 = OpLabel
+         %26 = OpLabel
         %a_1 = OpVariable %_ptr_Function_v3int Function %9
         %b_1 = OpVariable %_ptr_Function_int Function
-         %27 = OpAccessChain %_ptr_Function_int %a_1 %i
-         %28 = OpLoad %int %27 None
-               OpStore %b_1 %28
-         %30 = OpAccessChain %_ptr_Function_int %a_1 %i
-               OpStore %30 %int_42 None
+         %29 = OpBitcast %uint %i
+         %30 = OpExtInst %uint %31 UMin %29 %uint_2
+         %33 = OpAccessChain %_ptr_Function_int %a_1 %30
+         %34 = OpLoad %int %33 None
+               OpStore %b_1 %34
+         %36 = OpAccessChain %_ptr_Function_int %a_1 %uint_0
+               OpStore %36 %int_42 None
                OpReturn
                OpFunctionEnd
 %no_deref_let = OpFunction %void None %3
-         %32 = OpLabel
+         %38 = OpLabel
         %a_2 = OpVariable %_ptr_Function_v3int Function %9
         %b_2 = OpVariable %_ptr_Function_int Function
-         %34 = OpAccessChain %_ptr_Function_int %a_2 %i
-         %35 = OpLoad %int %34 None
-               OpStore %b_2 %35
-         %37 = OpAccessChain %_ptr_Function_int %a_2 %i
-               OpStore %37 %int_42 None
+         %40 = OpBitcast %uint %i
+         %41 = OpExtInst %uint %31 UMin %40 %uint_2
+         %42 = OpAccessChain %_ptr_Function_int %a_2 %41
+         %43 = OpLoad %int %42 None
+               OpStore %b_2 %43
+         %45 = OpAccessChain %_ptr_Function_int %a_2 %uint_0
+               OpStore %45 %int_42 None
                OpReturn
                OpFunctionEnd
   %deref_var = OpFunction %void None %3
-         %39 = OpLabel
+         %47 = OpLabel
         %a_3 = OpVariable %_ptr_Function_v3int Function %9
         %i_0 = OpVariable %_ptr_Function_int Function
         %b_3 = OpVariable %_ptr_Function_int Function
                OpStore %i_0 %i
-         %42 = OpLoad %int %i_0 None
-         %43 = OpAccessChain %_ptr_Function_int %a_3 %42
-         %44 = OpLoad %int %43 None
-               OpStore %b_3 %44
-         %46 = OpAccessChain %_ptr_Function_int %a_3 %i
-               OpStore %46 %int_42 None
+         %50 = OpLoad %int %i_0 None
+         %51 = OpBitcast %uint %50
+         %52 = OpExtInst %uint %31 UMin %51 %uint_2
+         %53 = OpAccessChain %_ptr_Function_int %a_3 %52
+         %54 = OpLoad %int %53 None
+               OpStore %b_3 %54
+         %56 = OpAccessChain %_ptr_Function_int %a_3 %uint_0
+               OpStore %56 %int_42 None
                OpReturn
                OpFunctionEnd
 %no_deref_var = OpFunction %void None %3
-         %48 = OpLabel
+         %58 = OpLabel
         %a_4 = OpVariable %_ptr_Function_v3int Function %9
         %b_4 = OpVariable %_ptr_Function_int Function
-         %50 = OpAccessChain %_ptr_Function_int %a_4 %i
-         %51 = OpLoad %int %50 None
-               OpStore %b_4 %51
-         %53 = OpAccessChain %_ptr_Function_int %a_4 %i
-               OpStore %53 %int_42 None
+         %60 = OpBitcast %uint %i
+         %61 = OpExtInst %uint %31 UMin %60 %uint_2
+         %62 = OpAccessChain %_ptr_Function_int %a_4 %61
+         %63 = OpLoad %int %62 None
+               OpStore %b_4 %63
+         %65 = OpAccessChain %_ptr_Function_int %a_4 %uint_0
+               OpStore %65 %int_42 None
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %3
-         %55 = OpLabel
-         %56 = OpFunctionCall %void %deref_const
-         %57 = OpFunctionCall %void %no_deref_const
-         %58 = OpFunctionCall %void %deref_let
-         %59 = OpFunctionCall %void %no_deref_let
-         %60 = OpFunctionCall %void %deref_var
-         %61 = OpFunctionCall %void %no_deref_var
+         %67 = OpLabel
+         %68 = OpFunctionCall %void %deref_const
+         %69 = OpFunctionCall %void %no_deref_const
+         %70 = OpFunctionCall %void %deref_let
+         %71 = OpFunctionCall %void %no_deref_let
+         %72 = OpFunctionCall %void %deref_var
+         %73 = OpFunctionCall %void %no_deref_var
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/samples/compute_boids.wgsl.expected.dxc.hlsl b/test/tint/samples/compute_boids.wgsl.expected.dxc.hlsl
index 0ac0dbe..09a92bd 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.dxc.hlsl
+++ b/test/tint/samples/compute_boids.wgsl.expected.dxc.hlsl
@@ -50,8 +50,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = asfloat(particlesA.Load2((16u * index)));
-  float2 vVel = asfloat(particlesA.Load2(((16u * index) + 8u)));
+  float2 vPos = asfloat(particlesA.Load2((16u * min(index, 4u))));
+  float2 vVel = asfloat(particlesA.Load2(((16u * min(index, 4u)) + 8u)));
   float2 cMass = (0.0f).xx;
   float2 cVel = (0.0f).xx;
   float2 colVel = (0.0f).xx;
@@ -64,8 +64,8 @@
       if ((i == index)) {
         continue;
       }
-      pos = asfloat(particlesA.Load2((16u * i))).xy;
-      vel = asfloat(particlesA.Load2(((16u * i) + 8u))).xy;
+      pos = asfloat(particlesA.Load2((16u * min(i, 4u)))).xy;
+      vel = asfloat(particlesA.Load2(((16u * min(i, 4u)) + 8u))).xy;
       if ((distance(pos, vPos) < asfloat(params[0].y))) {
         cMass = (cMass + pos);
         cMassCount = (cMassCount + 1);
@@ -100,8 +100,8 @@
   if ((vPos.y > 1.0f)) {
     vPos.y = -1.0f;
   }
-  particlesB.Store2((16u * index), asuint(vPos));
-  particlesB.Store2(((16u * index) + 8u), asuint(vVel));
+  particlesB.Store2((16u * min(index, 4u)), asuint(vPos));
+  particlesB.Store2(((16u * min(index, 4u)) + 8u), asuint(vVel));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/samples/compute_boids.wgsl.expected.fxc.hlsl b/test/tint/samples/compute_boids.wgsl.expected.fxc.hlsl
index 0ac0dbe..09a92bd 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.fxc.hlsl
+++ b/test/tint/samples/compute_boids.wgsl.expected.fxc.hlsl
@@ -50,8 +50,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = asfloat(particlesA.Load2((16u * index)));
-  float2 vVel = asfloat(particlesA.Load2(((16u * index) + 8u)));
+  float2 vPos = asfloat(particlesA.Load2((16u * min(index, 4u))));
+  float2 vVel = asfloat(particlesA.Load2(((16u * min(index, 4u)) + 8u)));
   float2 cMass = (0.0f).xx;
   float2 cVel = (0.0f).xx;
   float2 colVel = (0.0f).xx;
@@ -64,8 +64,8 @@
       if ((i == index)) {
         continue;
       }
-      pos = asfloat(particlesA.Load2((16u * i))).xy;
-      vel = asfloat(particlesA.Load2(((16u * i) + 8u))).xy;
+      pos = asfloat(particlesA.Load2((16u * min(i, 4u)))).xy;
+      vel = asfloat(particlesA.Load2(((16u * min(i, 4u)) + 8u))).xy;
       if ((distance(pos, vPos) < asfloat(params[0].y))) {
         cMass = (cMass + pos);
         cMassCount = (cMassCount + 1);
@@ -100,8 +100,8 @@
   if ((vPos.y > 1.0f)) {
     vPos.y = -1.0f;
   }
-  particlesB.Store2((16u * index), asuint(vPos));
-  particlesB.Store2(((16u * index) + 8u), asuint(vVel));
+  particlesB.Store2((16u * min(index, 4u)), asuint(vPos));
+  particlesB.Store2(((16u * min(index, 4u)) + 8u), asuint(vVel));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/samples/compute_boids.wgsl.expected.glsl b/test/tint/samples/compute_boids.wgsl.expected.glsl
index bffa33d..5d2b5c8 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.glsl
+++ b/test/tint/samples/compute_boids.wgsl.expected.glsl
@@ -64,9 +64,9 @@
   if ((index >= 5u)) {
     return;
   }
-  uint v_3 = index;
+  uint v_3 = min(index, 4u);
   vec2 vPos = v_1.inner.particles[v_3].pos;
-  uint v_4 = index;
+  uint v_4 = min(index, 4u);
   vec2 vVel = v_1.inner.particles[v_4].vel;
   vec2 cMass = vec2(0.0f);
   vec2 cVel = vec2(0.0f);
@@ -88,9 +88,9 @@
         }
         continue;
       }
-      uint v_5 = i;
+      uint v_5 = min(i, 4u);
       pos = v_1.inner.particles[v_5].pos.xy;
-      uint v_6 = i;
+      uint v_6 = min(i, 4u);
       vel = v_1.inner.particles[v_6].vel.xy;
       if ((distance(pos, vPos) < v.inner.rule1Distance)) {
         cMass = (cMass + pos);
@@ -135,9 +135,9 @@
   if ((vPos.y > 1.0f)) {
     vPos[1u] = -1.0f;
   }
-  uint v_12 = index;
+  uint v_12 = min(index, 4u);
   v_2.inner.particles[v_12].pos = vPos;
-  uint v_13 = index;
+  uint v_13 = min(index, 4u);
   v_2.inner.particles[v_13].vel = vVel;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/samples/compute_boids.wgsl.expected.ir.dxc.hlsl b/test/tint/samples/compute_boids.wgsl.expected.ir.dxc.hlsl
index 90ba35a..487a8d2 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/samples/compute_boids.wgsl.expected.ir.dxc.hlsl
@@ -37,8 +37,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = asfloat(particlesA.Load2((0u + (index * 16u))));
-  float2 vVel = asfloat(particlesA.Load2((8u + (index * 16u))));
+  float2 vPos = asfloat(particlesA.Load2((0u + (min(index, 4u) * 16u))));
+  float2 vVel = asfloat(particlesA.Load2((8u + (min(index, 4u) * 16u))));
   float2 cMass = (0.0f).xx;
   float2 cVel = (0.0f).xx;
   float2 colVel = (0.0f).xx;
@@ -59,8 +59,8 @@
         }
         continue;
       }
-      pos = asfloat(particlesA.Load2((0u + (i * 16u)))).xy;
-      vel = asfloat(particlesA.Load2((8u + (i * 16u)))).xy;
+      pos = asfloat(particlesA.Load2((0u + (min(i, 4u) * 16u)))).xy;
+      vel = asfloat(particlesA.Load2((8u + (min(i, 4u) * 16u)))).xy;
       if ((distance(pos, vPos) < asfloat(params[0u].y))) {
         cMass = (cMass + pos);
         cMassCount = (cMassCount + int(1));
@@ -104,8 +104,8 @@
   if ((vPos.y > 1.0f)) {
     vPos.y = -1.0f;
   }
-  particlesB.Store2((0u + (index * 16u)), asuint(vPos));
-  particlesB.Store2((8u + (index * 16u)), asuint(vVel));
+  particlesB.Store2((0u + (min(index, 4u) * 16u)), asuint(vPos));
+  particlesB.Store2((8u + (min(index, 4u) * 16u)), asuint(vVel));
 }
 
 vert_main_outputs vert_main(vert_main_inputs inputs) {
diff --git a/test/tint/samples/compute_boids.wgsl.expected.ir.fxc.hlsl b/test/tint/samples/compute_boids.wgsl.expected.ir.fxc.hlsl
index 90ba35a..487a8d2 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/samples/compute_boids.wgsl.expected.ir.fxc.hlsl
@@ -37,8 +37,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = asfloat(particlesA.Load2((0u + (index * 16u))));
-  float2 vVel = asfloat(particlesA.Load2((8u + (index * 16u))));
+  float2 vPos = asfloat(particlesA.Load2((0u + (min(index, 4u) * 16u))));
+  float2 vVel = asfloat(particlesA.Load2((8u + (min(index, 4u) * 16u))));
   float2 cMass = (0.0f).xx;
   float2 cVel = (0.0f).xx;
   float2 colVel = (0.0f).xx;
@@ -59,8 +59,8 @@
         }
         continue;
       }
-      pos = asfloat(particlesA.Load2((0u + (i * 16u)))).xy;
-      vel = asfloat(particlesA.Load2((8u + (i * 16u)))).xy;
+      pos = asfloat(particlesA.Load2((0u + (min(i, 4u) * 16u)))).xy;
+      vel = asfloat(particlesA.Load2((8u + (min(i, 4u) * 16u)))).xy;
       if ((distance(pos, vPos) < asfloat(params[0u].y))) {
         cMass = (cMass + pos);
         cMassCount = (cMassCount + int(1));
@@ -104,8 +104,8 @@
   if ((vPos.y > 1.0f)) {
     vPos.y = -1.0f;
   }
-  particlesB.Store2((0u + (index * 16u)), asuint(vPos));
-  particlesB.Store2((8u + (index * 16u)), asuint(vVel));
+  particlesB.Store2((0u + (min(index, 4u) * 16u)), asuint(vPos));
+  particlesB.Store2((8u + (min(index, 4u) * 16u)), asuint(vVel));
 }
 
 vert_main_outputs vert_main(vert_main_inputs inputs) {
diff --git a/test/tint/samples/compute_boids.wgsl.expected.ir.msl b/test/tint/samples/compute_boids.wgsl.expected.ir.msl
index 648fa23..e2e915a 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.ir.msl
+++ b/test/tint/samples/compute_boids.wgsl.expected.ir.msl
@@ -67,8 +67,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = (*tint_module_vars.particlesA).particles[index].pos;
-  float2 vVel = (*tint_module_vars.particlesA).particles[index].vel;
+  float2 vPos = (*tint_module_vars.particlesA).particles[min(index, 4u)].pos;
+  float2 vVel = (*tint_module_vars.particlesA).particles[min(index, 4u)].vel;
   float2 cMass = float2(0.0f);
   float2 cVel = float2(0.0f);
   float2 colVel = float2(0.0f);
@@ -89,8 +89,8 @@
         }
         continue;
       }
-      pos = (*tint_module_vars.particlesA).particles[i].pos.xy;
-      vel = (*tint_module_vars.particlesA).particles[i].vel.xy;
+      pos = (*tint_module_vars.particlesA).particles[min(i, 4u)].pos.xy;
+      vel = (*tint_module_vars.particlesA).particles[min(i, 4u)].vel.xy;
       if ((distance(pos, vPos) < (*tint_module_vars.params).rule1Distance)) {
         cMass = (cMass + pos);
         cMassCount = as_type<int>((as_type<uint>(cMassCount) + as_type<uint>(1)));
@@ -134,8 +134,8 @@
   if ((vPos[1u] > 1.0f)) {
     vPos[1u] = -1.0f;
   }
-  (*tint_module_vars.particlesB).particles[index].pos = vPos;
-  (*tint_module_vars.particlesB).particles[index].vel = vVel;
+  (*tint_module_vars.particlesB).particles[min(index, 4u)].pos = vPos;
+  (*tint_module_vars.particlesB).particles[min(index, 4u)].vel = vVel;
 }
 
 vertex vert_main_outputs vert_main(vert_main_inputs inputs [[stage_in]]) {
diff --git a/test/tint/samples/compute_boids.wgsl.expected.msl b/test/tint/samples/compute_boids.wgsl.expected.msl
index dd67382..5a9c9b6 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.msl
+++ b/test/tint/samples/compute_boids.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_1 {
   float2 a_particlePos [[attribute(0)]];
   float2 a_particleVel [[attribute(1)]];
@@ -76,8 +79,8 @@
   if ((index >= 5u)) {
     return;
   }
-  float2 vPos = (*(tint_symbol_4)).particles[index].pos;
-  float2 vVel = (*(tint_symbol_4)).particles[index].vel;
+  float2 vPos = (*(tint_symbol_4)).particles[min(index, 4u)].pos;
+  float2 vVel = (*(tint_symbol_4)).particles[min(index, 4u)].vel;
   float2 cMass = float2(0.0f);
   float2 cVel = float2(0.0f);
   float2 colVel = float2(0.0f);
@@ -86,11 +89,12 @@
   float2 pos = 0.0f;
   float2 vel = 0.0f;
   for(uint i = 0u; (i < 5u); i = (i + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     if ((i == index)) {
       continue;
     }
-    pos = (*(tint_symbol_4)).particles[i].pos.xy;
-    vel = (*(tint_symbol_4)).particles[i].vel.xy;
+    pos = (*(tint_symbol_4)).particles[min(i, 4u)].pos.xy;
+    vel = (*(tint_symbol_4)).particles[min(i, 4u)].vel.xy;
     if ((distance(pos, vPos) < (*(tint_symbol_5)).rule1Distance)) {
       cMass = (cMass + pos);
       cMassCount = as_type<int>((as_type<uint>(cMassCount) + as_type<uint>(1)));
@@ -124,8 +128,8 @@
   if ((vPos[1] > 1.0f)) {
     vPos[1] = -1.0f;
   }
-  (*(tint_symbol_6)).particles[index].pos = vPos;
-  (*(tint_symbol_6)).particles[index].vel = vVel;
+  (*(tint_symbol_6)).particles[min(index, 4u)].pos = vPos;
+  (*(tint_symbol_6)).particles[min(index, 4u)].vel = vVel;
 }
 
 kernel void comp_main(device Particles* tint_symbol_7 [[buffer(1)]], const constant SimParams* tint_symbol_8 [[buffer(0)]], device Particles* tint_symbol_9 [[buffer(2)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) {
diff --git a/test/tint/samples/compute_boids.wgsl.expected.spvasm b/test/tint/samples/compute_boids.wgsl.expected.spvasm
index 456e402..da38485 100644
--- a/test/tint/samples/compute_boids.wgsl.expected.spvasm
+++ b/test/tint/samples/compute_boids.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 277
+; Bound: 283
 ; Schema: 0
                OpCapability Shader
          %40 = OpExtInstImport "GLSL.std.450"
@@ -134,10 +134,11 @@
          %77 = OpTypeFunction %void %v3uint
 %_ptr_Function_uint = OpTypePointer Function %uint
        %bool = OpTypeBool
+     %uint_4 = OpConstant %uint 4
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
-         %99 = OpConstantNull %v2float
+        %102 = OpConstantNull %v2float
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
@@ -145,11 +146,10 @@
       %int_1 = OpConstant %int 1
      %uint_2 = OpConstant %uint 2
      %uint_3 = OpConstant %uint 3
-     %uint_4 = OpConstant %uint 4
      %uint_6 = OpConstant %uint 6
 %float_0_100000001 = OpConstant %float 0.100000001
    %float_n1 = OpConstant %float -1
-        %264 = OpTypeFunction %void
+        %270 = OpTypeFunction %void
 %vert_main_inner = OpFunction %v4float None %35
 %a_particlePos = OpFunctionParameter %v2float
 %a_particleVel = OpFunctionParameter %v2float
@@ -202,8 +202,8 @@
      %colVel = OpVariable %_ptr_Function_v2float Function
  %cMassCount = OpVariable %_ptr_Function_int Function
   %cVelCount = OpVariable %_ptr_Function_int Function
-      %pos_0 = OpVariable %_ptr_Function_v2float Function %99
-        %vel = OpVariable %_ptr_Function_v2float Function %99
+      %pos_0 = OpVariable %_ptr_Function_v2float Function %102
+        %vel = OpVariable %_ptr_Function_v2float Function %102
           %i = OpVariable %_ptr_Function_uint Function
          %79 = OpCompositeExtract %uint %gl_GlobalInvocationID 0
                OpStore %index %79
@@ -215,243 +215,249 @@
                OpReturn
          %85 = OpLabel
          %87 = OpLoad %uint %index None
-         %88 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %87 %uint_0
-         %91 = OpLoad %v2float %88 None
-               OpStore %vPos %91
-         %93 = OpLoad %uint %index None
-         %94 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %93 %uint_1
-         %96 = OpLoad %v2float %94 None
-               OpStore %vVel %96
-               OpStore %cMass %99
-               OpStore %cVel %99
-               OpStore %colVel %99
+         %88 = OpExtInst %uint %40 UMin %87 %uint_4
+         %90 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %88 %uint_0
+         %93 = OpLoad %v2float %90 None
+               OpStore %vPos %93
+         %95 = OpLoad %uint %index None
+         %96 = OpExtInst %uint %40 UMin %95 %uint_4
+         %97 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %96 %uint_1
+         %99 = OpLoad %v2float %97 None
+               OpStore %vVel %99
+               OpStore %cMass %102
+               OpStore %cVel %102
+               OpStore %colVel %102
                OpStore %cMassCount %int_0
                OpStore %cVelCount %int_0
-               OpBranch %109
-        %109 = OpLabel
-               OpStore %i %uint_0
                OpBranch %112
         %112 = OpLabel
-               OpLoopMerge %113 %111 None
-               OpBranch %110
-        %110 = OpLabel
-        %115 = OpLoad %uint %i None
-        %116 = OpULessThan %bool %115 %uint_5
-               OpSelectionMerge %117 None
-               OpBranchConditional %116 %117 %118
-        %118 = OpLabel
+               OpStore %i %uint_0
+               OpBranch %115
+        %115 = OpLabel
+               OpLoopMerge %116 %114 None
                OpBranch %113
-        %117 = OpLabel
-        %119 = OpLoad %uint %i None
-        %120 = OpLoad %uint %index None
-        %121 = OpIEqual %bool %119 %120
-               OpSelectionMerge %122 None
-               OpBranchConditional %121 %123 %122
-        %123 = OpLabel
-               OpBranch %111
-        %122 = OpLabel
-        %124 = OpLoad %uint %i None
-        %125 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %124 %uint_0
-        %126 = OpLoad %v2float %125 None
-        %127 = OpVectorShuffle %v2float %126 %126 0 1
-               OpStore %pos_0 %127 None
-        %128 = OpLoad %uint %i None
-        %129 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %128 %uint_1
+        %113 = OpLabel
+        %118 = OpLoad %uint %i None
+        %119 = OpULessThan %bool %118 %uint_5
+               OpSelectionMerge %120 None
+               OpBranchConditional %119 %120 %121
+        %121 = OpLabel
+               OpBranch %116
+        %120 = OpLabel
+        %122 = OpLoad %uint %i None
+        %123 = OpLoad %uint %index None
+        %124 = OpIEqual %bool %122 %123
+               OpSelectionMerge %125 None
+               OpBranchConditional %124 %126 %125
+        %126 = OpLabel
+               OpBranch %114
+        %125 = OpLabel
+        %127 = OpLoad %uint %i None
+        %128 = OpExtInst %uint %40 UMin %127 %uint_4
+        %129 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %128 %uint_0
         %130 = OpLoad %v2float %129 None
         %131 = OpVectorShuffle %v2float %130 %130 0 1
-               OpStore %vel %131 None
-        %132 = OpLoad %v2float %pos_0 None
-        %133 = OpLoad %v2float %vPos None
-        %134 = OpExtInst %float %40 Distance %132 %133
-        %135 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_1
-        %137 = OpLoad %float %135 None
-        %138 = OpFOrdLessThan %bool %134 %137
-               OpSelectionMerge %139 None
-               OpBranchConditional %138 %140 %139
-        %140 = OpLabel
-        %141 = OpLoad %v2float %cMass None
-        %142 = OpLoad %v2float %pos_0 None
-        %143 = OpFAdd %v2float %141 %142
-               OpStore %cMass %143 None
-        %144 = OpLoad %int %cMassCount None
-        %145 = OpIAdd %int %144 %int_1
-               OpStore %cMassCount %145 None
-               OpBranch %139
-        %139 = OpLabel
+               OpStore %pos_0 %131 None
+        %132 = OpLoad %uint %i None
+        %133 = OpExtInst %uint %40 UMin %132 %uint_4
+        %134 = OpAccessChain %_ptr_StorageBuffer_v2float %6 %uint_0 %uint_0 %133 %uint_1
+        %135 = OpLoad %v2float %134 None
+        %136 = OpVectorShuffle %v2float %135 %135 0 1
+               OpStore %vel %136 None
+        %137 = OpLoad %v2float %pos_0 None
+        %138 = OpLoad %v2float %vPos None
+        %139 = OpExtInst %float %40 Distance %137 %138
+        %140 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_1
+        %142 = OpLoad %float %140 None
+        %143 = OpFOrdLessThan %bool %139 %142
+               OpSelectionMerge %144 None
+               OpBranchConditional %143 %145 %144
+        %145 = OpLabel
+        %146 = OpLoad %v2float %cMass None
         %147 = OpLoad %v2float %pos_0 None
-        %148 = OpLoad %v2float %vPos None
-        %149 = OpExtInst %float %40 Distance %147 %148
-        %150 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_2
-        %152 = OpLoad %float %150 None
-        %153 = OpFOrdLessThan %bool %149 %152
-               OpSelectionMerge %154 None
-               OpBranchConditional %153 %155 %154
-        %155 = OpLabel
-        %156 = OpLoad %v2float %colVel None
-        %157 = OpLoad %v2float %pos_0 None
-        %158 = OpLoad %v2float %vPos None
-        %159 = OpFSub %v2float %157 %158
-        %160 = OpFSub %v2float %156 %159
-               OpStore %colVel %160 None
-               OpBranch %154
-        %154 = OpLabel
-        %161 = OpLoad %v2float %pos_0 None
-        %162 = OpLoad %v2float %vPos None
-        %163 = OpExtInst %float %40 Distance %161 %162
-        %164 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_3
-        %166 = OpLoad %float %164 None
-        %167 = OpFOrdLessThan %bool %163 %166
-               OpSelectionMerge %168 None
-               OpBranchConditional %167 %169 %168
-        %169 = OpLabel
-        %170 = OpLoad %v2float %cVel None
-        %171 = OpLoad %v2float %vel None
-        %172 = OpFAdd %v2float %170 %171
-               OpStore %cVel %172 None
-        %173 = OpLoad %int %cVelCount None
-        %174 = OpIAdd %int %173 %int_1
-               OpStore %cVelCount %174 None
-               OpBranch %168
-        %168 = OpLabel
-               OpBranch %111
-        %111 = OpLabel
-        %175 = OpLoad %uint %i None
-        %176 = OpIAdd %uint %175 %uint_1
-               OpStore %i %176 None
-               OpBranch %112
-        %113 = OpLabel
-        %177 = OpLoad %int %cMassCount None
-        %178 = OpSGreaterThan %bool %177 %int_0
-               OpSelectionMerge %179 None
-               OpBranchConditional %178 %180 %179
-        %180 = OpLabel
-        %181 = OpLoad %v2float %cMass None
+        %148 = OpFAdd %v2float %146 %147
+               OpStore %cMass %148 None
+        %149 = OpLoad %int %cMassCount None
+        %150 = OpIAdd %int %149 %int_1
+               OpStore %cMassCount %150 None
+               OpBranch %144
+        %144 = OpLabel
+        %152 = OpLoad %v2float %pos_0 None
+        %153 = OpLoad %v2float %vPos None
+        %154 = OpExtInst %float %40 Distance %152 %153
+        %155 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_2
+        %157 = OpLoad %float %155 None
+        %158 = OpFOrdLessThan %bool %154 %157
+               OpSelectionMerge %159 None
+               OpBranchConditional %158 %160 %159
+        %160 = OpLabel
+        %161 = OpLoad %v2float %colVel None
+        %162 = OpLoad %v2float %pos_0 None
+        %163 = OpLoad %v2float %vPos None
+        %164 = OpFSub %v2float %162 %163
+        %165 = OpFSub %v2float %161 %164
+               OpStore %colVel %165 None
+               OpBranch %159
+        %159 = OpLabel
+        %166 = OpLoad %v2float %pos_0 None
+        %167 = OpLoad %v2float %vPos None
+        %168 = OpExtInst %float %40 Distance %166 %167
+        %169 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_3
+        %171 = OpLoad %float %169 None
+        %172 = OpFOrdLessThan %bool %168 %171
+               OpSelectionMerge %173 None
+               OpBranchConditional %172 %174 %173
+        %174 = OpLabel
+        %175 = OpLoad %v2float %cVel None
+        %176 = OpLoad %v2float %vel None
+        %177 = OpFAdd %v2float %175 %176
+               OpStore %cVel %177 None
+        %178 = OpLoad %int %cVelCount None
+        %179 = OpIAdd %int %178 %int_1
+               OpStore %cVelCount %179 None
+               OpBranch %173
+        %173 = OpLabel
+               OpBranch %114
+        %114 = OpLabel
+        %180 = OpLoad %uint %i None
+        %181 = OpIAdd %uint %180 %uint_1
+               OpStore %i %181 None
+               OpBranch %115
+        %116 = OpLabel
         %182 = OpLoad %int %cMassCount None
-        %183 = OpConvertSToF %float %182
-        %184 = OpLoad %int %cMassCount None
-        %185 = OpConvertSToF %float %184
-        %186 = OpCompositeConstruct %v2float %183 %185
-        %187 = OpFDiv %v2float %181 %186
-        %188 = OpLoad %v2float %vPos None
-        %189 = OpFSub %v2float %187 %188
-               OpStore %cMass %189 None
-               OpBranch %179
-        %179 = OpLabel
-        %190 = OpLoad %int %cVelCount None
-        %191 = OpSGreaterThan %bool %190 %int_0
-               OpSelectionMerge %192 None
-               OpBranchConditional %191 %193 %192
-        %193 = OpLabel
-        %194 = OpLoad %v2float %cVel None
+        %183 = OpSGreaterThan %bool %182 %int_0
+               OpSelectionMerge %184 None
+               OpBranchConditional %183 %185 %184
+        %185 = OpLabel
+        %186 = OpLoad %v2float %cMass None
+        %187 = OpLoad %int %cMassCount None
+        %188 = OpConvertSToF %float %187
+        %189 = OpLoad %int %cMassCount None
+        %190 = OpConvertSToF %float %189
+        %191 = OpCompositeConstruct %v2float %188 %190
+        %192 = OpFDiv %v2float %186 %191
+        %193 = OpLoad %v2float %vPos None
+        %194 = OpFSub %v2float %192 %193
+               OpStore %cMass %194 None
+               OpBranch %184
+        %184 = OpLabel
         %195 = OpLoad %int %cVelCount None
-        %196 = OpConvertSToF %float %195
-        %197 = OpLoad %int %cVelCount None
-        %198 = OpConvertSToF %float %197
-        %199 = OpCompositeConstruct %v2float %196 %198
-        %200 = OpFDiv %v2float %194 %199
-               OpStore %cVel %200 None
-               OpBranch %192
-        %192 = OpLabel
-        %201 = OpLoad %v2float %vVel None
-        %202 = OpLoad %v2float %cMass None
-        %203 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_4
-        %205 = OpLoad %float %203 None
-        %206 = OpVectorTimesScalar %v2float %202 %205
-        %207 = OpFAdd %v2float %201 %206
-        %208 = OpLoad %v2float %colVel None
-        %209 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_5
-        %210 = OpLoad %float %209 None
-        %211 = OpVectorTimesScalar %v2float %208 %210
-        %212 = OpFAdd %v2float %207 %211
-        %213 = OpLoad %v2float %cVel None
-        %214 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_6
-        %216 = OpLoad %float %214 None
-        %217 = OpVectorTimesScalar %v2float %213 %216
-        %218 = OpFAdd %v2float %212 %217
-               OpStore %vVel %218 None
-        %219 = OpLoad %v2float %vVel None
-        %220 = OpExtInst %v2float %40 Normalize %219
-        %221 = OpLoad %v2float %vVel None
-        %222 = OpExtInst %float %40 Length %221
-        %223 = OpExtInst %float %40 NClamp %222 %float_0 %float_0_100000001
-        %225 = OpVectorTimesScalar %v2float %220 %223
-               OpStore %vVel %225 None
-        %226 = OpLoad %v2float %vPos None
-        %227 = OpLoad %v2float %vVel None
-        %228 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0
-        %229 = OpLoad %float %228 None
-        %230 = OpVectorTimesScalar %v2float %227 %229
-        %231 = OpFAdd %v2float %226 %230
-               OpStore %vPos %231 None
-        %232 = OpAccessChain %_ptr_Function_float %vPos %uint_0
+        %196 = OpSGreaterThan %bool %195 %int_0
+               OpSelectionMerge %197 None
+               OpBranchConditional %196 %198 %197
+        %198 = OpLabel
+        %199 = OpLoad %v2float %cVel None
+        %200 = OpLoad %int %cVelCount None
+        %201 = OpConvertSToF %float %200
+        %202 = OpLoad %int %cVelCount None
+        %203 = OpConvertSToF %float %202
+        %204 = OpCompositeConstruct %v2float %201 %203
+        %205 = OpFDiv %v2float %199 %204
+               OpStore %cVel %205 None
+               OpBranch %197
+        %197 = OpLabel
+        %206 = OpLoad %v2float %vVel None
+        %207 = OpLoad %v2float %cMass None
+        %208 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_4
+        %209 = OpLoad %float %208 None
+        %210 = OpVectorTimesScalar %v2float %207 %209
+        %211 = OpFAdd %v2float %206 %210
+        %212 = OpLoad %v2float %colVel None
+        %213 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_5
+        %214 = OpLoad %float %213 None
+        %215 = OpVectorTimesScalar %v2float %212 %214
+        %216 = OpFAdd %v2float %211 %215
+        %217 = OpLoad %v2float %cVel None
+        %218 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_6
+        %220 = OpLoad %float %218 None
+        %221 = OpVectorTimesScalar %v2float %217 %220
+        %222 = OpFAdd %v2float %216 %221
+               OpStore %vVel %222 None
+        %223 = OpLoad %v2float %vVel None
+        %224 = OpExtInst %v2float %40 Normalize %223
+        %225 = OpLoad %v2float %vVel None
+        %226 = OpExtInst %float %40 Length %225
+        %227 = OpExtInst %float %40 NClamp %226 %float_0 %float_0_100000001
+        %229 = OpVectorTimesScalar %v2float %224 %227
+               OpStore %vVel %229 None
+        %230 = OpLoad %v2float %vPos None
+        %231 = OpLoad %v2float %vVel None
+        %232 = OpAccessChain %_ptr_Uniform_float %1 %uint_0 %uint_0
         %233 = OpLoad %float %232 None
-        %234 = OpFOrdLessThan %bool %233 %float_n1
-               OpSelectionMerge %236 None
-               OpBranchConditional %234 %237 %236
-        %237 = OpLabel
-        %238 = OpAccessChain %_ptr_Function_float %vPos %uint_0
-               OpStore %238 %float_1 None
-               OpBranch %236
-        %236 = OpLabel
-        %239 = OpAccessChain %_ptr_Function_float %vPos %uint_0
-        %240 = OpLoad %float %239 None
-        %241 = OpFOrdGreaterThan %bool %240 %float_1
-               OpSelectionMerge %242 None
-               OpBranchConditional %241 %243 %242
-        %243 = OpLabel
-        %244 = OpAccessChain %_ptr_Function_float %vPos %uint_0
-               OpStore %244 %float_n1 None
-               OpBranch %242
-        %242 = OpLabel
-        %245 = OpAccessChain %_ptr_Function_float %vPos %uint_1
-        %246 = OpLoad %float %245 None
-        %247 = OpFOrdLessThan %bool %246 %float_n1
-               OpSelectionMerge %248 None
-               OpBranchConditional %247 %249 %248
-        %249 = OpLabel
-        %250 = OpAccessChain %_ptr_Function_float %vPos %uint_1
-               OpStore %250 %float_1 None
-               OpBranch %248
-        %248 = OpLabel
-        %251 = OpAccessChain %_ptr_Function_float %vPos %uint_1
-        %252 = OpLoad %float %251 None
-        %253 = OpFOrdGreaterThan %bool %252 %float_1
-               OpSelectionMerge %254 None
-               OpBranchConditional %253 %255 %254
-        %255 = OpLabel
-        %256 = OpAccessChain %_ptr_Function_float %vPos %uint_1
-               OpStore %256 %float_n1 None
-               OpBranch %254
-        %254 = OpLabel
-        %257 = OpLoad %uint %index None
-        %258 = OpAccessChain %_ptr_StorageBuffer_v2float %15 %uint_0 %uint_0 %257 %uint_0
-        %259 = OpLoad %v2float %vPos None
-               OpStore %258 %259 None
-        %260 = OpLoad %uint %index None
-        %261 = OpAccessChain %_ptr_StorageBuffer_v2float %15 %uint_0 %uint_0 %260 %uint_1
-        %262 = OpLoad %v2float %vVel None
-               OpStore %261 %262 None
+        %234 = OpVectorTimesScalar %v2float %231 %233
+        %235 = OpFAdd %v2float %230 %234
+               OpStore %vPos %235 None
+        %236 = OpAccessChain %_ptr_Function_float %vPos %uint_0
+        %237 = OpLoad %float %236 None
+        %238 = OpFOrdLessThan %bool %237 %float_n1
+               OpSelectionMerge %240 None
+               OpBranchConditional %238 %241 %240
+        %241 = OpLabel
+        %242 = OpAccessChain %_ptr_Function_float %vPos %uint_0
+               OpStore %242 %float_1 None
+               OpBranch %240
+        %240 = OpLabel
+        %243 = OpAccessChain %_ptr_Function_float %vPos %uint_0
+        %244 = OpLoad %float %243 None
+        %245 = OpFOrdGreaterThan %bool %244 %float_1
+               OpSelectionMerge %246 None
+               OpBranchConditional %245 %247 %246
+        %247 = OpLabel
+        %248 = OpAccessChain %_ptr_Function_float %vPos %uint_0
+               OpStore %248 %float_n1 None
+               OpBranch %246
+        %246 = OpLabel
+        %249 = OpAccessChain %_ptr_Function_float %vPos %uint_1
+        %250 = OpLoad %float %249 None
+        %251 = OpFOrdLessThan %bool %250 %float_n1
+               OpSelectionMerge %252 None
+               OpBranchConditional %251 %253 %252
+        %253 = OpLabel
+        %254 = OpAccessChain %_ptr_Function_float %vPos %uint_1
+               OpStore %254 %float_1 None
+               OpBranch %252
+        %252 = OpLabel
+        %255 = OpAccessChain %_ptr_Function_float %vPos %uint_1
+        %256 = OpLoad %float %255 None
+        %257 = OpFOrdGreaterThan %bool %256 %float_1
+               OpSelectionMerge %258 None
+               OpBranchConditional %257 %259 %258
+        %259 = OpLabel
+        %260 = OpAccessChain %_ptr_Function_float %vPos %uint_1
+               OpStore %260 %float_n1 None
+               OpBranch %258
+        %258 = OpLabel
+        %261 = OpLoad %uint %index None
+        %262 = OpExtInst %uint %40 UMin %261 %uint_4
+        %263 = OpAccessChain %_ptr_StorageBuffer_v2float %15 %uint_0 %uint_0 %262 %uint_0
+        %264 = OpLoad %v2float %vPos None
+               OpStore %263 %264 None
+        %265 = OpLoad %uint %index None
+        %266 = OpExtInst %uint %40 UMin %265 %uint_4
+        %267 = OpAccessChain %_ptr_StorageBuffer_v2float %15 %uint_0 %uint_0 %266 %uint_1
+        %268 = OpLoad %v2float %vVel None
+               OpStore %267 %268 None
                OpReturn
                OpFunctionEnd
-  %vert_main = OpFunction %void None %264
-        %265 = OpLabel
-        %266 = OpLoad %v2float %vert_main_loc0_Input None
-        %267 = OpLoad %v2float %vert_main_loc1_Input None
-        %268 = OpLoad %v2float %vert_main_loc2_Input None
-        %269 = OpFunctionCall %v4float %vert_main_inner %266 %267 %268
-               OpStore %vert_main_position_Output %269 None
+  %vert_main = OpFunction %void None %270
+        %271 = OpLabel
+        %272 = OpLoad %v2float %vert_main_loc0_Input None
+        %273 = OpLoad %v2float %vert_main_loc1_Input None
+        %274 = OpLoad %v2float %vert_main_loc2_Input None
+        %275 = OpFunctionCall %v4float %vert_main_inner %272 %273 %274
+               OpStore %vert_main_position_Output %275 None
                OpStore %vert_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-  %frag_main = OpFunction %void None %264
-        %271 = OpLabel
-        %272 = OpFunctionCall %v4float %frag_main_inner
-               OpStore %frag_main_loc0_Output %272 None
+  %frag_main = OpFunction %void None %270
+        %277 = OpLabel
+        %278 = OpFunctionCall %v4float %frag_main_inner
+               OpStore %frag_main_loc0_Output %278 None
                OpReturn
                OpFunctionEnd
-  %comp_main = OpFunction %void None %264
-        %274 = OpLabel
-        %275 = OpLoad %v3uint %comp_main_global_invocation_id_Input None
-        %276 = OpFunctionCall %void %comp_main_inner %275
+  %comp_main = OpFunction %void None %270
+        %280 = OpLabel
+        %281 = OpLoad %v3uint %comp_main_global_invocation_id_Input None
+        %282 = OpFunctionCall %void %comp_main_inner %281
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/samples/triangle.wgsl.expected.dxc.hlsl b/test/tint/samples/triangle.wgsl.expected.dxc.hlsl
index 827cc24..de63c87 100644
--- a/test/tint/samples/triangle.wgsl.expected.dxc.hlsl
+++ b/test/tint/samples/triangle.wgsl.expected.dxc.hlsl
@@ -7,7 +7,7 @@
 
 float4 vtx_main_inner(uint VertexIndex) {
   float2 tint_symbol_4[3] = {float2(0.0f, 0.5f), (-0.5f).xx, float2(0.5f, -0.5f)};
-  return float4(tint_symbol_4[VertexIndex], 0.0f, 1.0f);
+  return float4(tint_symbol_4[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 tint_symbol_2 vtx_main(tint_symbol_1 tint_symbol) {
diff --git a/test/tint/samples/triangle.wgsl.expected.fxc.hlsl b/test/tint/samples/triangle.wgsl.expected.fxc.hlsl
index 827cc24..de63c87 100644
--- a/test/tint/samples/triangle.wgsl.expected.fxc.hlsl
+++ b/test/tint/samples/triangle.wgsl.expected.fxc.hlsl
@@ -7,7 +7,7 @@
 
 float4 vtx_main_inner(uint VertexIndex) {
   float2 tint_symbol_4[3] = {float2(0.0f, 0.5f), (-0.5f).xx, float2(0.5f, -0.5f)};
-  return float4(tint_symbol_4[VertexIndex], 0.0f, 1.0f);
+  return float4(tint_symbol_4[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 tint_symbol_2 vtx_main(tint_symbol_1 tint_symbol) {
diff --git a/test/tint/samples/triangle.wgsl.expected.glsl b/test/tint/samples/triangle.wgsl.expected.glsl
index 24571ad..065badf 100644
--- a/test/tint/samples/triangle.wgsl.expected.glsl
+++ b/test/tint/samples/triangle.wgsl.expected.glsl
@@ -1,7 +1,7 @@
 #version 310 es
 
 vec4 vtx_main_inner(uint VertexIndex) {
-  return vec4(vec2[3](vec2(0.0f, 0.5f), vec2(-0.5f), vec2(0.5f, -0.5f))[VertexIndex], 0.0f, 1.0f);
+  return vec4(vec2[3](vec2(0.0f, 0.5f), vec2(-0.5f), vec2(0.5f, -0.5f))[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 void main() {
   gl_Position = vtx_main_inner(uint(gl_VertexID));
diff --git a/test/tint/samples/triangle.wgsl.expected.ir.dxc.hlsl b/test/tint/samples/triangle.wgsl.expected.ir.dxc.hlsl
index cd0e6b2..f8c295e 100644
--- a/test/tint/samples/triangle.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/samples/triangle.wgsl.expected.ir.dxc.hlsl
@@ -13,7 +13,7 @@
 
 float4 vtx_main_inner(uint VertexIndex) {
   float2 v[3] = {float2(0.0f, 0.5f), (-0.5f).xx, float2(0.5f, -0.5f)};
-  return float4(v[VertexIndex], 0.0f, 1.0f);
+  return float4(v[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 float4 frag_main_inner() {
diff --git a/test/tint/samples/triangle.wgsl.expected.ir.fxc.hlsl b/test/tint/samples/triangle.wgsl.expected.ir.fxc.hlsl
index cd0e6b2..f8c295e 100644
--- a/test/tint/samples/triangle.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/samples/triangle.wgsl.expected.ir.fxc.hlsl
@@ -13,7 +13,7 @@
 
 float4 vtx_main_inner(uint VertexIndex) {
   float2 v[3] = {float2(0.0f, 0.5f), (-0.5f).xx, float2(0.5f, -0.5f)};
-  return float4(v[VertexIndex], 0.0f, 1.0f);
+  return float4(v[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 float4 frag_main_inner() {
diff --git a/test/tint/samples/triangle.wgsl.expected.ir.msl b/test/tint/samples/triangle.wgsl.expected.ir.msl
index 5756766..edb01bf 100644
--- a/test/tint/samples/triangle.wgsl.expected.ir.msl
+++ b/test/tint/samples/triangle.wgsl.expected.ir.msl
@@ -22,7 +22,7 @@
 };
 
 float4 vtx_main_inner(uint VertexIndex) {
-  return float4(tint_array<float2, 3>{float2(0.0f, 0.5f), float2(-0.5f), float2(0.5f, -0.5f)}[VertexIndex], 0.0f, 1.0f);
+  return float4(tint_array<float2, 3>{float2(0.0f, 0.5f), float2(-0.5f), float2(0.5f, -0.5f)}[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 float4 frag_main_inner() {
diff --git a/test/tint/samples/triangle.wgsl.expected.msl b/test/tint/samples/triangle.wgsl.expected.msl
index bac249a..46bebdd 100644
--- a/test/tint/samples/triangle.wgsl.expected.msl
+++ b/test/tint/samples/triangle.wgsl.expected.msl
@@ -20,7 +20,7 @@
 
 float4 vtx_main_inner(uint VertexIndex) {
   tint_array<float2, 3> const tint_symbol_2 = tint_array<float2, 3>{float2(0.0f, 0.5f), float2(-0.5f), float2(0.5f, -0.5f)};
-  return float4(tint_symbol_2[VertexIndex], 0.0f, 1.0f);
+  return float4(tint_symbol_2[min(VertexIndex, 2u)], 0.0f, 1.0f);
 }
 
 vertex tint_symbol vtx_main(uint VertexIndex [[vertex_id]]) {
diff --git a/test/tint/samples/triangle.wgsl.expected.spvasm b/test/tint/samples/triangle.wgsl.expected.spvasm
index be526d1..44ca888 100644
--- a/test/tint/samples/triangle.wgsl.expected.spvasm
+++ b/test/tint/samples/triangle.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 45
+; Bound: 48
 ; Schema: 0
                OpCapability Shader
+         %28 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Vertex %vtx_main "vtx_main" %vtx_main_vertex_index_Input %vtx_main_position_Output %vtx_main___point_size_Output
                OpEntryPoint Fragment %frag_main "frag_main" %frag_main_loc0_Output
@@ -45,35 +46,37 @@
          %16 = OpConstantComposite %_arr_v2float_uint_3 %17 %20 %22
          %11 = OpVariable %_ptr_Private__arr_v2float_uint_3 Private %16
          %25 = OpTypeFunction %v4float %uint
+     %uint_2 = OpConstant %uint 2
 %_ptr_Private_v2float = OpTypePointer Private %v2float
     %float_1 = OpConstant %float 1
-         %33 = OpTypeFunction %v4float
-         %35 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+         %36 = OpTypeFunction %v4float
+         %38 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
        %void = OpTypeVoid
-         %38 = OpTypeFunction %void
+         %41 = OpTypeFunction %void
 %vtx_main_inner = OpFunction %v4float None %25
 %VertexIndex = OpFunctionParameter %uint
          %26 = OpLabel
-         %27 = OpAccessChain %_ptr_Private_v2float %11 %VertexIndex
-         %29 = OpLoad %v2float %27 None
-         %30 = OpCompositeConstruct %v4float %29 %float_0 %float_1
-               OpReturnValue %30
+         %27 = OpExtInst %uint %28 UMin %VertexIndex %uint_2
+         %30 = OpAccessChain %_ptr_Private_v2float %11 %27
+         %32 = OpLoad %v2float %30 None
+         %33 = OpCompositeConstruct %v4float %32 %float_0 %float_1
+               OpReturnValue %33
                OpFunctionEnd
-%frag_main_inner = OpFunction %v4float None %33
-         %34 = OpLabel
-               OpReturnValue %35
+%frag_main_inner = OpFunction %v4float None %36
+         %37 = OpLabel
+               OpReturnValue %38
                OpFunctionEnd
-   %vtx_main = OpFunction %void None %38
-         %39 = OpLabel
-         %40 = OpLoad %uint %vtx_main_vertex_index_Input None
-         %41 = OpFunctionCall %v4float %vtx_main_inner %40
-               OpStore %vtx_main_position_Output %41 None
+   %vtx_main = OpFunction %void None %41
+         %42 = OpLabel
+         %43 = OpLoad %uint %vtx_main_vertex_index_Input None
+         %44 = OpFunctionCall %v4float %vtx_main_inner %43
+               OpStore %vtx_main_position_Output %44 None
                OpStore %vtx_main___point_size_Output %float_1 None
                OpReturn
                OpFunctionEnd
-  %frag_main = OpFunction %void None %38
-         %43 = OpLabel
-         %44 = OpFunctionCall %v4float %frag_main_inner
-               OpStore %frag_main_loc0_Output %44 None
+  %frag_main = OpFunction %void None %41
+         %46 = OpLabel
+         %47 = OpFunctionCall %v4float %frag_main_inner
+               OpStore %frag_main_loc0_Output %47 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/shadowing/loop.wgsl.expected.dxc.hlsl b/test/tint/shadowing/loop.wgsl.expected.dxc.hlsl
index 8be1d6f..eaabf87 100644
--- a/test/tint/shadowing/loop.wgsl.expected.dxc.hlsl
+++ b/test/tint/shadowing/loop.wgsl.expected.dxc.hlsl
@@ -4,9 +4,9 @@
 void foo() {
   int i = 0;
   while (true) {
-    int x = asint(output.Load((4u * uint(i))));
+    int x = asint(output.Load((4u * min(uint(i), 9u))));
     {
-      int x_1 = asint(output.Load((4u * uint(x))));
+      int x_1 = asint(output.Load((4u * min(uint(x), 9u))));
       i = (i + x_1);
       if ((i > 10)) { break; }
     }
diff --git a/test/tint/shadowing/loop.wgsl.expected.fxc.hlsl b/test/tint/shadowing/loop.wgsl.expected.fxc.hlsl
index 8be1d6f..eaabf87 100644
--- a/test/tint/shadowing/loop.wgsl.expected.fxc.hlsl
+++ b/test/tint/shadowing/loop.wgsl.expected.fxc.hlsl
@@ -4,9 +4,9 @@
 void foo() {
   int i = 0;
   while (true) {
-    int x = asint(output.Load((4u * uint(i))));
+    int x = asint(output.Load((4u * min(uint(i), 9u))));
     {
-      int x_1 = asint(output.Load((4u * uint(x))));
+      int x_1 = asint(output.Load((4u * min(uint(x), 9u))));
       i = (i + x_1);
       if ((i > 10)) { break; }
     }
diff --git a/test/tint/shadowing/loop.wgsl.expected.glsl b/test/tint/shadowing/loop.wgsl.expected.glsl
index 204ce0a..cb75b1d 100644
--- a/test/tint/shadowing/loop.wgsl.expected.glsl
+++ b/test/tint/shadowing/loop.wgsl.expected.glsl
@@ -9,10 +9,10 @@
   int i = 0;
   {
     while(true) {
-      int v_1 = i;
+      uint v_1 = min(uint(i), 9u);
       int x = v.inner[v_1];
       {
-        int v_2 = x;
+        uint v_2 = min(uint(x), 9u);
         int x_1 = v.inner[v_2];
         i = (i + x_1);
         if ((i > 10)) { break; }
@@ -20,5 +20,5 @@
       continue;
     }
   }
-  v.inner[0] = i;
+  v.inner[0u] = i;
 }
diff --git a/test/tint/shadowing/loop.wgsl.expected.ir.dxc.hlsl b/test/tint/shadowing/loop.wgsl.expected.ir.dxc.hlsl
index ac00424..67f1db9 100644
--- a/test/tint/shadowing/loop.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/shadowing/loop.wgsl.expected.ir.dxc.hlsl
@@ -5,9 +5,9 @@
   int i = int(0);
   {
     while(true) {
-      int x = asint(output.Load((0u + (uint(i) * 4u))));
+      int x = asint(output.Load((0u + (min(uint(i), 9u) * 4u))));
       {
-        int x_1 = asint(output.Load((0u + (uint(x) * 4u))));
+        int x_1 = asint(output.Load((0u + (min(uint(x), 9u) * 4u))));
         i = (i + x_1);
         if ((i > int(10))) { break; }
       }
diff --git a/test/tint/shadowing/loop.wgsl.expected.ir.fxc.hlsl b/test/tint/shadowing/loop.wgsl.expected.ir.fxc.hlsl
index ac00424..67f1db9 100644
--- a/test/tint/shadowing/loop.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/shadowing/loop.wgsl.expected.ir.fxc.hlsl
@@ -5,9 +5,9 @@
   int i = int(0);
   {
     while(true) {
-      int x = asint(output.Load((0u + (uint(i) * 4u))));
+      int x = asint(output.Load((0u + (min(uint(i), 9u) * 4u))));
       {
-        int x_1 = asint(output.Load((0u + (uint(x) * 4u))));
+        int x_1 = asint(output.Load((0u + (min(uint(x), 9u) * 4u))));
         i = (i + x_1);
         if ((i > int(10))) { break; }
       }
diff --git a/test/tint/shadowing/loop.wgsl.expected.ir.msl b/test/tint/shadowing/loop.wgsl.expected.ir.msl
index 0b551eb..73fe235 100644
--- a/test/tint/shadowing/loop.wgsl.expected.ir.msl
+++ b/test/tint/shadowing/loop.wgsl.expected.ir.msl
@@ -17,19 +17,23 @@
   device tint_array<int, 10>* output;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void foo(device tint_array<int, 10>* output [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
   int i = 0;
   {
     while(true) {
-      int x = (*tint_module_vars.output)[i];
+      TINT_ISOLATE_UB(tint_volatile_false)
+      int x = (*tint_module_vars.output)[min(uint(i), 9u)];
       {
-        int x_1 = (*tint_module_vars.output)[x];
+        int x_1 = (*tint_module_vars.output)[min(uint(x), 9u)];
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(x_1)));
         if ((i > 10)) { break; }
       }
       continue;
     }
   }
-  (*tint_module_vars.output)[0] = i;
+  (*tint_module_vars.output)[0u] = i;
 }
diff --git a/test/tint/shadowing/loop.wgsl.expected.msl b/test/tint/shadowing/loop.wgsl.expected.msl
index ccd0bd3..1c3403b 100644
--- a/test/tint/shadowing/loop.wgsl.expected.msl
+++ b/test/tint/shadowing/loop.wgsl.expected.msl
@@ -14,12 +14,16 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void foo(device tint_array<int, 10>* tint_symbol [[buffer(0)]]) {
   int i = 0;
   while(true) {
-    int x = (*(tint_symbol))[i];
+    TINT_ISOLATE_UB(tint_volatile_false);
+    int x = (*(tint_symbol))[min(uint(i), 9u)];
     {
-      int x_1 = (*(tint_symbol))[x];
+      int x_1 = (*(tint_symbol))[min(uint(x), 9u)];
       i = as_type<int>((as_type<uint>(i) + as_type<uint>(x_1)));
       if ((i > 10)) { break; }
     }
diff --git a/test/tint/shadowing/loop.wgsl.expected.spvasm b/test/tint/shadowing/loop.wgsl.expected.spvasm
index de4ba7e..55c647d 100644
--- a/test/tint/shadowing/loop.wgsl.expected.spvasm
+++ b/test/tint/shadowing/loop.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 38
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %foo "foo"
                OpExecutionMode %foo LocalSize 1 1 1
@@ -30,6 +31,7 @@
          %10 = OpTypeFunction %void
 %_ptr_Function_int = OpTypePointer Function %int
       %int_0 = OpConstant %int 0
+     %uint_9 = OpConstant %uint 9
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
      %uint_0 = OpConstant %uint 0
      %int_10 = OpConstant %int 10
@@ -46,25 +48,29 @@
                OpBranch %15
          %15 = OpLabel
          %19 = OpLoad %int %i None
-         %20 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %19
-         %23 = OpLoad %int %20 None
-               OpStore %x %23
+         %20 = OpBitcast %uint %19
+         %21 = OpExtInst %uint %22 UMin %20 %uint_9
+         %24 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %21
+         %27 = OpLoad %int %24 None
+               OpStore %x %27
                OpBranch %16
          %16 = OpLabel
-         %25 = OpLoad %int %x None
-         %26 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %25
-         %27 = OpLoad %int %26 None
-               OpStore %x_0 %27
-         %29 = OpLoad %int %x_0 None
-         %30 = OpLoad %int %i None
-         %31 = OpIAdd %int %30 %29
-               OpStore %i %31 None
-         %32 = OpLoad %int %i None
-         %33 = OpSGreaterThan %bool %32 %int_10
-               OpBranchConditional %33 %18 %17
+         %29 = OpLoad %int %x None
+         %30 = OpBitcast %uint %29
+         %31 = OpExtInst %uint %22 UMin %30 %uint_9
+         %32 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %31
+         %33 = OpLoad %int %32 None
+               OpStore %x_0 %33
+         %35 = OpLoad %int %x_0 None
+         %36 = OpLoad %int %i None
+         %37 = OpIAdd %int %36 %35
+               OpStore %i %37 None
+         %38 = OpLoad %int %i None
+         %39 = OpSGreaterThan %bool %38 %int_10
+               OpBranchConditional %39 %18 %17
          %18 = OpLabel
-         %36 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %int_0
-         %37 = OpLoad %int %i None
-               OpStore %36 %37 None
+         %42 = OpAccessChain %_ptr_StorageBuffer_int %1 %uint_0 %uint_0
+         %43 = OpLoad %int %i None
+               OpStore %42 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.dxc.hlsl
index 7ae1d29..134df00 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.dxc.hlsl
@@ -17,7 +17,7 @@
     for(int i = 0; (i < 4); i = (i + 1)) {
       {
         InnerS tint_symbol_1[8] = s1.a1;
-        tint_symbol_1[uniforms[0].x] = v;
+        tint_symbol_1[min(uniforms[0].x, 7u)] = v;
         s1.a1 = tint_symbol_1;
       }
     }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.fxc.hlsl
index 7ae1d29..134df00 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.fxc.hlsl
@@ -17,7 +17,7 @@
     for(int i = 0; (i < 4); i = (i + 1)) {
       {
         InnerS tint_symbol_1[8] = s1.a1;
-        tint_symbol_1[uniforms[0].x] = v;
+        tint_symbol_1[min(uniforms[0].x, 7u)] = v;
         s1.a1 = tint_symbol_1;
       }
     }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.glsl
index e1eca62..6de53bf 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.glsl
@@ -28,7 +28,7 @@
       } else {
         break;
       }
-      uint v_2 = v_1.inner.i;
+      uint v_2 = min(v_1.inner.i, 7u);
       s1.a1[v_2] = v;
       {
         i = (i + 1);
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.dxc.hlsl
index 16f1fd2..5562806 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.dxc.hlsl
@@ -21,7 +21,7 @@
       } else {
         break;
       }
-      uint v_1 = uniforms[0u].x;
+      uint v_1 = min(uniforms[0u].x, 7u);
       InnerS v_2 = v;
       s1.a1[v_1] = v_2;
       {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.fxc.hlsl
index 9cdec0b..303b74d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.fxc.hlsl
@@ -24,7 +24,7 @@
       uint v_1 = uniforms[0u].x;
       InnerS tint_array_copy[8] = s1.a1;
       InnerS v_2 = v;
-      tint_array_copy[v_1] = v_2;
+      tint_array_copy[min(v_1, 7u)] = v_2;
       InnerS v_3[8] = tint_array_copy;
       s1.a1 = v_3;
       {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.msl
index dcd6f77..1506f8f 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.ir.msl
@@ -40,7 +40,7 @@
       } else {
         break;
       }
-      s1.a1[(*tint_module_vars.uniforms).i] = v;
+      s1.a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
       {
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.msl
index 939ff14..51fe5aa 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Uniforms {
   /* 0x0000 */ uint i;
 };
@@ -30,7 +33,8 @@
   InnerS v = {};
   OuterS s1 = {};
   for(int i = 0; (i < 4); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    s1.a1[(*(tint_symbol_1)).i] = v;
+    TINT_ISOLATE_UB(tint_volatile_false);
+    s1.a1[min((*(tint_symbol_1)).i, 7u)] = v;
   }
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.spvasm
index 5b59a3a..83ad806 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_body.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+         %40 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -50,6 +51,7 @@
        %bool = OpTypeBool
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
       %int_1 = OpConstant %int 1
        %main = OpFunction %void None %8
           %9 = OpLabel
@@ -73,14 +75,15 @@
          %33 = OpLabel
          %35 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %38 = OpLoad %uint %35 None
-         %39 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %38
-         %40 = OpLoad %InnerS %v None
-               OpStore %39 %40 None
+         %39 = OpExtInst %uint %40 UMin %38 %uint_7
+         %42 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %39
+         %43 = OpLoad %InnerS %v None
+               OpStore %42 %43 None
                OpBranch %23
          %23 = OpLabel
-         %41 = OpLoad %int %i None
-         %42 = OpIAdd %int %41 %int_1
-               OpStore %i %42 None
+         %44 = OpLoad %int %i None
+         %45 = OpIAdd %int %44 %int_1
+               OpStore %i %45 None
                OpBranch %24
          %25 = OpLabel
                OpReturn
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.dxc.hlsl
index f7e6074..b8c9fea 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.dxc.hlsl
@@ -20,7 +20,7 @@
       i = (i + 1);
       {
         InnerS tint_symbol_1[8] = s1.a1;
-        tint_symbol_1[uniforms[0].x] = v;
+        tint_symbol_1[min(uniforms[0].x, 7u)] = v;
         s1.a1 = tint_symbol_1;
       }
     }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.fxc.hlsl
index f7e6074..b8c9fea 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.fxc.hlsl
@@ -20,7 +20,7 @@
       i = (i + 1);
       {
         InnerS tint_symbol_1[8] = s1.a1;
-        tint_symbol_1[uniforms[0].x] = v;
+        tint_symbol_1[min(uniforms[0].x, 7u)] = v;
         s1.a1 = tint_symbol_1;
       }
     }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.glsl
index 9ed2700..4d58b0c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.glsl
@@ -30,7 +30,7 @@
       }
       i = (i + 1);
       {
-        uint v_2 = v_1.inner.i;
+        uint v_2 = min(v_1.inner.i, 7u);
         s1.a1[v_2] = v;
       }
       continue;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
index 1b8aefc..60c4818 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.dxc.hlsl
@@ -23,7 +23,7 @@
       }
       i = (i + int(1));
       {
-        uint v_1 = uniforms[0u].x;
+        uint v_1 = min(uniforms[0u].x, 7u);
         InnerS v_2 = v;
         s1.a1[v_1] = v_2;
       }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
index ca90ef7..9412474 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.fxc.hlsl
@@ -26,7 +26,7 @@
         uint v_1 = uniforms[0u].x;
         InnerS tint_array_copy[8] = s1.a1;
         InnerS v_2 = v;
-        tint_array_copy[v_1] = v_2;
+        tint_array_copy[min(v_1, 7u)] = v_2;
         InnerS v_3[8] = tint_array_copy;
         s1.a1 = v_3;
       }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.msl
index 667517b..72037b9 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.ir.msl
@@ -29,6 +29,9 @@
   tint_array<InnerS, 8> a1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
@@ -36,13 +39,14 @@
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 4)) {
       } else {
         break;
       }
       i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
       {
-        s1.a1[(*tint_module_vars.uniforms).i] = v;
+        s1.a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
       }
       continue;
     }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.msl
index 76e27e9..612c4b3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Uniforms {
   /* 0x0000 */ uint i;
 };
@@ -29,7 +32,8 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  for(int i = 0; (i < 4); s1.a1[(*(tint_symbol_1)).i] = v) {
+  for(int i = 0; (i < 4); s1.a1[min((*(tint_symbol_1)).i, 7u)] = v) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)));
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.spvasm
index 168c6c2..3b76eee 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_continuing.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+         %43 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -51,6 +52,7 @@
       %int_1 = OpConstant %int 1
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
@@ -78,9 +80,10 @@
          %23 = OpLabel
          %38 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %41 = OpLoad %uint %38 None
-         %42 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %41
-         %43 = OpLoad %InnerS %v None
-               OpStore %42 %43 None
+         %42 = OpExtInst %uint %43 UMin %41 %uint_7
+         %45 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %42
+         %46 = OpLoad %InnerS %v None
+               OpStore %45 %46 None
                OpBranch %24
          %25 = OpLabel
                OpReturn
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.dxc.hlsl
index 268c8e8..1b28ea1 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.dxc.hlsl
@@ -17,7 +17,7 @@
   {
     {
       InnerS tint_symbol_1[8] = s1.a1;
-      tint_symbol_1[uniforms[0].x] = v;
+      tint_symbol_1[min(uniforms[0].x, 7u)] = v;
       s1.a1 = tint_symbol_1;
     }
     for(; (i < 4); i = (i + 1)) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.fxc.hlsl
index 268c8e8..1b28ea1 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.fxc.hlsl
@@ -17,7 +17,7 @@
   {
     {
       InnerS tint_symbol_1[8] = s1.a1;
-      tint_symbol_1[uniforms[0].x] = v;
+      tint_symbol_1[min(uniforms[0].x, 7u)] = v;
       s1.a1 = tint_symbol_1;
     }
     for(; (i < 4); i = (i + 1)) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.glsl
index 859e7af..8dd68ab 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.glsl
@@ -23,7 +23,7 @@
   OuterS s1 = OuterS(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)));
   int i = 0;
   {
-    uint v_2 = v_1.inner.i;
+    uint v_2 = min(v_1.inner.i, 7u);
     s1.a1[v_2] = v;
     while(true) {
       if ((i < 4)) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.dxc.hlsl
index 4e2f45c..2890b4c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.dxc.hlsl
@@ -16,7 +16,7 @@
   OuterS s1 = (OuterS)0;
   int i = int(0);
   {
-    uint v_1 = uniforms[0u].x;
+    uint v_1 = min(uniforms[0u].x, 7u);
     InnerS v_2 = v;
     s1.a1[v_1] = v_2;
     while(true) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.fxc.hlsl
index 507d1f3..370a15b 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.fxc.hlsl
@@ -19,7 +19,7 @@
     uint v_1 = uniforms[0u].x;
     InnerS tint_array_copy[8] = s1.a1;
     InnerS v_2 = v;
-    tint_array_copy[v_1] = v_2;
+    tint_array_copy[min(v_1, 7u)] = v_2;
     InnerS v_3[8] = tint_array_copy;
     s1.a1 = v_3;
     while(true) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.msl
index 27b1a7b..b6b66ea 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.ir.msl
@@ -29,14 +29,18 @@
   tint_array<InnerS, 8> a1;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
   int i = 0;
   {
-    s1.a1[(*tint_module_vars.uniforms).i] = v;
+    s1.a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 4)) {
       } else {
         break;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.msl
index 82e2101..b14e5e7 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct Uniforms {
   /* 0x0000 */ uint i;
 };
@@ -30,7 +33,8 @@
   InnerS v = {};
   OuterS s1 = {};
   int i = 0;
-  for(s1.a1[(*(tint_symbol_1)).i] = v; (i < 4); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+  for(s1.a1[min((*(tint_symbol_1)).i, 7u)] = v; (i < 4); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.spvasm
index 76d3480..e57e6ce 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/in_for_loop_init.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 44
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -48,6 +49,7 @@
       %int_0 = OpConstant %int 0
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
       %int_4 = OpConstant %int 4
        %bool = OpTypeBool
       %int_1 = OpConstant %int 1
@@ -61,26 +63,27 @@
          %24 = OpLabel
          %29 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %32 = OpLoad %uint %29 None
-         %33 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %32
-         %34 = OpLoad %InnerS %v None
-               OpStore %33 %34 None
+         %33 = OpExtInst %uint %34 UMin %32 %uint_7
+         %36 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %33
+         %37 = OpLoad %InnerS %v None
+               OpStore %36 %37 None
                OpBranch %27
          %27 = OpLabel
                OpLoopMerge %28 %26 None
                OpBranch %25
          %25 = OpLabel
-         %35 = OpLoad %int %i None
-         %36 = OpSLessThan %bool %35 %int_4
-               OpSelectionMerge %39 None
-               OpBranchConditional %36 %39 %40
-         %40 = OpLabel
+         %38 = OpLoad %int %i None
+         %39 = OpSLessThan %bool %38 %int_4
+               OpSelectionMerge %42 None
+               OpBranchConditional %39 %42 %43
+         %43 = OpLabel
                OpBranch %28
-         %39 = OpLabel
+         %42 = OpLabel
                OpBranch %26
          %26 = OpLabel
-         %41 = OpLoad %int %i None
-         %42 = OpIAdd %int %41 %int_1
-               OpStore %i %42 None
+         %44 = OpLoad %int %i None
+         %45 = OpIAdd %int %44 %int_1
+               OpStore %i %45 None
                OpBranch %27
          %28 = OpLabel
                OpReturn
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.dxc.hlsl
index 0adc404..36a2648 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.dxc.hlsl
@@ -26,9 +26,9 @@
   {
     S1 tint_symbol_1[8] = s.a1;
     uint tint_symbol_4 = getNextIndex();
-    uint tint_symbol_2_save = tint_symbol_4;
+    uint tint_symbol_2_save = min(tint_symbol_4, 7u);
     InnerS tint_symbol_3[8] = tint_symbol_1[tint_symbol_2_save].a2;
-    tint_symbol_3[uniforms[0].y] = v;
+    tint_symbol_3[min(uniforms[0].y, 7u)] = v;
     tint_symbol_1[tint_symbol_2_save].a2 = tint_symbol_3;
     s.a1 = tint_symbol_1;
   }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.fxc.hlsl
index 0adc404..36a2648 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.fxc.hlsl
@@ -26,9 +26,9 @@
   {
     S1 tint_symbol_1[8] = s.a1;
     uint tint_symbol_4 = getNextIndex();
-    uint tint_symbol_2_save = tint_symbol_4;
+    uint tint_symbol_2_save = min(tint_symbol_4, 7u);
     InnerS tint_symbol_3[8] = tint_symbol_1[tint_symbol_2_save].a2;
-    tint_symbol_3[uniforms[0].y] = v;
+    tint_symbol_3[min(uniforms[0].y, 7u)] = v;
     tint_symbol_1[tint_symbol_2_save].a2 = tint_symbol_3;
     s.a1 = tint_symbol_1;
   }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.glsl
index 1211408..c4e3eb9 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.glsl
@@ -32,6 +32,6 @@
   InnerS v = InnerS(0);
   OuterS s = OuterS(S1[8](S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)))));
   uint v_2 = getNextIndex();
-  uint v_3 = v_1.inner.j;
-  s.a1[v_2].a2[v_3] = v;
+  uint v_3 = min(v_1.inner.j, 7u);
+  s.a1[min(v_2, 7u)].a2[v_3] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.dxc.hlsl
index 52ff861..5e1460a 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.dxc.hlsl
@@ -25,8 +25,8 @@
   InnerS v = (InnerS)0;
   OuterS s = (OuterS)0;
   uint v_1 = getNextIndex();
-  uint v_2 = uniforms[0u].y;
+  uint v_2 = min(uniforms[0u].y, 7u);
   InnerS v_3 = v;
-  s.a1[v_1].a2[v_2] = v_3;
+  s.a1[min(v_1, 7u)].a2[v_2] = v_3;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.fxc.hlsl
index e8f4009..afff090 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.fxc.hlsl
@@ -28,7 +28,7 @@
   uint v_2 = uniforms[0u].y;
   S1 tint_array_copy[8] = s.a1;
   InnerS v_3 = v;
-  tint_array_copy[v_1].a2[v_2] = v_3;
+  tint_array_copy[min(v_1, 7u)].a2[min(v_2, 7u)] = v_3;
   S1 v_4[8] = tint_array_copy;
   s.a1 = v_4;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.msl
index 10279cf..6e0925c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.ir.msl
@@ -46,5 +46,5 @@
   InnerS v = {};
   OuterS s = {};
   uint const v_1 = getNextIndex(tint_module_vars);
-  s.a1[v_1].a2[(*tint_module_vars.uniforms).j] = v;
+  s.a1[min(v_1, 7u)].a2[min((*tint_module_vars.uniforms).j, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.msl
index c5637a4..717add9 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.msl
@@ -45,7 +45,7 @@
   InnerS v = {};
   OuterS s = {};
   uint const tint_symbol_1 = getNextIndex(&(tint_private_vars));
-  s.a1[tint_symbol_1].a2[(*(tint_symbol_2)).j] = v;
+  s.a1[min(tint_symbol_1, 7u)].a2[min((*(tint_symbol_2)).j, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.spvasm
index e9d4349..83c03cc 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/indexing_with_side_effect_func.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 40
+; Bound: 44
 ; Schema: 0
                OpCapability Shader
+         %39 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -60,6 +61,7 @@
          %32 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
 %getNextIndex = OpFunction %uint None %10
          %11 = OpLabel
          %12 = OpLoad %uint %nextIndex None
@@ -75,8 +77,10 @@
          %33 = OpFunctionCall %uint %getNextIndex
          %34 = OpAccessChain %_ptr_Uniform_uint %5 %uint_0 %uint_1
          %37 = OpLoad %uint %34 None
-         %38 = OpAccessChain %_ptr_Function_InnerS %s %uint_0 %33 %uint_0 %37
-         %39 = OpLoad %InnerS %v None
-               OpStore %38 %39 None
+         %38 = OpExtInst %uint %39 UMin %33 %uint_7
+         %41 = OpExtInst %uint %39 UMin %37 %uint_7
+         %42 = OpAccessChain %_ptr_Function_InnerS %s %uint_0 %38 %uint_0 %41
+         %43 = OpLoad %InnerS %v None
+               OpStore %42 %43 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.dxc.hlsl
index 15ddcb2..6c3bd9e 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.dxc.hlsl
@@ -15,7 +15,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.fxc.hlsl
index 15ddcb2..6c3bd9e 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.fxc.hlsl
@@ -15,7 +15,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.glsl
index b090d8e..fc46b1d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.glsl
@@ -21,6 +21,6 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)));
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   s1.a1[v_2] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.dxc.hlsl
index 29a037b..d83089f 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   s1.a1[v_1] = v_2;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.fxc.hlsl
index 03bd6d0..d945dc3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.fxc.hlsl
@@ -17,7 +17,7 @@
   uint v_1 = uniforms[0u].x;
   InnerS tint_array_copy[8] = s1.a1;
   InnerS v_2 = v;
-  tint_array_copy[v_1] = v_2;
+  tint_array_copy[min(v_1, 7u)] = v_2;
   InnerS v_3[8] = tint_array_copy;
   s1.a1 = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.msl
index 0a5b721..d17c197 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.ir.msl
@@ -33,5 +33,5 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*tint_module_vars.uniforms).i] = v;
+  s1.a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.msl
index 6e93e31..29d0468 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.msl
@@ -29,7 +29,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*(tint_symbol_1)).i] = v;
+  s1.a1[min((*(tint_symbol_1)).i, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.spvasm
index 8ff7c1d..32c0489 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -45,14 +46,16 @@
          %20 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
          %s1 = OpVariable %_ptr_Function_OuterS Function %20
          %21 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %24 = OpLoad %uint %21 None
-         %25 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %24
-         %26 = OpLoad %InnerS %v None
-               OpStore %25 %26 None
+         %25 = OpExtInst %uint %26 UMin %24 %uint_7
+         %28 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %25
+         %29 = OpLoad %InnerS %v None
+               OpStore %28 %29 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.dxc.hlsl
index 6ebca2e..e507cfd 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.dxc.hlsl
@@ -15,7 +15,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8][8] = s1.a1;
-    tint_symbol_1[uniforms[0].x][uniforms[0].y] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)][min(uniforms[0].y, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.fxc.hlsl
index 6ebca2e..e507cfd 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.fxc.hlsl
@@ -15,7 +15,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8][8] = s1.a1;
-    tint_symbol_1[uniforms[0].x][uniforms[0].y] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)][min(uniforms[0].y, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.glsl
index e50fa3f..7c729ae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.glsl
@@ -22,7 +22,7 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(InnerS[8][8](InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))));
-  uint v_2 = v_1.inner.i;
-  uint v_3 = v_1.inner.j;
+  uint v_2 = min(v_1.inner.i, 7u);
+  uint v_3 = min(v_1.inner.j, 7u);
   s1.a1[v_2][v_3] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.dxc.hlsl
index c608a6d..5c82efe 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.dxc.hlsl
@@ -14,8 +14,8 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
-  uint v_2 = uniforms[0u].y;
+  uint v_1 = min(uniforms[0u].x, 7u);
+  uint v_2 = min(uniforms[0u].y, 7u);
   InnerS v_3 = v;
   s1.a1[v_1][v_2] = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.fxc.hlsl
index e9924d7..1c3eddb 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.fxc.hlsl
@@ -18,7 +18,7 @@
   uint v_2 = uniforms[0u].y;
   InnerS tint_array_copy[8][8] = s1.a1;
   InnerS v_3 = v;
-  tint_array_copy[v_1][v_2] = v_3;
+  tint_array_copy[min(v_1, 7u)][min(v_2, 7u)] = v_3;
   InnerS v_4[8][8] = tint_array_copy;
   s1.a1 = v_4;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.msl
index 57968d0..545f5c6 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.ir.msl
@@ -34,5 +34,5 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*tint_module_vars.uniforms).i][(*tint_module_vars.uniforms).j] = v;
+  s1.a1[min((*tint_module_vars.uniforms).i, 7u)][min((*tint_module_vars.uniforms).j, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.msl
index 05ae52c..9e4e18a 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.msl
@@ -30,7 +30,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*(tint_symbol_1)).i][(*(tint_symbol_1)).j] = v;
+  s1.a1[min((*(tint_symbol_1)).i, 7u)][min((*(tint_symbol_1)).j, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.spvasm
index 9750bb2..f1e1e53 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %30 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -50,6 +51,7 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
@@ -58,8 +60,10 @@
          %25 = OpLoad %uint %22 None
          %26 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
          %28 = OpLoad %uint %26 None
-         %29 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %25 %28
-         %30 = OpLoad %InnerS %v None
-               OpStore %29 %30 None
+         %29 = OpExtInst %uint %30 UMin %25 %uint_7
+         %32 = OpExtInst %uint %30 UMin %28 %uint_7
+         %33 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %29 %32
+         %34 = OpLoad %InnerS %v None
+               OpStore %33 %34 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.dxc.hlsl
index 24cee3d..aac7aae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.dxc.hlsl
@@ -18,7 +18,7 @@
   OuterS s1 = (OuterS)0;
   {
     S1 tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x].s2 = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)].s2 = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.fxc.hlsl
index 24cee3d..aac7aae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.fxc.hlsl
@@ -18,7 +18,7 @@
   OuterS s1 = (OuterS)0;
   {
     S1 tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x].s2 = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)].s2 = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.glsl
index 084545a..0c35eb7 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.glsl
@@ -25,6 +25,6 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(S1[8](S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0)), S1(InnerS(0))));
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   s1.a1[v_2].s2 = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.dxc.hlsl
index af87bd1..fbd8134 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.dxc.hlsl
@@ -18,7 +18,7 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   s1.a1[v_1].s2 = v_2;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.fxc.hlsl
index 67c9aed..95dfe6d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.fxc.hlsl
@@ -21,7 +21,7 @@
   uint v_1 = uniforms[0u].x;
   S1 tint_array_copy[8] = s1.a1;
   InnerS v_2 = v;
-  tint_array_copy[v_1].s2 = v_2;
+  tint_array_copy[min(v_1, 7u)].s2 = v_2;
   S1 v_3[8] = tint_array_copy;
   s1.a1 = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.msl
index 38514da..1b8d638 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.ir.msl
@@ -37,5 +37,5 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*tint_module_vars.uniforms).i].s2 = v;
+  s1.a1[min((*tint_module_vars.uniforms).i, 7u)].s2 = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.msl
index 9ad4660..880f35c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.msl
@@ -33,7 +33,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*(tint_symbol_1)).i].s2 = v;
+  s1.a1[min((*(tint_symbol_1)).i, 7u)].s2 = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.spvasm
index 87511d0..82a0772 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -49,14 +50,16 @@
          %21 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
          %s1 = OpVariable %_ptr_Function_OuterS Function %21
          %22 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %25 = OpLoad %uint %22 None
-         %26 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %25 %uint_0
-         %27 = OpLoad %InnerS %v None
-               OpStore %26 %27 None
+         %26 = OpExtInst %uint %27 UMin %25 %uint_7
+         %29 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %26 %uint_0
+         %30 = OpLoad %InnerS %v None
+               OpStore %29 %30 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.dxc.hlsl
index 932efcc..249ebef 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.dxc.hlsl
@@ -18,9 +18,9 @@
   OuterS s = (OuterS)0;
   {
     S1 tint_symbol_1[8] = s.a1;
-    uint tint_symbol_2_save = uniforms[0].x;
+    uint tint_symbol_2_save = min(uniforms[0].x, 7u);
     InnerS tint_symbol_3[8] = tint_symbol_1[tint_symbol_2_save].a2;
-    tint_symbol_3[uniforms[0].y] = v;
+    tint_symbol_3[min(uniforms[0].y, 7u)] = v;
     tint_symbol_1[tint_symbol_2_save].a2 = tint_symbol_3;
     s.a1 = tint_symbol_1;
   }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.fxc.hlsl
index 932efcc..249ebef 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.fxc.hlsl
@@ -18,9 +18,9 @@
   OuterS s = (OuterS)0;
   {
     S1 tint_symbol_1[8] = s.a1;
-    uint tint_symbol_2_save = uniforms[0].x;
+    uint tint_symbol_2_save = min(uniforms[0].x, 7u);
     InnerS tint_symbol_3[8] = tint_symbol_1[tint_symbol_2_save].a2;
-    tint_symbol_3[uniforms[0].y] = v;
+    tint_symbol_3[min(uniforms[0].y, 7u)] = v;
     tint_symbol_1[tint_symbol_2_save].a2 = tint_symbol_3;
     s.a1 = tint_symbol_1;
   }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.glsl
index e724767..63396ee 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.glsl
@@ -26,7 +26,7 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s = OuterS(S1[8](S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))), S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)))));
-  uint v_2 = v_1.inner.i;
-  uint v_3 = v_1.inner.j;
+  uint v_2 = min(v_1.inner.i, 7u);
+  uint v_3 = min(v_1.inner.j, 7u);
   s.a1[v_2].a2[v_3] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.dxc.hlsl
index 91951da..04612aa 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.dxc.hlsl
@@ -18,8 +18,8 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
-  uint v_2 = uniforms[0u].y;
+  uint v_1 = min(uniforms[0u].x, 7u);
+  uint v_2 = min(uniforms[0u].y, 7u);
   InnerS v_3 = v;
   s.a1[v_1].a2[v_2] = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.fxc.hlsl
index 9ad327b..655f2ae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.fxc.hlsl
@@ -22,7 +22,7 @@
   uint v_2 = uniforms[0u].y;
   S1 tint_array_copy[8] = s.a1;
   InnerS v_3 = v;
-  tint_array_copy[v_1].a2[v_2] = v_3;
+  tint_array_copy[min(v_1, 7u)].a2[min(v_2, 7u)] = v_3;
   S1 v_4[8] = tint_array_copy;
   s.a1 = v_4;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.msl
index f7ac301..ba95313 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.ir.msl
@@ -38,5 +38,5 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s = {};
-  s.a1[(*tint_module_vars.uniforms).i].a2[(*tint_module_vars.uniforms).j] = v;
+  s.a1[min((*tint_module_vars.uniforms).i, 7u)].a2[min((*tint_module_vars.uniforms).j, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.msl
index c92d7c4..77a9b69 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.msl
@@ -34,7 +34,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s = {};
-  s.a1[(*(tint_symbol_1)).i].a2[(*(tint_symbol_1)).j] = v;
+  s.a1[min((*(tint_symbol_1)).i, 7u)].a2[min((*(tint_symbol_1)).j, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.spvasm
index 87c5c29..f1d0b41 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_array_struct_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %31 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -54,6 +55,7 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
@@ -62,8 +64,10 @@
          %26 = OpLoad %uint %23 None
          %27 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
          %29 = OpLoad %uint %27 None
-         %30 = OpAccessChain %_ptr_Function_InnerS %s %uint_0 %26 %uint_0 %29
-         %31 = OpLoad %InnerS %v None
-               OpStore %30 %31 None
+         %30 = OpExtInst %uint %31 UMin %26 %uint_7
+         %33 = OpExtInst %uint %31 UMin %29 %uint_7
+         %34 = OpAccessChain %_ptr_Function_InnerS %s %uint_0 %30 %uint_0 %33
+         %35 = OpLoad %InnerS %v None
+               OpStore %34 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.dxc.hlsl
index e99da54..c6ac0ae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.dxc.hlsl
@@ -13,7 +13,10 @@
 
 [numthreads(1, 1, 1)]
 void main() {
+  uint tint_symbol_1 = 0u;
+  s1.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 4u);
   InnerS v = (InnerS)0;
-  s1_store((4u * uniforms[0].x), v);
+  s1_store((4u * min(uniforms[0].x, (tint_symbol_2 - 1u))), v);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.fxc.hlsl
index e99da54..c6ac0ae 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.fxc.hlsl
@@ -13,7 +13,10 @@
 
 [numthreads(1, 1, 1)]
 void main() {
+  uint tint_symbol_1 = 0u;
+  s1.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 4u);
   InnerS v = (InnerS)0;
-  s1_store((4u * uniforms[0].x), v);
+  s1_store((4u * min(uniforms[0].x, (tint_symbol_2 - 1u))), v);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.glsl
index 3b8db1d..e6bd455 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.glsl
@@ -21,5 +21,6 @@
 void main() {
   InnerS v = InnerS(0);
   uint v_2 = v_1.inner.i;
-  s1.a1[v_2] = v;
+  uint v_3 = min(v_2, (uint(s1.a1.length()) - 1u));
+  s1.a1[v_3] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.dxc.hlsl
index 5aa8396..4e628c7 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   InnerS v = (InnerS)0;
-  InnerS v_2 = v;
-  v_1((0u + (uniforms[0u].x * 4u)), v_2);
+  uint v_2 = 0u;
+  s1.GetDimensions(v_2);
+  InnerS v_3 = v;
+  v_1((0u + (min(uniforms[0u].x, ((v_2 / 4u) - 1u)) * 4u)), v_3);
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.fxc.hlsl
index 5aa8396..4e628c7 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   InnerS v = (InnerS)0;
-  InnerS v_2 = v;
-  v_1((0u + (uniforms[0u].x * 4u)), v_2);
+  uint v_2 = 0u;
+  s1.GetDimensions(v_2);
+  InnerS v_3 = v;
+  v_1((0u + (min(uniforms[0u].x, ((v_2 / 4u) - 1u)) * 4u)), v_3);
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.msl
index e9e2700..295d3c3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.ir.msl
@@ -28,10 +28,11 @@
 struct tint_module_vars_struct {
   const constant Uniforms* uniforms;
   device OuterS* s1;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]], device OuterS* s1 [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .s1=s1};
+kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]], device OuterS* s1 [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .s1=s1, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   InnerS v = {};
-  (*tint_module_vars.s1).a1[(*tint_module_vars.uniforms).i] = v;
+  (*tint_module_vars.s1).a1[min((*tint_module_vars.uniforms).i, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 4u) - 1u))] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.msl
index ac9d29d..72ac536 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.msl
@@ -14,6 +14,10 @@
     T elements[N];
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Uniforms {
   /* 0x0000 */ uint i;
 };
@@ -26,9 +30,9 @@
   /* 0x0000 */ tint_array<InnerS, 1> a1;
 };
 
-kernel void tint_symbol(device OuterS* tint_symbol_1 [[buffer(1)]], const constant Uniforms* tint_symbol_2 [[buffer(0)]]) {
+kernel void tint_symbol(device OuterS* tint_symbol_1 [[buffer(1)]], const constant Uniforms* tint_symbol_2 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]]) {
   InnerS v = {};
-  (*(tint_symbol_1)).a1[(*(tint_symbol_2)).i] = v;
+  (*(tint_symbol_1)).a1[min((*(tint_symbol_2)).i, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 4u) - 1u))] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.spvasm
index ee328ce..855f99c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 26
+; Bound: 33
 ; Schema: 0
                OpCapability Shader
+         %29 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -48,14 +49,20 @@
          %18 = OpConstantNull %InnerS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+%_ptr_StorageBuffer__runtimearr_InnerS = OpTypePointer StorageBuffer %_runtimearr_InnerS
+     %uint_1 = OpConstant %uint 1
 %_ptr_StorageBuffer_InnerS = OpTypePointer StorageBuffer %InnerS
        %main = OpFunction %void None %14
          %15 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %18
          %19 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %22 = OpLoad %uint %19 None
-         %23 = OpAccessChain %_ptr_StorageBuffer_InnerS %s1 %uint_0 %22
-         %25 = OpLoad %InnerS %v None
-               OpStore %23 %25 None
+         %23 = OpAccessChain %_ptr_StorageBuffer__runtimearr_InnerS %s1 %uint_0
+         %25 = OpArrayLength %uint %s1 0
+         %26 = OpISub %uint %25 %uint_1
+         %28 = OpExtInst %uint %29 UMin %22 %26
+         %30 = OpAccessChain %_ptr_StorageBuffer_InnerS %s1 %uint_0 %28
+         %32 = OpLoad %InnerS %v None
+               OpStore %30 %32 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.dxc.hlsl
index 747317f..d54f943 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.dxc.hlsl
@@ -13,7 +13,10 @@
 
 [numthreads(1, 1, 1)]
 void main() {
+  uint tint_symbol_1 = 0u;
+  s.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 32u);
   InnerS v = (InnerS)0;
-  s_store(((32u * uniforms[0].x) + (4u * uniforms[0].y)), v);
+  s_store(((32u * min(uniforms[0].x, (tint_symbol_2 - 1u))) + (4u * min(uniforms[0].y, 7u))), v);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.fxc.hlsl
index 747317f..d54f943 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.fxc.hlsl
@@ -13,7 +13,10 @@
 
 [numthreads(1, 1, 1)]
 void main() {
+  uint tint_symbol_1 = 0u;
+  s.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = ((tint_symbol_1 - 0u) / 32u);
   InnerS v = (InnerS)0;
-  s_store(((32u * uniforms[0].x) + (4u * uniforms[0].y)), v);
+  s_store(((32u * min(uniforms[0].x, (tint_symbol_2 - 1u))) + (4u * min(uniforms[0].y, 7u))), v);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.glsl
index 6a909af..a82be3b 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.glsl
@@ -27,5 +27,6 @@
   InnerS v = InnerS(0);
   uint v_2 = v_1.inner.i;
   uint v_3 = v_1.inner.j;
-  s.a1[v_2].a2[v_3] = v;
+  uint v_4 = min(v_2, (uint(s.a1.length()) - 1u));
+  s.a1[v_4].a2[min(v_3, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.dxc.hlsl
index 6af205b..18d4515 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   InnerS v = (InnerS)0;
-  InnerS v_2 = v;
-  v_1(((0u + (uniforms[0u].x * 32u)) + (uniforms[0u].y * 4u)), v_2);
+  uint v_2 = 0u;
+  s.GetDimensions(v_2);
+  InnerS v_3 = v;
+  v_1(((0u + (min(uniforms[0u].x, ((v_2 / 32u) - 1u)) * 32u)) + (min(uniforms[0u].y, 7u) * 4u)), v_3);
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.fxc.hlsl
index 6af205b..18d4515 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.fxc.hlsl
@@ -14,7 +14,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   InnerS v = (InnerS)0;
-  InnerS v_2 = v;
-  v_1(((0u + (uniforms[0u].x * 32u)) + (uniforms[0u].y * 4u)), v_2);
+  uint v_2 = 0u;
+  s.GetDimensions(v_2);
+  InnerS v_3 = v;
+  v_1(((0u + (min(uniforms[0u].x, ((v_2 / 32u) - 1u)) * 32u)) + (min(uniforms[0u].y, 7u) * 4u)), v_3);
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.msl
index 46d6374..12a5b37 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.ir.msl
@@ -33,10 +33,11 @@
 struct tint_module_vars_struct {
   const constant Uniforms* uniforms;
   device OuterS* s;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]], device OuterS* s [[buffer(1)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .s=s};
+kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]], device OuterS* s [[buffer(1)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms, .s=s, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   InnerS v = {};
-  (*tint_module_vars.s).a1[(*tint_module_vars.uniforms).i].a2[(*tint_module_vars.uniforms).j] = v;
+  (*tint_module_vars.s).a1[min((*tint_module_vars.uniforms).i, ((((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] - 0u) / 32u) - 1u))].a2[min((*tint_module_vars.uniforms).j, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.msl
index b9abd21..9052855 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.msl
@@ -14,6 +14,10 @@
     T elements[N];
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct Uniforms {
   /* 0x0000 */ uint i;
   /* 0x0004 */ uint j;
@@ -31,9 +35,9 @@
   /* 0x0000 */ tint_array<S1, 1> a1;
 };
 
-kernel void tint_symbol(device OuterS* tint_symbol_1 [[buffer(1)]], const constant Uniforms* tint_symbol_2 [[buffer(0)]]) {
+kernel void tint_symbol(device OuterS* tint_symbol_1 [[buffer(1)]], const constant Uniforms* tint_symbol_2 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]]) {
   InnerS v = {};
-  (*(tint_symbol_1)).a1[(*(tint_symbol_2)).i].a2[(*(tint_symbol_2)).j] = v;
+  (*(tint_symbol_1)).a1[min((*(tint_symbol_2)).i, ((((*(tint_symbol_3)).array_lengths[0u][0u] - 0u) / 32u) - 1u))].a2[min((*(tint_symbol_2)).j, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.spvasm
index 5b0b6bf..1da254b 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_dynamic_array_struct_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 40
 ; Schema: 0
                OpCapability Shader
+         %34 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -58,6 +59,8 @@
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
      %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer__runtimearr_S1 = OpTypePointer StorageBuffer %_runtimearr_S1
+     %uint_7 = OpConstant %uint 7
 %_ptr_StorageBuffer_InnerS = OpTypePointer StorageBuffer %InnerS
        %main = OpFunction %void None %17
          %18 = OpLabel
@@ -66,8 +69,13 @@
          %25 = OpLoad %uint %22 None
          %26 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_1
          %28 = OpLoad %uint %26 None
-         %29 = OpAccessChain %_ptr_StorageBuffer_InnerS %s %uint_0 %25 %uint_0 %28
-         %31 = OpLoad %InnerS %v None
-               OpStore %29 %31 None
+         %29 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S1 %s %uint_0
+         %31 = OpArrayLength %uint %s 0
+         %32 = OpISub %uint %31 %uint_1
+         %33 = OpExtInst %uint %34 UMin %25 %32
+         %35 = OpExtInst %uint %34 UMin %28 %uint_7
+         %37 = OpAccessChain %_ptr_StorageBuffer_InnerS %s %uint_0 %33 %uint_0 %35
+         %39 = OpLoad %InnerS %v None
+               OpStore %37 %39 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.dxc.hlsl
index 76df457..5010f7d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.dxc.hlsl
@@ -27,7 +27,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  set_matrix_column(s1.m1, uniforms[0].x, (1.0f).xxxx);
-  set_matrix_scalar(s1.m1, uniforms[0].x, uniforms[0].x, 1.0f);
+  set_matrix_column(s1.m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
+  set_matrix_scalar(s1.m1, min(uniforms[0].x, 1u), min(uniforms[0].x, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.fxc.hlsl
index 76df457..5010f7d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.fxc.hlsl
@@ -27,7 +27,7 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  set_matrix_column(s1.m1, uniforms[0].x, (1.0f).xxxx);
-  set_matrix_scalar(s1.m1, uniforms[0].x, uniforms[0].x, 1.0f);
+  set_matrix_column(s1.m1, min(uniforms[0].x, 1u), (1.0f).xxxx);
+  set_matrix_scalar(s1.m1, min(uniforms[0].x, 1u), min(uniforms[0].x, 3u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.glsl
index d98ef86..ecc05a2 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.glsl
@@ -16,8 +16,8 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   OuterS s1 = OuterS(mat2x4(vec4(0.0f), vec4(0.0f)));
-  uint v_1 = v.inner.i;
+  uint v_1 = min(v.inner.i, 1u);
   s1.m1[v_1] = vec4(1.0f);
-  uint v_2 = v.inner.i;
-  s1.m1[v_2][v.inner.i] = 1.0f;
+  uint v_2 = min(v.inner.i, 1u);
+  s1.m1[v_2][min(v.inner.i, 3u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.dxc.hlsl
index 4b04a28..9d77f57 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.dxc.hlsl
@@ -9,9 +9,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  uint v = uniforms[0u].x;
+  uint v = min(uniforms[0u].x, 1u);
   s1.m1[v] = (1.0f).xxxx;
-  uint v_1 = uniforms[0u].x;
-  s1.m1[v_1][uniforms[0u].x] = 1.0f;
+  uint v_1 = min(uniforms[0u].x, 1u);
+  s1.m1[v_1][min(uniforms[0u].x, 3u)] = 1.0f;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.msl
index 284e042..f8c1e80 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.ir.msl
@@ -16,6 +16,6 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   OuterS s1 = {};
-  s1.m1[(*tint_module_vars.uniforms).i] = float4(1.0f);
-  s1.m1[(*tint_module_vars.uniforms).i][(*tint_module_vars.uniforms).i] = 1.0f;
+  s1.m1[min((*tint_module_vars.uniforms).i, 1u)] = float4(1.0f);
+  s1.m1[min((*tint_module_vars.uniforms).i, 1u)][min((*tint_module_vars.uniforms).i, 3u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.msl
index 226c644..e6763531f 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.msl
@@ -11,8 +11,8 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   OuterS s1 = {};
-  s1.m1[(*(tint_symbol_1)).i] = float4(1.0f);
-  s1.m1[(*(tint_symbol_1)).i][(*(tint_symbol_1)).i] = 1.0f;
+  s1.m1[min((*(tint_symbol_1)).i, 1u)] = float4(1.0f);
+  s1.m1[min((*(tint_symbol_1)).i, 1u)][min((*(tint_symbol_1)).i, 3u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.spvasm
index b97fc0e..c6eedee 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_matrix.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 38
 ; Schema: 0
                OpCapability Shader
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -39,23 +40,28 @@
          %16 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
 %_ptr_Function_v4float = OpTypePointer Function %v4float
     %float_1 = OpConstant %float 1
-         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+         %26 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_float = OpTypePointer Function %float
        %main = OpFunction %void None %8
           %9 = OpLabel
          %s1 = OpVariable %_ptr_Function_OuterS Function %16
          %17 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %20 = OpLoad %uint %17 None
-         %21 = OpAccessChain %_ptr_Function_v4float %s1 %uint_0 %20
-               OpStore %21 %23 None
-         %25 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-         %26 = OpLoad %uint %25 None
-         %27 = OpAccessChain %_ptr_Function_v4float %s1 %uint_0 %26
+         %21 = OpExtInst %uint %22 UMin %20 %uint_1
+         %24 = OpAccessChain %_ptr_Function_v4float %s1 %uint_0 %21
+               OpStore %24 %26 None
          %28 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %29 = OpLoad %uint %28 None
-         %30 = OpAccessChain %_ptr_Function_float %27 %29
-               OpStore %30 %float_1 None
+         %30 = OpExtInst %uint %22 UMin %29 %uint_1
+         %31 = OpAccessChain %_ptr_Function_v4float %s1 %uint_0 %30
+         %32 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+         %33 = OpLoad %uint %32 None
+         %34 = OpExtInst %uint %22 UMin %33 %uint_3
+         %36 = OpAccessChain %_ptr_Function_float %31 %34
+               OpStore %36 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.dxc.hlsl
index aa6d6bc..9a36f9c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.dxc.hlsl
@@ -16,12 +16,12 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   {
     InnerS tint_symbol_3[8] = s1.a2;
-    tint_symbol_3[uniforms[0].x] = v;
+    tint_symbol_3[min(uniforms[0].x, 7u)] = v;
     s1.a2 = tint_symbol_3;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.fxc.hlsl
index aa6d6bc..9a36f9c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.fxc.hlsl
@@ -16,12 +16,12 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   {
     InnerS tint_symbol_3[8] = s1.a2;
-    tint_symbol_3[uniforms[0].x] = v;
+    tint_symbol_3[min(uniforms[0].x, 7u)] = v;
     s1.a2 = tint_symbol_3;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.glsl
index 6f5816a..83a1229 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.glsl
@@ -22,8 +22,8 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)), InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)));
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   s1.a1[v_2] = v;
-  uint v_3 = v_1.inner.i;
+  uint v_3 = min(v_1.inner.i, 7u);
   s1.a2[v_3] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.dxc.hlsl
index c480ddd..25ef7e3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.dxc.hlsl
@@ -15,10 +15,10 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   s1.a1[v_1] = v_2;
-  uint v_3 = uniforms[0u].x;
+  uint v_3 = min(uniforms[0u].x, 7u);
   InnerS v_4 = v;
   s1.a2[v_3] = v_4;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.fxc.hlsl
index cc6a500..1c5f13e 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.fxc.hlsl
@@ -18,13 +18,13 @@
   uint v_1 = uniforms[0u].x;
   InnerS tint_array_copy[8] = s1.a1;
   InnerS v_2 = v;
-  tint_array_copy[v_1] = v_2;
+  tint_array_copy[min(v_1, 7u)] = v_2;
   InnerS v_3[8] = tint_array_copy;
   s1.a1 = v_3;
   uint v_4 = uniforms[0u].x;
   InnerS tint_array_copy_1[8] = s1.a2;
   InnerS v_5 = v;
-  tint_array_copy_1[v_4] = v_5;
+  tint_array_copy_1[min(v_4, 7u)] = v_5;
   InnerS v_6[8] = tint_array_copy_1;
   s1.a2 = v_6;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.msl
index 22693ac..04bb2e2 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.ir.msl
@@ -34,6 +34,6 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*tint_module_vars.uniforms).i] = v;
-  s1.a2[(*tint_module_vars.uniforms).i] = v;
+  s1.a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
+  s1.a2[min((*tint_module_vars.uniforms).i, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.msl
index 6bdd4e5..2965b26 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.msl
@@ -30,8 +30,8 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  s1.a1[(*(tint_symbol_1)).i] = v;
-  s1.a2[(*(tint_symbol_1)).i] = v;
+  s1.a1[min((*(tint_symbol_1)).i, 7u)] = v;
+  s1.a2[min((*(tint_symbol_1)).i, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.spvasm
index 95b02af..a57a1c1 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_multiple_arrays.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 36
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -47,6 +48,7 @@
          %20 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
      %uint_1 = OpConstant %uint 1
        %main = OpFunction %void None %8
           %9 = OpLabel
@@ -54,13 +56,15 @@
          %s1 = OpVariable %_ptr_Function_OuterS Function %20
          %21 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %24 = OpLoad %uint %21 None
-         %25 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %24
-         %26 = OpLoad %InnerS %v None
-               OpStore %25 %26 None
-         %27 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-         %28 = OpLoad %uint %27 None
-         %29 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_1 %28
-         %31 = OpLoad %InnerS %v None
-               OpStore %29 %31 None
+         %25 = OpExtInst %uint %26 UMin %24 %uint_7
+         %28 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %25
+         %29 = OpLoad %InnerS %v None
+               OpStore %28 %29 None
+         %30 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+         %31 = OpLoad %uint %30 None
+         %32 = OpExtInst %uint %26 UMin %31 %uint_7
+         %33 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_1 %32
+         %35 = OpLoad %InnerS %v None
+               OpStore %33 %35 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.dxc.hlsl
index 47f844c..1e06954 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.dxc.hlsl
@@ -18,7 +18,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.s2.a;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.s2.a = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.fxc.hlsl
index 47f844c..1e06954 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.fxc.hlsl
@@ -18,7 +18,7 @@
   OuterS s1 = (OuterS)0;
   {
     InnerS tint_symbol_1[8] = s1.s2.a;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     s1.s2.a = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.glsl
index fcf5bbf..62a7424 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.glsl
@@ -25,6 +25,6 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(S1(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0))));
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   s1.s2.a[v_2] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.dxc.hlsl
index dd6563d..99875eb 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.dxc.hlsl
@@ -18,7 +18,7 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   s1.s2.a[v_1] = v_2;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.fxc.hlsl
index c0620d7..168f3df 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.fxc.hlsl
@@ -21,7 +21,7 @@
   uint v_1 = uniforms[0u].x;
   InnerS tint_array_copy[8] = s1.s2.a;
   InnerS v_2 = v;
-  tint_array_copy[v_1] = v_2;
+  tint_array_copy[min(v_1, 7u)] = v_2;
   InnerS v_3[8] = tint_array_copy;
   s1.s2.a = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.msl
index 854e40a..dc7aa80 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.ir.msl
@@ -37,5 +37,5 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  s1.s2.a[(*tint_module_vars.uniforms).i] = v;
+  s1.s2.a[min((*tint_module_vars.uniforms).i, 7u)] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.msl
index 375695c..7cecdb9 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.msl
@@ -33,7 +33,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  s1.s2.a[(*(tint_symbol_1)).i] = v;
+  s1.s2.a[min((*(tint_symbol_1)).i, 7u)] = v;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.spvasm
index decbdd6..ddcced3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_struct_array.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
+         %27 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -49,14 +50,16 @@
          %21 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
          %s1 = OpVariable %_ptr_Function_OuterS Function %21
          %22 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %25 = OpLoad %uint %22 None
-         %26 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %uint_0 %25
-         %27 = OpLoad %InnerS %v None
-               OpStore %26 %27 None
+         %26 = OpExtInst %uint %27 UMin %25 %uint_7
+         %29 = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %uint_0 %26
+         %30 = OpLoad %InnerS %v None
+               OpStore %29 %30 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.dxc.hlsl
index e556fab..a6deda3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.dxc.hlsl
@@ -13,6 +13,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  set_vector_element(s1.v1, uniforms[0].x, 1.0f);
+  set_vector_element(s1.v1, min(uniforms[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.fxc.hlsl
index e556fab..a6deda3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.fxc.hlsl
@@ -13,6 +13,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  set_vector_element(s1.v1, uniforms[0].x, 1.0f);
+  set_vector_element(s1.v1, min(uniforms[0].x, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.glsl
index 8757f8a..5e0bb96 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.glsl
@@ -16,5 +16,5 @@
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
   OuterS s1 = OuterS(vec3(0.0f));
-  s1.v1[v.inner.i] = 1.0f;
+  s1.v1[min(v.inner.i, 2u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.dxc.hlsl
index 3509301..bd79416 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.dxc.hlsl
@@ -9,6 +9,6 @@
 [numthreads(1, 1, 1)]
 void main() {
   OuterS s1 = (OuterS)0;
-  s1.v1[uniforms[0u].x] = 1.0f;
+  s1.v1[min(uniforms[0u].x, 2u)] = 1.0f;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.msl
index c1e8455..2897514 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.ir.msl
@@ -16,5 +16,5 @@
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   OuterS s1 = {};
-  s1.v1[(*tint_module_vars.uniforms).i] = 1.0f;
+  s1.v1[min((*tint_module_vars.uniforms).i, 2u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.msl
index 4999967..047be7d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.msl
@@ -11,7 +11,7 @@
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   OuterS s1 = {};
-  s1.v1[(*(tint_symbol_1)).i] = 1.0f;
+  s1.v1[min((*(tint_symbol_1)).i, 2u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.spvasm
index 68a4675..ea871d9 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/struct_vector.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 25
+; Bound: 28
 ; Schema: 0
                OpCapability Shader
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -37,6 +38,7 @@
 %_ptr_Function_v3float = OpTypePointer Function %v3float
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
        %main = OpFunction %void None %8
@@ -45,7 +47,8 @@
          %16 = OpAccessChain %_ptr_Function_v3float %s1 %uint_0
          %19 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %21 = OpLoad %uint %19 None
-         %22 = OpAccessChain %_ptr_Function_float %16 %21
-               OpStore %22 %float_1 None
+         %22 = OpExtInst %uint %23 UMin %21 %uint_2
+         %25 = OpAccessChain %_ptr_Function_float %16 %22
+               OpStore %25 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.dxc.hlsl
index 57bae19..16f1326 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.dxc.hlsl
@@ -18,8 +18,8 @@
 void main() {
   OuterS s1 = (OuterS)0;
   float3 v = float3(0.0f, 0.0f, 0.0f);
-  set_vector_element(v, s1.a1[uniforms[0].x], 1.0f);
-  uint tint_symbol = f(s1.a1[uniforms[0].x]);
-  set_vector_element(v, tint_symbol, 1.0f);
+  set_vector_element(v, min(s1.a1[min(uniforms[0].x, 7u)], 2u), 1.0f);
+  uint tint_symbol = f(s1.a1[min(uniforms[0].x, 7u)]);
+  set_vector_element(v, min(tint_symbol, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.fxc.hlsl
index 57bae19..16f1326 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.fxc.hlsl
@@ -18,8 +18,8 @@
 void main() {
   OuterS s1 = (OuterS)0;
   float3 v = float3(0.0f, 0.0f, 0.0f);
-  set_vector_element(v, s1.a1[uniforms[0].x], 1.0f);
-  uint tint_symbol = f(s1.a1[uniforms[0].x]);
-  set_vector_element(v, tint_symbol, 1.0f);
+  set_vector_element(v, min(s1.a1[min(uniforms[0].x, 7u)], 2u), 1.0f);
+  uint tint_symbol = f(s1.a1[min(uniforms[0].x, 7u)]);
+  set_vector_element(v, min(tint_symbol, 2u), 1.0f);
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.glsl
index fabfc8b..55aa2aa 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.glsl
@@ -20,8 +20,8 @@
 void main() {
   OuterS s1 = OuterS(uint[8](0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u));
   vec3 v = vec3(0.0f);
-  uint v_2 = v_1.inner.i;
-  v[s1.a1[v_2]] = 1.0f;
-  uint v_3 = v_1.inner.i;
-  v[f(s1.a1[v_3])] = 1.0f;
+  uint v_2 = min(v_1.inner.i, 7u);
+  v[min(s1.a1[v_2], 2u)] = 1.0f;
+  uint v_3 = min(v_1.inner.i, 7u);
+  v[min(f(s1.a1[v_3]), 2u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.dxc.hlsl
index c380d42..cf983e6 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.dxc.hlsl
@@ -14,9 +14,9 @@
 void main() {
   OuterS s1 = (OuterS)0;
   float3 v = (0.0f).xxx;
-  uint v_1 = uniforms[0u].x;
-  v[s1.a1[v_1]] = 1.0f;
-  uint v_2 = uniforms[0u].x;
-  v[f(s1.a1[v_2])] = 1.0f;
+  uint v_1 = min(uniforms[0u].x, 7u);
+  v[min(s1.a1[v_1], 2u)] = 1.0f;
+  uint v_2 = min(uniforms[0u].x, 7u);
+  v[min(f(s1.a1[v_2]), 2u)] = 1.0f;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.fxc.hlsl
index 5a7f3d5..939f9e5 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.fxc.hlsl
@@ -14,11 +14,11 @@
 void main() {
   OuterS s1 = (OuterS)0;
   float3 v = (0.0f).xxx;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   float3 v_2 = v;
   float3 v_3 = s1.a1[v_1].xxx;
   v = (((v_3 == float3(int(0), int(1), int(2)))) ? (1.0f.xxx) : (v_2));
-  uint v_4 = uniforms[0u].x;
+  uint v_4 = min(uniforms[0u].x, 7u);
   uint v_5 = f(s1.a1[v_4]);
   float3 v_6 = v;
   v = (((v_5.xxx == float3(int(0), int(1), int(2)))) ? (1.0f.xxx) : (v_6));
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.msl
index cdd9c6b..5e0bf39 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.ir.msl
@@ -33,6 +33,6 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   OuterS s1 = {};
   float3 v = 0.0f;
-  v[s1.a1[(*tint_module_vars.uniforms).i]] = 1.0f;
-  v[f(s1.a1[(*tint_module_vars.uniforms).i])] = 1.0f;
+  v[min(s1.a1[min((*tint_module_vars.uniforms).i, 7u)], 2u)] = 1.0f;
+  v[min(f(s1.a1[min((*tint_module_vars.uniforms).i, 7u)]), 2u)] = 1.0f;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.msl
index bccd603..6fec565 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.msl
@@ -29,9 +29,9 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_2 [[buffer(0)]]) {
   OuterS s1 = {};
   float3 v = 0.0f;
-  v[s1.a1[(*(tint_symbol_2)).i]] = 1.0f;
-  uint const tint_symbol_1 = f(s1.a1[(*(tint_symbol_2)).i]);
-  v[tint_symbol_1] = 1.0f;
+  v[min(s1.a1[min((*(tint_symbol_2)).i, 7u)], 2u)] = 1.0f;
+  uint const tint_symbol_1 = f(s1.a1[min((*(tint_symbol_2)).i, 7u)]);
+  v[min(tint_symbol_1, 2u)] = 1.0f;
   return;
 }
 
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.spvasm
index 0423062..678b22f 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/vector_assign.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 50
 ; Schema: 0
                OpCapability Shader
+         %32 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -46,7 +47,9 @@
          %26 = OpConstantNull %v3float
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
 %_ptr_Function_uint = OpTypePointer Function %uint
+     %uint_2 = OpConstant %uint 2
 %_ptr_Function_float = OpTypePointer Function %float
     %float_1 = OpConstant %float 1
           %f = OpFunction %uint None %8
@@ -61,16 +64,20 @@
           %v = OpVariable %_ptr_Function_v3float Function %26
          %27 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %30 = OpLoad %uint %27 None
-         %31 = OpAccessChain %_ptr_Function_uint %s1 %uint_0 %30
-         %33 = OpLoad %uint %31 None
-         %34 = OpAccessChain %_ptr_Function_float %v %33
-               OpStore %34 %float_1 None
-         %37 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
-         %38 = OpLoad %uint %37 None
-         %39 = OpAccessChain %_ptr_Function_uint %s1 %uint_0 %38
-         %40 = OpLoad %uint %39 None
-         %41 = OpFunctionCall %uint %f %40
-         %42 = OpAccessChain %_ptr_Function_float %v %41
-               OpStore %42 %float_1 None
+         %31 = OpExtInst %uint %32 UMin %30 %uint_7
+         %34 = OpAccessChain %_ptr_Function_uint %s1 %uint_0 %31
+         %36 = OpLoad %uint %34 None
+         %37 = OpExtInst %uint %32 UMin %36 %uint_2
+         %39 = OpAccessChain %_ptr_Function_float %v %37
+               OpStore %39 %float_1 None
+         %42 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
+         %43 = OpLoad %uint %42 None
+         %44 = OpExtInst %uint %32 UMin %43 %uint_7
+         %45 = OpAccessChain %_ptr_Function_uint %s1 %uint_0 %44
+         %46 = OpLoad %uint %45 None
+         %47 = OpFunctionCall %uint %f %46
+         %48 = OpExtInst %uint %32 UMin %47 %uint_2
+         %49 = OpAccessChain %_ptr_Function_float %v %48
+               OpStore %49 %float_1 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.dxc.hlsl
index a8628ef..c6bf55b 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.dxc.hlsl
@@ -16,7 +16,7 @@
   uint p_save = uniforms[0].x;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[p_save] = v;
+    tint_symbol_1[min(p_save, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.fxc.hlsl
index a8628ef..c6bf55b 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.fxc.hlsl
@@ -16,7 +16,7 @@
   uint p_save = uniforms[0].x;
   {
     InnerS tint_symbol_1[8] = s1.a1;
-    tint_symbol_1[p_save] = v;
+    tint_symbol_1[min(p_save, 7u)] = v;
     s1.a1 = tint_symbol_1;
   }
   return;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.glsl
index b090d8e..fc46b1d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.glsl
@@ -21,6 +21,6 @@
 void main() {
   InnerS v = InnerS(0);
   OuterS s1 = OuterS(InnerS[8](InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0), InnerS(0)));
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   s1.a1[v_2] = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.dxc.hlsl
index 29a037b..d83089f 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.dxc.hlsl
@@ -14,7 +14,7 @@
 void main() {
   InnerS v = (InnerS)0;
   OuterS s1 = (OuterS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   s1.a1[v_1] = v_2;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.fxc.hlsl
index 03bd6d0..d945dc3 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.fxc.hlsl
@@ -17,7 +17,7 @@
   uint v_1 = uniforms[0u].x;
   InnerS tint_array_copy[8] = s1.a1;
   InnerS v_2 = v;
-  tint_array_copy[v_1] = v_2;
+  tint_array_copy[min(v_1, 7u)] = v_2;
   InnerS v_3[8] = tint_array_copy;
   s1.a1 = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.msl
index e209539..8ea0e0d 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.ir.msl
@@ -33,6 +33,6 @@
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
   InnerS v = {};
   OuterS s1 = {};
-  thread InnerS* const p = (&s1.a1[(*tint_module_vars.uniforms).i]);
+  thread InnerS* const p = (&s1.a1[min((*tint_module_vars.uniforms).i, 7u)]);
   (*p) = v;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.msl
index 573c567..1465512 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.msl
@@ -29,7 +29,7 @@
 kernel void tint_symbol(const constant Uniforms* tint_symbol_1 [[buffer(0)]]) {
   InnerS v = {};
   OuterS s1 = {};
-  uint const p_save = (*(tint_symbol_1)).i;
+  uint const p_save = min((*(tint_symbol_1)).i, 7u);
   s1.a1[p_save] = v;
   return;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.spvasm
index dddc84b..8a4a477 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 30
 ; Schema: 0
                OpCapability Shader
+         %26 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -46,14 +47,16 @@
          %20 = OpConstantNull %OuterS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
+     %uint_7 = OpConstant %uint 7
        %main = OpFunction %void None %8
           %9 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %14
          %s1 = OpVariable %_ptr_Function_OuterS Function %20
          %21 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %24 = OpLoad %uint %21 None
-          %p = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %24
-         %26 = OpLoad %InnerS %v None
-               OpStore %p %26 None
+         %25 = OpExtInst %uint %26 UMin %24 %uint_7
+          %p = OpAccessChain %_ptr_Function_InnerS %s1 %uint_0 %25
+         %29 = OpLoad %InnerS %v None
+               OpStore %p %29 None
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.dxc.hlsl
index bdaae4d..1691fed 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.dxc.hlsl
@@ -13,7 +13,7 @@
   InnerS v = (InnerS)0;
   {
     InnerS tint_symbol_1[8] = p.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     p.a1 = tint_symbol_1;
   }
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.fxc.hlsl
index bdaae4d..1691fed 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.fxc.hlsl
@@ -13,7 +13,7 @@
   InnerS v = (InnerS)0;
   {
     InnerS tint_symbol_1[8] = p.a1;
-    tint_symbol_1[uniforms[0].x] = v;
+    tint_symbol_1[min(uniforms[0].x, 7u)] = v;
     p.a1 = tint_symbol_1;
   }
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.glsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.glsl
index e1fcf69..ab498c8 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.glsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.glsl
@@ -19,7 +19,7 @@
 } v_1;
 void f(inout OuterS p) {
   InnerS v = InnerS(0);
-  uint v_2 = v_1.inner.i;
+  uint v_2 = min(v_1.inner.i, 7u);
   p.a1[v_2] = v;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.dxc.hlsl
index e988a2d..9c0231c 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.dxc.hlsl
@@ -12,7 +12,7 @@
 };
 void f(inout OuterS p) {
   InnerS v = (InnerS)0;
-  uint v_1 = uniforms[0u].x;
+  uint v_1 = min(uniforms[0u].x, 7u);
   InnerS v_2 = v;
   p.a1[v_1] = v_2;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.fxc.hlsl
index ac25523..6160ef8 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.fxc.hlsl
@@ -15,7 +15,7 @@
   uint v_1 = uniforms[0u].x;
   InnerS tint_array_copy[8] = p.a1;
   InnerS v_2 = v;
-  tint_array_copy[v_1] = v_2;
+  tint_array_copy[min(v_1, 7u)] = v_2;
   InnerS v_3[8] = tint_array_copy;
   p.a1 = v_3;
 }
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.msl
index a1f4df3..9ef6794 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.ir.msl
@@ -31,7 +31,7 @@
 
 void f(thread OuterS* const p, tint_module_vars_struct tint_module_vars) {
   InnerS v = {};
-  (*p).a1[(*tint_module_vars.uniforms).i] = v;
+  (*p).a1[min((*tint_module_vars.uniforms).i, 7u)] = v;
 }
 
 kernel void tint_symbol(const constant Uniforms* uniforms [[buffer(0)]]) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.msl b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.msl
index 9d025d3..4351d6a 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.msl
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.msl
@@ -28,7 +28,7 @@
 
 void f(thread OuterS* const p, const constant Uniforms* const tint_symbol_1) {
   InnerS v = {};
-  (*(p)).a1[(*(tint_symbol_1)).i] = v;
+  (*(p)).a1[min((*(tint_symbol_1)).i, 7u)] = v;
 }
 
 kernel void tint_symbol(const constant Uniforms* tint_symbol_2 [[buffer(0)]]) {
diff --git a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.spvasm b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.spvasm
index 97754f5..a1b2091 100644
--- a/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.spvasm
+++ b/test/tint/statements/assign/indexed_assign_to_array_in_struct/via_pointer_arg.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 32
+; Bound: 35
 ; Schema: 0
                OpCapability Shader
+         %25 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -46,22 +47,24 @@
          %19 = OpConstantNull %InnerS
 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
      %uint_0 = OpConstant %uint 0
-         %27 = OpTypeFunction %void
-         %30 = OpConstantNull %OuterS
+     %uint_7 = OpConstant %uint 7
+         %30 = OpTypeFunction %void
+         %33 = OpConstantNull %OuterS
           %f = OpFunction %void None %15
      %p_root = OpFunctionParameter %_ptr_Function_OuterS
          %16 = OpLabel
           %v = OpVariable %_ptr_Function_InnerS Function %19
          %20 = OpAccessChain %_ptr_Uniform_uint %1 %uint_0 %uint_0
          %23 = OpLoad %uint %20 None
-         %24 = OpAccessChain %_ptr_Function_InnerS %p_root %uint_0 %23
-         %25 = OpLoad %InnerS %v None
-               OpStore %24 %25 None
+         %24 = OpExtInst %uint %25 UMin %23 %uint_7
+         %27 = OpAccessChain %_ptr_Function_InnerS %p_root %uint_0 %24
+         %28 = OpLoad %InnerS %v None
+               OpStore %27 %28 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %27
-         %28 = OpLabel
-         %s1 = OpVariable %_ptr_Function_OuterS Function %30
-         %31 = OpFunctionCall %void %f %s1
+       %main = OpFunction %void None %30
+         %31 = OpLabel
+         %s1 = OpVariable %_ptr_Function_OuterS Function %33
+         %34 = OpFunctionCall %void %f %s1
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl
index bad2fa5..19e4474 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.dxc.hlsl
@@ -29,7 +29,7 @@
   int tint_symbol_1 = bar();
   {
     int4 tint_symbol_3[4] = x.a;
-    set_vector_element(tint_symbol_3[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5));
+    set_vector_element(tint_symbol_3[min(uint(tint_symbol_save), 3u)], min(uint(tint_symbol_1), 3u), (x.a[min(uint(tint_symbol_save), 3u)][min(uint(tint_symbol_1), 3u)] + 5));
     x.a = tint_symbol_3;
   }
 }
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl
index bad2fa5..19e4474 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.fxc.hlsl
@@ -29,7 +29,7 @@
   int tint_symbol_1 = bar();
   {
     int4 tint_symbol_3[4] = x.a;
-    set_vector_element(tint_symbol_3[tint_symbol_save], tint_symbol_1, (x.a[tint_symbol_save][tint_symbol_1] + 5));
+    set_vector_element(tint_symbol_3[min(uint(tint_symbol_save), 3u)], min(uint(tint_symbol_1), 3u), (x.a[min(uint(tint_symbol_save), 3u)][min(uint(tint_symbol_1), 3u)] + 5));
     x.a = tint_symbol_3;
   }
 }
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.glsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.glsl
index f2aed78..edab938 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.glsl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.glsl
@@ -16,9 +16,10 @@
 }
 void tint_symbol() {
   S x = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
-  int v = foo();
+  uint v = min(uint(foo()), 3u);
   int v_1 = bar();
-  x.a[v][v_1] = (x.a[v][v_1] + 5);
+  int v_2 = (x.a[v][min(uint(v_1), 3u)] + 5);
+  x.a[v][min(uint(v_1), 3u)] = v_2;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.dxc.hlsl
index b99a5f0..5510317 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.dxc.hlsl
@@ -16,9 +16,10 @@
 
 void main() {
   S x = (S)0;
-  int v = foo();
+  uint v = min(uint(foo()), 3u);
   int v_1 = bar();
-  x.a[v][v_1] = (x.a[v][v_1] + int(5));
+  int v_2 = (x.a[v][min(uint(v_1), 3u)] + int(5));
+  x.a[v][min(uint(v_1), 3u)] = v_2;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.fxc.hlsl
index d5f7a21..5a7a79a 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.fxc.hlsl
@@ -16,11 +16,11 @@
 
 void main() {
   S x = (S)0;
-  int v = foo();
+  uint v = min(uint(foo()), 3u);
   int v_1 = bar();
-  int4 v_2 = x.a[v];
-  int4 v_3 = (x.a[v][v_1] + int(5)).xxxx;
-  x.a[v] = (((v_1.xxxx == int4(int(0), int(1), int(2), int(3)))) ? (v_3) : (v_2));
+  int v_2 = (x.a[v][min(uint(v_1), 3u)] + int(5));
+  int4 v_3 = x.a[v];
+  x.a[v] = (((v_1.xxxx == int4(int(0), int(1), int(2), int(3)))) ? (v_2.xxxx) : (v_3));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.msl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.msl
index f925068..a3aeb71 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.msl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.ir.msl
@@ -34,7 +34,8 @@
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   S x = S{};
   thread S* const p = (&x);
-  thread int4* const v = (&(*p).a[foo(tint_module_vars)]);
+  thread int4* const v = (&(*p).a[min(uint(foo(tint_module_vars)), 3u)]);
   int const v_1 = bar(tint_module_vars);
-  (*v)[v_1] = as_type<int>((as_type<uint>((*v)[v_1]) + as_type<uint>(5)));
+  int const v_2 = as_type<int>((as_type<uint>((*v)[min(uint(v_1), 3u)]) + as_type<uint>(5)));
+  (*v)[min(uint(v_1), 3u)] = v_2;
 }
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
index c7c4bd6..9394178 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.msl
@@ -35,8 +35,8 @@
 void tint_symbol(thread tint_private_vars_struct* const tint_private_vars) {
   S x = S{};
   int const tint_symbol_3 = foo(tint_private_vars);
-  int const tint_symbol_1_save = tint_symbol_3;
+  uint const tint_symbol_1_save = min(uint(tint_symbol_3), 3u);
   int const tint_symbol_2 = bar(tint_private_vars);
-  x.a[tint_symbol_1_save][tint_symbol_2] = as_type<int>((as_type<uint>(x.a[tint_symbol_1_save][tint_symbol_2]) + as_type<uint>(5)));
+  x.a[tint_symbol_1_save][min(uint(tint_symbol_2), 3u)] = as_type<int>((as_type<uint>(x.a[tint_symbol_1_save][min(uint(tint_symbol_2), 3u)]) + as_type<uint>(5)));
 }
 
diff --git a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.spvasm b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.spvasm
index 142a250..9de8a97 100644
--- a/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.spvasm
+++ b/test/tint/statements/compound_assign/complex_lhs.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 43
+; Bound: 51
 ; Schema: 0
                OpCapability Shader
+         %33 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -34,6 +35,7 @@
           %S = OpTypeStruct %_arr_v4int_uint_4
 %_ptr_Function_S = OpTypePointer Function %S
          %29 = OpConstantNull %S
+     %uint_3 = OpConstant %uint 3
 %_ptr_Function_v4int = OpTypePointer Function %v4int
      %uint_0 = OpConstant %uint 0
 %_ptr_Function_int = OpTypePointer Function %int
@@ -59,16 +61,22 @@
           %x = OpVariable %_ptr_Function_S Function
                OpStore %x %29
          %30 = OpFunctionCall %int %foo
-         %31 = OpAccessChain %_ptr_Function_v4int %x %uint_0 %30
-         %34 = OpFunctionCall %int %bar
-         %35 = OpAccessChain %_ptr_Function_int %31 %34
-         %37 = OpLoad %int %35 None
-         %38 = OpIAdd %int %37 %int_5
-         %40 = OpAccessChain %_ptr_Function_int %31 %34
-               OpStore %40 %38 None
+         %31 = OpBitcast %uint %30
+         %32 = OpExtInst %uint %33 UMin %31 %uint_3
+         %35 = OpAccessChain %_ptr_Function_v4int %x %uint_0 %32
+         %38 = OpFunctionCall %int %bar
+         %39 = OpBitcast %uint %38
+         %40 = OpExtInst %uint %33 UMin %39 %uint_3
+         %41 = OpAccessChain %_ptr_Function_int %35 %40
+         %43 = OpLoad %int %41 None
+         %44 = OpIAdd %int %43 %int_5
+         %46 = OpBitcast %uint %38
+         %47 = OpExtInst %uint %33 UMin %46 %uint_3
+         %48 = OpAccessChain %_ptr_Function_int %35 %47
+               OpStore %48 %44 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %20
-         %42 = OpLabel
+         %50 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl
index 7c05eb7..614a07c 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.dxc.hlsl
@@ -25,17 +25,17 @@
   float a[4] = (float[4])0;
   {
     int tint_symbol_save = idx1();
-    a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f);
+    a[min(uint(tint_symbol_save), 3u)] = (a[min(uint(tint_symbol_save), 3u)] * 2.0f);
     while (true) {
       int tint_symbol_2 = idx2();
-      if (!((a[tint_symbol_2] < 10.0f))) {
+      if (!((a[min(uint(tint_symbol_2), 3u)] < 10.0f))) {
         break;
       }
       {
       }
       {
         int tint_symbol_1_save = idx3();
-        a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f);
+        a[min(uint(tint_symbol_1_save), 3u)] = (a[min(uint(tint_symbol_1_save), 3u)] + 1.0f);
       }
     }
   }
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl
index 7c05eb7..614a07c 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.fxc.hlsl
@@ -25,17 +25,17 @@
   float a[4] = (float[4])0;
   {
     int tint_symbol_save = idx1();
-    a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f);
+    a[min(uint(tint_symbol_save), 3u)] = (a[min(uint(tint_symbol_save), 3u)] * 2.0f);
     while (true) {
       int tint_symbol_2 = idx2();
-      if (!((a[tint_symbol_2] < 10.0f))) {
+      if (!((a[min(uint(tint_symbol_2), 3u)] < 10.0f))) {
         break;
       }
       {
       }
       {
         int tint_symbol_1_save = idx3();
-        a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f);
+        a[min(uint(tint_symbol_1_save), 3u)] = (a[min(uint(tint_symbol_1_save), 3u)] + 1.0f);
       }
     }
   }
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.glsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.glsl
index af5db78..963d874 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.glsl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.glsl
@@ -30,16 +30,16 @@
 void foo() {
   float a[4] = float[4](0.0f, 0.0f, 0.0f, 0.0f);
   {
-    int v_2 = idx1();
+    uint v_2 = min(uint(idx1()), 3u);
     a[v_2] = (a[v_2] * 2.0f);
     while(true) {
-      int v_3 = idx2();
+      uint v_3 = min(uint(idx2()), 3u);
       if ((a[v_3] < 10.0f)) {
       } else {
         break;
       }
       {
-        int v_4 = idx3();
+        uint v_4 = min(uint(idx3()), 3u);
         a[v_4] = (a[v_4] + 1.0f);
       }
       continue;
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.dxc.hlsl
index 070b80d..56cbb14 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.dxc.hlsl
@@ -19,16 +19,16 @@
 void foo() {
   float a[4] = (float[4])0;
   {
-    int v_1 = idx1();
+    uint v_1 = min(uint(idx1()), 3u);
     a[v_1] = (a[v_1] * 2.0f);
     while(true) {
-      int v_2 = idx2();
+      uint v_2 = min(uint(idx2()), 3u);
       if ((a[v_2] < 10.0f)) {
       } else {
         break;
       }
       {
-        int v_3 = idx3();
+        uint v_3 = min(uint(idx3()), 3u);
         a[v_3] = (a[v_3] + 1.0f);
       }
       continue;
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.fxc.hlsl
index 070b80d..56cbb14 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.fxc.hlsl
@@ -19,16 +19,16 @@
 void foo() {
   float a[4] = (float[4])0;
   {
-    int v_1 = idx1();
+    uint v_1 = min(uint(idx1()), 3u);
     a[v_1] = (a[v_1] * 2.0f);
     while(true) {
-      int v_2 = idx2();
+      uint v_2 = min(uint(idx2()), 3u);
       if ((a[v_2] < 10.0f)) {
       } else {
         break;
       }
       {
-        int v_3 = idx3();
+        uint v_3 = min(uint(idx3()), 3u);
         a[v_3] = (a[v_3] + 1.0f);
       }
       continue;
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.msl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.msl
index 4ec904b..7a589be 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.msl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.ir.msl
@@ -24,6 +24,9 @@
   T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int idx1(tint_module_vars_struct tint_module_vars) {
   (*tint_module_vars.i) = ((*tint_module_vars.i) + 1u);
   return 1;
@@ -42,15 +45,16 @@
 void foo(tint_module_vars_struct tint_module_vars) {
   tint_array<float, 4> a = tint_array<float, 4>{};
   {
-    thread float* const v_1 = (&a[idx1(tint_module_vars)]);
+    thread float* const v_1 = (&a[min(uint(idx1(tint_module_vars)), 3u)]);
     (*v_1) = ((*v_1) * 2.0f);
     while(true) {
-      if ((a[idx2(tint_module_vars)] < 10.0f)) {
+      TINT_ISOLATE_UB(tint_volatile_false)
+      if ((a[min(uint(idx2(tint_module_vars)), 3u)] < 10.0f)) {
       } else {
         break;
       }
       {
-        thread float* const v_2 = (&a[idx3(tint_module_vars)]);
+        thread float* const v_2 = (&a[min(uint(idx3(tint_module_vars)), 3u)]);
         (*v_2) = ((*v_2) + 1.0f);
       }
       continue;
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl b/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
index 5d741a3..322e836 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.msl
@@ -14,6 +14,9 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint i;
 };
@@ -43,18 +46,19 @@
   tint_array<float, 4> a = tint_array<float, 4>{};
   {
     int const tint_symbol_2 = idx1(tint_private_vars);
-    int const tint_symbol_save = tint_symbol_2;
+    uint const tint_symbol_save = min(uint(tint_symbol_2), 3u);
     a[tint_symbol_save] = (a[tint_symbol_save] * 2.0f);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       int const tint_symbol_3 = idx2(tint_private_vars);
-      if (!((a[tint_symbol_3] < 10.0f))) {
+      if (!((a[min(uint(tint_symbol_3), 3u)] < 10.0f))) {
         break;
       }
       {
       }
       {
         int const tint_symbol_4 = idx3(tint_private_vars);
-        int const tint_symbol_1_save = tint_symbol_4;
+        uint const tint_symbol_1_save = min(uint(tint_symbol_4), 3u);
         a[tint_symbol_1_save] = (a[tint_symbol_1_save] + 1.0f);
       }
     }
diff --git a/test/tint/statements/compound_assign/for_loop.wgsl.expected.spvasm b/test/tint/statements/compound_assign/for_loop.wgsl.expected.spvasm
index 9ff6f18..b9b896e 100644
--- a/test/tint/statements/compound_assign/for_loop.wgsl.expected.spvasm
+++ b/test/tint/statements/compound_assign/for_loop.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 66
+; Bound: 73
 ; Schema: 0
                OpCapability Shader
+         %48 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -88,36 +89,42 @@
                OpBranch %40
          %40 = OpLabel
          %45 = OpFunctionCall %int %idx1
-         %46 = OpAccessChain %_ptr_Function_float %a %45
-         %48 = OpLoad %float %46 None
-         %49 = OpFMul %float %48 %float_2
-               OpStore %46 %49 None
+         %46 = OpBitcast %uint %45
+         %47 = OpExtInst %uint %48 UMin %46 %uint_3
+         %49 = OpAccessChain %_ptr_Function_float %a %47
+         %51 = OpLoad %float %49 None
+         %52 = OpFMul %float %51 %float_2
+               OpStore %49 %52 None
                OpBranch %43
          %43 = OpLabel
                OpLoopMerge %44 %42 None
                OpBranch %41
          %41 = OpLabel
-         %51 = OpFunctionCall %int %idx2
-         %52 = OpAccessChain %_ptr_Function_float %a %51
-         %53 = OpLoad %float %52 None
-         %54 = OpFOrdLessThan %bool %53 %float_10
-               OpSelectionMerge %57 None
-               OpBranchConditional %54 %57 %58
-         %58 = OpLabel
+         %54 = OpFunctionCall %int %idx2
+         %55 = OpBitcast %uint %54
+         %56 = OpExtInst %uint %48 UMin %55 %uint_3
+         %57 = OpAccessChain %_ptr_Function_float %a %56
+         %58 = OpLoad %float %57 None
+         %59 = OpFOrdLessThan %bool %58 %float_10
+               OpSelectionMerge %62 None
+               OpBranchConditional %59 %62 %63
+         %63 = OpLabel
                OpBranch %44
-         %57 = OpLabel
+         %62 = OpLabel
                OpBranch %42
          %42 = OpLabel
-         %59 = OpFunctionCall %int %idx3
-         %60 = OpAccessChain %_ptr_Function_float %a %59
-         %61 = OpLoad %float %60 None
-         %62 = OpFAdd %float %61 %float_1
-               OpStore %60 %62 None
+         %64 = OpFunctionCall %int %idx3
+         %65 = OpBitcast %uint %64
+         %66 = OpExtInst %uint %48 UMin %65 %uint_3
+         %67 = OpAccessChain %_ptr_Function_float %a %66
+         %68 = OpLoad %float %67 None
+         %69 = OpFAdd %float %68 %float_1
+               OpStore %67 %69 None
                OpBranch %43
          %44 = OpLabel
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %33
-         %65 = OpLabel
+         %72 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.dxc.hlsl b/test/tint/statements/decrement/array_element.wgsl.expected.dxc.hlsl
index 69eba00..8b82f55 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.dxc.hlsl
@@ -6,5 +6,8 @@
 RWByteAddressBuffer a : register(u0);
 
 void main() {
-  a.Store(4u, asuint((a.Load(4u) - 1u)));
+  uint tint_symbol_2 = 0u;
+  a.GetDimensions(tint_symbol_2);
+  uint tint_symbol_3 = (tint_symbol_2 / 4u);
+  a.Store((4u * min(1u, (tint_symbol_3 - 1u))), asuint((a.Load((4u * min(1u, (tint_symbol_3 - 1u)))) - 1u)));
 }
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.fxc.hlsl b/test/tint/statements/decrement/array_element.wgsl.expected.fxc.hlsl
index 69eba00..8b82f55 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.fxc.hlsl
@@ -6,5 +6,8 @@
 RWByteAddressBuffer a : register(u0);
 
 void main() {
-  a.Store(4u, asuint((a.Load(4u) - 1u)));
+  uint tint_symbol_2 = 0u;
+  a.GetDimensions(tint_symbol_2);
+  uint tint_symbol_3 = (tint_symbol_2 / 4u);
+  a.Store((4u * min(1u, (tint_symbol_3 - 1u))), asuint((a.Load((4u * min(1u, (tint_symbol_3 - 1u)))) - 1u)));
 }
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.glsl b/test/tint/statements/decrement/array_element.wgsl.expected.glsl
index aab5b13..246f5ce 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.glsl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.glsl
@@ -5,7 +5,9 @@
   uint inner[];
 } v;
 void tint_symbol() {
-  v.inner[1] = (v.inner[1] - 1u);
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  v.inner[v_2] = (v.inner[v_2] - 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/decrement/array_element.wgsl.expected.ir.dxc.hlsl
index a35e7d0..7130cf4 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,11 @@
 
 RWByteAddressBuffer a : register(u0);
 void main() {
-  a.Store(4u, (a.Load(4u) - 1u));
+  uint v = 0u;
+  a.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(1)), v_1) * 4u);
+  a.Store((0u + v_2), (a.Load((0u + v_2)) - 1u));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/decrement/array_element.wgsl.expected.ir.fxc.hlsl
index a35e7d0..7130cf4 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,11 @@
 
 RWByteAddressBuffer a : register(u0);
 void main() {
-  a.Store(4u, (a.Load(4u) - 1u));
+  uint v = 0u;
+  a.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(1)), v_1) * 4u);
+  a.Store((0u + v_2), (a.Load((0u + v_2)) - 1u));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.ir.msl b/test/tint/statements/decrement/array_element.wgsl.expected.ir.msl
index 48e1a04..c5e9d04 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.ir.msl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.ir.msl
@@ -15,8 +15,11 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* a;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.a)[1] = ((*tint_module_vars.a)[1] - 1u);
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  device uint* const v_1 = (&(*tint_module_vars.a)[min(uint(1), v)]);
+  (*v_1) = ((*v_1) - 1u);
 }
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.msl b/test/tint/statements/decrement/array_element.wgsl.expected.msl
index 56896d1..91ca14c 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.msl
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.msl
@@ -14,7 +14,12 @@
     T elements[N];
 };
 
-void tint_symbol(device tint_array<uint, 1>* const tint_symbol_2) {
-  (*(tint_symbol_2))[1] = ((*(tint_symbol_2))[1] - 1u);
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+void tint_symbol(const constant TintArrayLengths* const tint_symbol_2, device tint_array<uint, 1>* const tint_symbol_3) {
+  uint const tint_symbol_1_save = min(1u, (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u));
+  (*(tint_symbol_3))[tint_symbol_1_save] = ((*(tint_symbol_3))[tint_symbol_1_save] - 1u);
 }
 
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.spvasm b/test/tint/statements/decrement/array_element.wgsl.expected.spvasm
index a7043da..1584a07 100644
--- a/test/tint/statements/decrement/array_element.wgsl.expected.spvasm
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 20
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -24,20 +25,26 @@
           %1 = OpVariable %_ptr_StorageBuffer_a_block StorageBuffer
        %void = OpTypeVoid
           %8 = OpTypeFunction %void
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
        %main = OpFunction %void None %8
           %9 = OpLabel
-         %10 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_1
-         %15 = OpLoad %uint %10 None
-         %16 = OpISub %uint %15 %uint_1
-               OpStore %10 %16 None
+         %10 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %13 = OpArrayLength %uint %1 0
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %19
+         %23 = OpLoad %uint %21 None
+         %24 = OpISub %uint %23 %uint_1
+               OpStore %21 %24 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %8
-         %19 = OpLabel
+         %26 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl
index 8d8d087..25df7a9 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.dxc.hlsl
@@ -38,10 +38,13 @@
 
 void main() {
   {
+    uint tint_symbol_5 = 0u;
+    buffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = (tint_symbol_5 / 64u);
     int tint_symbol_save = idx1();
     int tint_symbol_save_1 = idx2();
     int tint_symbol_1 = idx3();
-    buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) - 1)));
+    buffer.Store((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))))) - 1)));
     while (true) {
       if (!((v < 10u))) {
         break;
@@ -49,10 +52,13 @@
       {
       }
       {
+        uint tint_symbol_7 = 0u;
+        buffer.GetDimensions(tint_symbol_7);
+        uint tint_symbol_8 = (tint_symbol_7 / 64u);
         int tint_symbol_2_save = idx4();
         int tint_symbol_2_save_1 = idx5();
         int tint_symbol_3 = idx6();
-        buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) - 1)));
+        buffer.Store((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))))) - 1)));
       }
     }
   }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl
index 8d8d087..25df7a9 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.fxc.hlsl
@@ -38,10 +38,13 @@
 
 void main() {
   {
+    uint tint_symbol_5 = 0u;
+    buffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = (tint_symbol_5 / 64u);
     int tint_symbol_save = idx1();
     int tint_symbol_save_1 = idx2();
     int tint_symbol_1 = idx3();
-    buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) - 1)));
+    buffer.Store((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))))) - 1)));
     while (true) {
       if (!((v < 10u))) {
         break;
@@ -49,10 +52,13 @@
       {
       }
       {
+        uint tint_symbol_7 = 0u;
+        buffer.GetDimensions(tint_symbol_7);
+        uint tint_symbol_8 = (tint_symbol_7 / 64u);
         int tint_symbol_2_save = idx4();
         int tint_symbol_2_save_1 = idx5();
         int tint_symbol_3 = idx6();
-        buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) - 1)));
+        buffer.Store((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))))) - 1)));
       }
     }
   }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.glsl b/test/tint/statements/decrement/complex.wgsl.expected.glsl
index ac90566..1057b7b 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.glsl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.glsl
@@ -38,18 +38,26 @@
   {
     int v_2 = idx1();
     int v_3 = idx2();
-    int v_4 = idx3();
-    v_1.inner[v_2].a[v_3][v_4] = (v_1.inner[v_2].a[v_3][v_4] - 1);
+    uint v_4 = (uint(v_1.inner.length()) - 1u);
+    uint v_5 = min(uint(v_2), v_4);
+    uint v_6 = min(uint(v_3), 3u);
+    int v_7 = idx3();
+    int v_8 = (v_1.inner[v_5].a[v_6][min(uint(v_7), 3u)] - 1);
+    v_1.inner[v_5].a[v_6][min(uint(v_7), 3u)] = v_8;
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_5 = idx4();
-        int v_6 = idx5();
-        int v_7 = idx6();
-        v_1.inner[v_5].a[v_6][v_7] = (v_1.inner[v_5].a[v_6][v_7] - 1);
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = (uint(v_1.inner.length()) - 1u);
+        uint v_12 = min(uint(v_9), v_11);
+        uint v_13 = min(uint(v_10), 3u);
+        int v_14 = idx6();
+        int v_15 = (v_1.inner[v_12].a[v_13][min(uint(v_14), 3u)] - 1);
+        v_1.inner[v_12].a[v_13][min(uint(v_14), 3u)] = v_15;
       }
       continue;
     }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.ir.dxc.hlsl
index 8c8721c..8882183 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.ir.dxc.hlsl
@@ -35,24 +35,30 @@
   {
     int v_1 = idx1();
     int v_2 = idx2();
-    uint v_3 = (uint(v_1) * 64u);
-    uint v_4 = (uint(v_2) * 16u);
-    int v_5 = idx3();
-    int v_6 = (asint(buffer.Load((((0u + v_3) + v_4) + (uint(v_5) * 4u)))) - int(1));
-    buffer.Store((((0u + v_3) + v_4) + (uint(v_5) * 4u)), asuint(v_6));
+    uint v_3 = 0u;
+    buffer.GetDimensions(v_3);
+    uint v_4 = ((v_3 / 64u) - 1u);
+    uint v_5 = min(uint(v_1), v_4);
+    uint v_6 = (min(uint(v_2), 3u) * 16u);
+    int v_7 = idx3();
+    int v_8 = (asint(buffer.Load((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)))) - int(1));
+    buffer.Store((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)), asuint(v_8));
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_7 = idx4();
-        int v_8 = idx5();
-        uint v_9 = (uint(v_7) * 64u);
-        uint v_10 = (uint(v_8) * 16u);
-        int v_11 = idx6();
-        int v_12 = (asint(buffer.Load((((0u + v_9) + v_10) + (uint(v_11) * 4u)))) - int(1));
-        buffer.Store((((0u + v_9) + v_10) + (uint(v_11) * 4u)), asuint(v_12));
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = 0u;
+        buffer.GetDimensions(v_11);
+        uint v_12 = ((v_11 / 64u) - 1u);
+        uint v_13 = min(uint(v_9), v_12);
+        uint v_14 = (min(uint(v_10), 3u) * 16u);
+        int v_15 = idx6();
+        int v_16 = (asint(buffer.Load((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)))) - int(1));
+        buffer.Store((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)), asuint(v_16));
       }
       continue;
     }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.ir.fxc.hlsl
index 8c8721c..8882183 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.ir.fxc.hlsl
@@ -35,24 +35,30 @@
   {
     int v_1 = idx1();
     int v_2 = idx2();
-    uint v_3 = (uint(v_1) * 64u);
-    uint v_4 = (uint(v_2) * 16u);
-    int v_5 = idx3();
-    int v_6 = (asint(buffer.Load((((0u + v_3) + v_4) + (uint(v_5) * 4u)))) - int(1));
-    buffer.Store((((0u + v_3) + v_4) + (uint(v_5) * 4u)), asuint(v_6));
+    uint v_3 = 0u;
+    buffer.GetDimensions(v_3);
+    uint v_4 = ((v_3 / 64u) - 1u);
+    uint v_5 = min(uint(v_1), v_4);
+    uint v_6 = (min(uint(v_2), 3u) * 16u);
+    int v_7 = idx3();
+    int v_8 = (asint(buffer.Load((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)))) - int(1));
+    buffer.Store((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)), asuint(v_8));
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_7 = idx4();
-        int v_8 = idx5();
-        uint v_9 = (uint(v_7) * 64u);
-        uint v_10 = (uint(v_8) * 16u);
-        int v_11 = idx6();
-        int v_12 = (asint(buffer.Load((((0u + v_9) + v_10) + (uint(v_11) * 4u)))) - int(1));
-        buffer.Store((((0u + v_9) + v_10) + (uint(v_11) * 4u)), asuint(v_12));
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = 0u;
+        buffer.GetDimensions(v_11);
+        uint v_12 = ((v_11 / 64u) - 1u);
+        uint v_13 = min(uint(v_9), v_12);
+        uint v_14 = (min(uint(v_10), 3u) * 16u);
+        int v_15 = idx6();
+        int v_16 = (asint(buffer.Load((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)))) - int(1));
+        buffer.Store((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)), asuint(v_16));
       }
       continue;
     }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.ir.msl b/test/tint/statements/decrement/complex.wgsl.expected.ir.msl
index bb56100..91040d4 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.ir.msl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.ir.msl
@@ -20,8 +20,12 @@
 struct tint_module_vars_struct {
   device tint_array<S, 1>* tint_symbol;
   thread uint* v;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int idx1(tint_module_vars_struct tint_module_vars) {
   (*tint_module_vars.v) = ((*tint_module_vars.v) - 1u);
   return 1;
@@ -55,19 +59,28 @@
 void tint_symbol_1(tint_module_vars_struct tint_module_vars) {
   {
     int const v_1 = idx1(tint_module_vars);
-    device int4* const v_2 = (&(*tint_module_vars.tint_symbol)[v_1].a[idx2(tint_module_vars)]);
-    int const v_3 = idx3(tint_module_vars);
-    (*v_2)[v_3] = as_type<int>((as_type<uint>((*v_2)[v_3]) - as_type<uint>(1)));
+    int const v_2 = idx2(tint_module_vars);
+    uint const v_3 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 64u) - 1u);
+    uint const v_4 = min(uint(v_1), v_3);
+    device int4* const v_5 = (&(*tint_module_vars.tint_symbol)[v_4].a[min(uint(v_2), 3u)]);
+    int const v_6 = idx3(tint_module_vars);
+    int const v_7 = as_type<int>((as_type<uint>((*v_5)[min(uint(v_6), 3u)]) - as_type<uint>(1)));
+    (*v_5)[min(uint(v_6), 3u)] = v_7;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.v) < 10u)) {
       } else {
         break;
       }
       {
-        int const v_4 = idx4(tint_module_vars);
-        device int4* const v_5 = (&(*tint_module_vars.tint_symbol)[v_4].a[idx5(tint_module_vars)]);
-        int const v_6 = idx6(tint_module_vars);
-        (*v_5)[v_6] = as_type<int>((as_type<uint>((*v_5)[v_6]) - as_type<uint>(1)));
+        int const v_8 = idx4(tint_module_vars);
+        int const v_9 = idx5(tint_module_vars);
+        uint const v_10 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 64u) - 1u);
+        uint const v_11 = min(uint(v_8), v_10);
+        device int4* const v_12 = (&(*tint_module_vars.tint_symbol)[v_11].a[min(uint(v_9), 3u)]);
+        int const v_13 = idx6(tint_module_vars);
+        int const v_14 = as_type<int>((as_type<uint>((*v_12)[min(uint(v_13), 3u)]) - as_type<uint>(1)));
+        (*v_12)[min(uint(v_13), 3u)] = v_14;
       }
       continue;
     }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.msl b/test/tint/statements/decrement/complex.wgsl.expected.msl
index abaf557..dc659fc 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.msl
+++ b/test/tint/statements/decrement/complex.wgsl.expected.msl
@@ -14,10 +14,17 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint v;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct S {
   /* 0x0000 */ tint_array<int4, 4> a;
 };
@@ -52,15 +59,16 @@
   return 2;
 }
 
-void tint_symbol_1(thread tint_private_vars_struct* const tint_private_vars, device tint_array<S, 1>* const tint_symbol_10) {
+void tint_symbol_1(thread tint_private_vars_struct* const tint_private_vars, const constant TintArrayLengths* const tint_symbol_10, device tint_array<S, 1>* const tint_symbol_11) {
   {
     int const tint_symbol_6 = idx1(tint_private_vars);
     int const tint_symbol_7 = idx2(tint_private_vars);
-    int const tint_symbol_2_save = tint_symbol_6;
-    int const tint_symbol_2_save_1 = tint_symbol_7;
+    uint const tint_symbol_2_save = min(uint(tint_symbol_6), (((*(tint_symbol_10)).array_lengths[0u][0u] / 64u) - 1u));
+    uint const tint_symbol_2_save_1 = min(uint(tint_symbol_7), 3u);
     int const tint_symbol_3 = idx3(tint_private_vars);
-    (*(tint_symbol_10))[tint_symbol_2_save].a[tint_symbol_2_save_1][tint_symbol_3] = as_type<int>((as_type<uint>((*(tint_symbol_10))[tint_symbol_2_save].a[tint_symbol_2_save_1][tint_symbol_3]) - as_type<uint>(1)));
+    (*(tint_symbol_11))[tint_symbol_2_save].a[tint_symbol_2_save_1][min(uint(tint_symbol_3), 3u)] = as_type<int>((as_type<uint>((*(tint_symbol_11))[tint_symbol_2_save].a[tint_symbol_2_save_1][min(uint(tint_symbol_3), 3u)]) - as_type<uint>(1)));
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       if (!(((*(tint_private_vars)).v < 10u))) {
         break;
       }
@@ -69,10 +77,10 @@
       {
         int const tint_symbol_8 = idx4(tint_private_vars);
         int const tint_symbol_9 = idx5(tint_private_vars);
-        int const tint_symbol_4_save = tint_symbol_8;
-        int const tint_symbol_4_save_1 = tint_symbol_9;
+        uint const tint_symbol_4_save = min(uint(tint_symbol_8), (((*(tint_symbol_10)).array_lengths[0u][0u] / 64u) - 1u));
+        uint const tint_symbol_4_save_1 = min(uint(tint_symbol_9), 3u);
         int const tint_symbol_5 = idx6(tint_private_vars);
-        (*(tint_symbol_10))[tint_symbol_4_save].a[tint_symbol_4_save_1][tint_symbol_5] = as_type<int>((as_type<uint>((*(tint_symbol_10))[tint_symbol_4_save].a[tint_symbol_4_save_1][tint_symbol_5]) - as_type<uint>(1)));
+        (*(tint_symbol_11))[tint_symbol_4_save].a[tint_symbol_4_save_1][min(uint(tint_symbol_5), 3u)] = as_type<int>((as_type<uint>((*(tint_symbol_11))[tint_symbol_4_save].a[tint_symbol_4_save_1][min(uint(tint_symbol_5), 3u)]) - as_type<uint>(1)));
       }
     }
   }
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.spvasm b/test/tint/statements/decrement/complex.wgsl.expected.spvasm
index d89c71f..882bc5e 100644
--- a/test/tint/statements/decrement/complex.wgsl.expected.spvasm
+++ b/test/tint/statements/decrement/complex.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
+         %63 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -50,8 +51,10 @@
       %int_0 = OpConstant %int 0
        %void = OpTypeVoid
          %47 = OpTypeFunction %void
-%_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
+%_ptr_StorageBuffer__runtimearr_S = OpTypePointer StorageBuffer %_runtimearr_S
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
+%_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
     %uint_10 = OpConstant %uint 10
        %bool = OpTypeBool
@@ -103,41 +106,63 @@
          %49 = OpLabel
          %54 = OpFunctionCall %int %idx1
          %55 = OpFunctionCall %int %idx2
-         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %54 %uint_0 %55
-         %59 = OpFunctionCall %int %idx3
-         %60 = OpAccessChain %_ptr_StorageBuffer_int %56 %59
-         %62 = OpLoad %int %60 None
-         %63 = OpISub %int %62 %int_1
-         %64 = OpAccessChain %_ptr_StorageBuffer_int %56 %59
-               OpStore %64 %63 None
+         %56 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %1 %uint_0
+         %59 = OpArrayLength %uint %1 0
+         %60 = OpISub %uint %59 %uint_1
+         %61 = OpBitcast %uint %54
+         %62 = OpExtInst %uint %63 UMin %61 %60
+         %64 = OpBitcast %uint %55
+         %65 = OpExtInst %uint %63 UMin %64 %uint_3
+         %67 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %62 %uint_0 %65
+         %69 = OpFunctionCall %int %idx3
+         %70 = OpBitcast %uint %69
+         %71 = OpExtInst %uint %63 UMin %70 %uint_3
+         %72 = OpAccessChain %_ptr_StorageBuffer_int %67 %71
+         %74 = OpLoad %int %72 None
+         %75 = OpISub %int %74 %int_1
+         %76 = OpBitcast %uint %69
+         %77 = OpExtInst %uint %63 UMin %76 %uint_3
+         %78 = OpAccessChain %_ptr_StorageBuffer_int %67 %77
+               OpStore %78 %75 None
                OpBranch %52
          %52 = OpLabel
                OpLoopMerge %53 %51 None
                OpBranch %50
          %50 = OpLabel
-         %65 = OpLoad %uint %v None
-         %66 = OpULessThan %bool %65 %uint_10
-               OpSelectionMerge %69 None
-               OpBranchConditional %66 %69 %70
-         %70 = OpLabel
+         %79 = OpLoad %uint %v None
+         %80 = OpULessThan %bool %79 %uint_10
+               OpSelectionMerge %83 None
+               OpBranchConditional %80 %83 %84
+         %84 = OpLabel
                OpBranch %53
-         %69 = OpLabel
+         %83 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %71 = OpFunctionCall %int %idx4
-         %72 = OpFunctionCall %int %idx5
-         %73 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %71 %uint_0 %72
-         %74 = OpFunctionCall %int %idx6
-         %75 = OpAccessChain %_ptr_StorageBuffer_int %73 %74
-         %76 = OpLoad %int %75 None
-         %77 = OpISub %int %76 %int_1
-         %78 = OpAccessChain %_ptr_StorageBuffer_int %73 %74
-               OpStore %78 %77 None
+         %85 = OpFunctionCall %int %idx4
+         %86 = OpFunctionCall %int %idx5
+         %87 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %1 %uint_0
+         %88 = OpArrayLength %uint %1 0
+         %89 = OpISub %uint %88 %uint_1
+         %90 = OpBitcast %uint %85
+         %91 = OpExtInst %uint %63 UMin %90 %89
+         %92 = OpBitcast %uint %86
+         %93 = OpExtInst %uint %63 UMin %92 %uint_3
+         %94 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %91 %uint_0 %93
+         %95 = OpFunctionCall %int %idx6
+         %96 = OpBitcast %uint %95
+         %97 = OpExtInst %uint %63 UMin %96 %uint_3
+         %98 = OpAccessChain %_ptr_StorageBuffer_int %94 %97
+         %99 = OpLoad %int %98 None
+        %100 = OpISub %int %99 %int_1
+        %101 = OpBitcast %uint %95
+        %102 = OpExtInst %uint %63 UMin %101 %uint_3
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %94 %102
+               OpStore %103 %100 None
                OpBranch %52
          %53 = OpLabel
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %47
-         %80 = OpLabel
+        %105 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.ir.msl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.ir.msl
index d61534f..df04b49 100644
--- a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.ir.msl
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.ir.msl
@@ -5,9 +5,13 @@
   device uint* i;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.i) < 10u)) {
       } else {
         break;
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl
index c91c6b2..2f44b37 100644
--- a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(device uint* const tint_symbol_1) {
   for(; (*(tint_symbol_1) < 10u); *(tint_symbol_1) = (*(tint_symbol_1) - 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.ir.msl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.ir.msl
index 7bcb668..6bb40ad 100644
--- a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.ir.msl
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.ir.msl
@@ -5,10 +5,14 @@
   device uint* i;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   {
     (*tint_module_vars.i) = ((*tint_module_vars.i) - 1u);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.i) < 10u)) {
       } else {
         break;
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl
index 1f1ebdf..783853d 100644
--- a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(device uint* const tint_symbol_1) {
   for(*(tint_symbol_1) = (*(tint_symbol_1) - 1u); (*(tint_symbol_1) < 10u); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.dxc.hlsl b/test/tint/statements/decrement/vector_component.wgsl.expected.dxc.hlsl
index cc37da7..8f60079 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.dxc.hlsl
@@ -7,6 +7,6 @@
 
 void main() {
   int tint_symbol_1 = 1;
-  a.Store((4u * uint(tint_symbol_1)), asuint((a.Load((4u * uint(tint_symbol_1))) - 1u)));
+  a.Store((4u * min(uint(tint_symbol_1), 3u)), asuint((a.Load((4u * min(uint(tint_symbol_1), 3u))) - 1u)));
   a.Store(8u, asuint((a.Load(8u) - 1u)));
 }
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.fxc.hlsl b/test/tint/statements/decrement/vector_component.wgsl.expected.fxc.hlsl
index cc37da7..8f60079 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.fxc.hlsl
@@ -7,6 +7,6 @@
 
 void main() {
   int tint_symbol_1 = 1;
-  a.Store((4u * uint(tint_symbol_1)), asuint((a.Load((4u * uint(tint_symbol_1))) - 1u)));
+  a.Store((4u * min(uint(tint_symbol_1), 3u)), asuint((a.Load((4u * min(uint(tint_symbol_1), 3u))) - 1u)));
   a.Store(8u, asuint((a.Load(8u) - 1u)));
 }
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.glsl b/test/tint/statements/decrement/vector_component.wgsl.expected.glsl
index 3482af1..44af40d 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.glsl
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.glsl
@@ -5,7 +5,7 @@
   uvec4 inner;
 } v;
 void tint_symbol() {
-  v.inner[1] = (v.inner.y - 1u);
+  v.inner[1u] = (v.inner.y - 1u);
   v.inner[2u] = (v.inner.z - 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.ir.msl b/test/tint/statements/decrement/vector_component.wgsl.expected.ir.msl
index 9f98da9..10c8ce4 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.ir.msl
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.ir.msl
@@ -6,6 +6,6 @@
 };
 
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.a)[1] = ((*tint_module_vars.a)[1] - 1u);
+  (*tint_module_vars.a)[1u] = ((*tint_module_vars.a)[1u] - 1u);
   (*tint_module_vars.a)[2u] = ((*tint_module_vars.a)[2u] - 1u);
 }
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.msl b/test/tint/statements/decrement/vector_component.wgsl.expected.msl
index 7211766..96a7078 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.msl
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 void tint_symbol(device uint4* const tint_symbol_3) {
   int const tint_symbol_2 = 1;
-  (*(tint_symbol_3))[tint_symbol_2] = ((*(tint_symbol_3))[tint_symbol_2] - 1u);
+  (*(tint_symbol_3))[min(uint(tint_symbol_2), 3u)] = ((*(tint_symbol_3))[min(uint(tint_symbol_2), 3u)] - 1u);
   (*(tint_symbol_3))[2] = ((*(tint_symbol_3))[2] - 1u);
 }
 
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm b/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm
index e0d7537..b6f60de 100644
--- a/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,29 +26,27 @@
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
        %main = OpFunction %void None %8
           %9 = OpLabel
          %10 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %13 = OpAccessChain %_ptr_StorageBuffer_uint %10 %int_1
-         %17 = OpLoad %uint %13 None
-         %18 = OpISub %uint %17 %uint_1
+         %13 = OpAccessChain %_ptr_StorageBuffer_uint %10 %uint_1
+         %16 = OpLoad %uint %13 None
+         %17 = OpISub %uint %16 %uint_1
+         %18 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+         %19 = OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_1
+               OpStore %19 %17 None
          %20 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %21 = OpAccessChain %_ptr_StorageBuffer_uint %20 %int_1
-               OpStore %21 %18 None
-         %22 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %23 = OpAccessChain %_ptr_StorageBuffer_uint %22 %uint_2
-         %25 = OpLoad %uint %23 None
-         %26 = OpISub %uint %25 %uint_1
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %28 = OpAccessChain %_ptr_StorageBuffer_uint %27 %uint_2
-               OpStore %28 %26 None
+         %21 = OpAccessChain %_ptr_StorageBuffer_uint %20 %uint_2
+         %23 = OpLoad %uint %21 None
+         %24 = OpISub %uint %23 %uint_1
+         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+         %26 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_2
+               OpStore %26 %24 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %8
-         %30 = OpLabel
+         %28 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.msl b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.msl
index 910b629..7e4bc07 100644
--- a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.msl
+++ b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.ir.msl
@@ -8,6 +8,9 @@
   thread bool* continue_execution;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct foo_outputs {
   int tint_symbol [[color(0)]];
 };
@@ -29,6 +32,7 @@
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 10)) {
       } else {
         break;
diff --git a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.msl b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.msl
index 94954bc..f2295b4 100644
--- a/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.msl
+++ b/test/tint/statements/discard/atomic_in_for_loop_continuing.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   bool tint_discarded;
 };
@@ -27,6 +31,7 @@
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       if (!((i < 10))) {
         break;
       }
diff --git a/test/tint/statements/discard/loop_discard_return.wgsl.expected.ir.msl b/test/tint/statements/discard/loop_discard_return.wgsl.expected.ir.msl
index 26ef48b..752536e 100644
--- a/test/tint/statements/discard/loop_discard_return.wgsl.expected.ir.msl
+++ b/test/tint/statements/discard/loop_discard_return.wgsl.expected.ir.msl
@@ -5,9 +5,13 @@
   thread bool* continue_execution;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f(tint_module_vars_struct tint_module_vars) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       (*tint_module_vars.continue_execution) = false;
       return;
     }
diff --git a/test/tint/statements/discard/loop_discard_return.wgsl.expected.msl b/test/tint/statements/discard/loop_discard_return.wgsl.expected.msl
index 1c56122..b522ea0 100644
--- a/test/tint/statements/discard/loop_discard_return.wgsl.expected.msl
+++ b/test/tint/statements/discard/loop_discard_return.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   while(true) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     discard_fragment();
     return;
   }
diff --git a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.msl b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.msl
index f28cc27..1c9efef 100644
--- a/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.msl
+++ b/test/tint/statements/discard/multiple_returns.wgsl.expected.ir.msl
@@ -7,6 +7,9 @@
   thread bool* continue_execution;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 fragment void tint_symbol(device int* non_uniform_global [[buffer(0)]], device float* output [[buffer(1)]]) {
   thread bool continue_execution = true;
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.non_uniform_global=non_uniform_global, .output=output, .continue_execution=(&continue_execution)};
@@ -21,6 +24,7 @@
     int i = 0;
     {
       while(true) {
+        TINT_ISOLATE_UB(tint_volatile_false)
         float const v_1 = (*tint_module_vars.output);
         if ((v_1 > float(i))) {
           float const v_2 = float(i);
diff --git a/test/tint/statements/discard/multiple_returns.wgsl.expected.msl b/test/tint/statements/discard/multiple_returns.wgsl.expected.msl
index 519adcf..669ce6c 100644
--- a/test/tint/statements/discard/multiple_returns.wgsl.expected.msl
+++ b/test/tint/statements/discard/multiple_returns.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   bool tint_discarded;
 };
@@ -18,6 +22,7 @@
   if ((*(tint_symbol_3) < 0.0f)) {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       if ((*(tint_symbol_3) > float(i))) {
         if (!(tint_private_vars.tint_discarded)) {
           *(tint_symbol_3) = float(i);
diff --git a/test/tint/statements/for/basic.wgsl.expected.msl b/test/tint/statements/for/basic.wgsl.expected.msl
index 20c444b..3fb7d2b 100644
--- a/test/tint/statements/for/basic.wgsl.expected.msl
+++ b/test/tint/statements/for/basic.wgsl.expected.msl
@@ -1,11 +1,16 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void some_loop_body() {
 }
 
 void f() {
   for(int i = 0; (i < 5); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     some_loop_body();
   }
 }
diff --git a/test/tint/statements/for/complex.wgsl.expected.ir.msl b/test/tint/statements/for/complex.wgsl.expected.ir.msl
index 8c93752..4dd60ee 100644
--- a/test/tint/statements/for/complex.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/complex.wgsl.expected.ir.msl
@@ -1,6 +1,9 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void some_loop_body() {
 }
 
@@ -9,6 +12,7 @@
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       bool v = false;
       if ((i < 5)) {
         v = (j < 10);
diff --git a/test/tint/statements/for/complex.wgsl.expected.msl b/test/tint/statements/for/complex.wgsl.expected.msl
index 534cd3a..b21df71 100644
--- a/test/tint/statements/for/complex.wgsl.expected.msl
+++ b/test/tint/statements/for/complex.wgsl.expected.msl
@@ -1,12 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void some_loop_body() {
 }
 
 void f() {
   int j = 0;
   for(int i = 0; ((i < 5) && (j < 10)); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     some_loop_body();
     j = as_type<int>((as_type<uint>(i) * as_type<uint>(30)));
   }
diff --git a/test/tint/statements/for/condition/array_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/condition/array_ctor.wgsl.expected.ir.msl
index 0acd4a1..02a71f0 100644
--- a/test/tint/statements/for/condition/array_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/condition/array_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 1)) {
       } else {
         break;
diff --git a/test/tint/statements/for/condition/array_ctor.wgsl.expected.msl b/test/tint/statements/for/condition/array_ctor.wgsl.expected.msl
index 31a0722..2246141 100644
--- a/test/tint/statements/for/condition/array_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/condition/array_ctor.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   for(; (i < 1); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/condition/basic.wgsl.expected.ir.msl b/test/tint/statements/for/condition/basic.wgsl.expected.ir.msl
index c42baba..fae57d4 100644
--- a/test/tint/statements/for/condition/basic.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/condition/basic.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 4)) {
       } else {
         break;
diff --git a/test/tint/statements/for/condition/basic.wgsl.expected.msl b/test/tint/statements/for/condition/basic.wgsl.expected.msl
index 839541b..5cb6019 100644
--- a/test/tint/statements/for/condition/basic.wgsl.expected.msl
+++ b/test/tint/statements/for/condition/basic.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   for(; (i < 4); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/condition/struct_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/condition/struct_ctor.wgsl.expected.ir.msl
index 0acd4a1..02a71f0 100644
--- a/test/tint/statements/for/condition/struct_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/condition/struct_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if ((i < 1)) {
       } else {
         break;
diff --git a/test/tint/statements/for/condition/struct_ctor.wgsl.expected.msl b/test/tint/statements/for/condition/struct_ctor.wgsl.expected.msl
index a0a3bf0..3e5e131 100644
--- a/test/tint/statements/for/condition/struct_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/condition/struct_ctor.wgsl.expected.msl
@@ -1,6 +1,10 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   int i;
 };
@@ -8,6 +12,7 @@
 void f() {
   int i = 0;
   for(; (i < 1); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/continuing/array_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/continuing/array_ctor.wgsl.expected.ir.msl
index e67c4cd..76a659f 100644
--- a/test/tint/statements/for/continuing/array_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/continuing/array_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/continuing/array_ctor.wgsl.expected.msl b/test/tint/statements/for/continuing/array_ctor.wgsl.expected.msl
index 3130ddd..f26ddd1 100644
--- a/test/tint/statements/for/continuing/array_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/continuing/array_ctor.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   for(; false; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/continuing/basic.wgsl.expected.ir.msl b/test/tint/statements/for/continuing/basic.wgsl.expected.ir.msl
index e67c4cd..76a659f 100644
--- a/test/tint/statements/for/continuing/basic.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/continuing/basic.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/continuing/basic.wgsl.expected.msl b/test/tint/statements/for/continuing/basic.wgsl.expected.msl
index 3130ddd..f26ddd1 100644
--- a/test/tint/statements/for/continuing/basic.wgsl.expected.msl
+++ b/test/tint/statements/for/continuing/basic.wgsl.expected.msl
@@ -1,9 +1,14 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   int i = 0;
   for(; false; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.ir.msl
index 71e91ee..ae63ee6 100644
--- a/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.msl b/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.msl
index fd9b90b..b6436c8 100644
--- a/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/continuing/struct_ctor.wgsl.expected.msl
@@ -1,12 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   int i;
 };
 
 void f() {
   for(int i = 0; false; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/empty.wgsl.expected.ir.msl b/test/tint/statements/for/empty.wgsl.expected.ir.msl
index 47641f0..7b3f2ce 100644
--- a/test/tint/statements/for/empty.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/empty.wgsl.expected.ir.msl
@@ -1,9 +1,13 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/empty.wgsl.expected.msl b/test/tint/statements/for/empty.wgsl.expected.msl
index a8d3f51..fb1eb0f 100644
--- a/test/tint/statements/for/empty.wgsl.expected.msl
+++ b/test/tint/statements/for/empty.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   for(; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/initializer/array_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/initializer/array_ctor.wgsl.expected.ir.msl
index db40de0..a1a7b9a 100644
--- a/test/tint/statements/for/initializer/array_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/initializer/array_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int i = 1;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/initializer/array_ctor.wgsl.expected.msl b/test/tint/statements/for/initializer/array_ctor.wgsl.expected.msl
index ee30daf..722361f 100644
--- a/test/tint/statements/for/initializer/array_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/initializer/array_ctor.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   for(int i = 1; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/initializer/basic.wgsl.expected.ir.msl b/test/tint/statements/for/initializer/basic.wgsl.expected.ir.msl
index 61e7a43..c3e6673 100644
--- a/test/tint/statements/for/initializer/basic.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/initializer/basic.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int i = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/initializer/basic.wgsl.expected.msl b/test/tint/statements/for/initializer/basic.wgsl.expected.msl
index caf48e3..25e4731 100644
--- a/test/tint/statements/for/initializer/basic.wgsl.expected.msl
+++ b/test/tint/statements/for/initializer/basic.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   for(int i = 0; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.ir.msl b/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.ir.msl
index db40de0..a1a7b9a 100644
--- a/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int i = 1;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (false) {
       } else {
         break;
diff --git a/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.msl b/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.msl
index a497720..a3917b9 100644
--- a/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.msl
+++ b/test/tint/statements/for/initializer/struct_ctor.wgsl.expected.msl
@@ -1,12 +1,17 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct S {
   int i;
 };
 
 void f() {
   for(int i = 1; false; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/for/scoping.wgsl.expected.ir.msl b/test/tint/statements/for/scoping.wgsl.expected.ir.msl
index 2947505..5b08034 100644
--- a/test/tint/statements/for/scoping.wgsl.expected.ir.msl
+++ b/test/tint/statements/for/scoping.wgsl.expected.ir.msl
@@ -1,10 +1,14 @@
 #include <metal_stdlib>
 using namespace metal;
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   {
     int must_not_collide = 0;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       break;
     }
   }
diff --git a/test/tint/statements/for/scoping.wgsl.expected.msl b/test/tint/statements/for/scoping.wgsl.expected.msl
index c6d9118..d4637af 100644
--- a/test/tint/statements/for/scoping.wgsl.expected.msl
+++ b/test/tint/statements/for/scoping.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void f() {
   for(int must_not_collide = 0; ; ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     break;
   }
   int must_not_collide = 0;
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.dxc.hlsl b/test/tint/statements/increment/array_element.wgsl.expected.dxc.hlsl
index bb1b8e1..67d5c6b 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.dxc.hlsl
@@ -6,5 +6,8 @@
 RWByteAddressBuffer a : register(u0);
 
 void main() {
-  a.Store(4u, asuint((a.Load(4u) + 1u)));
+  uint tint_symbol_2 = 0u;
+  a.GetDimensions(tint_symbol_2);
+  uint tint_symbol_3 = (tint_symbol_2 / 4u);
+  a.Store((4u * min(1u, (tint_symbol_3 - 1u))), asuint((a.Load((4u * min(1u, (tint_symbol_3 - 1u)))) + 1u)));
 }
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.fxc.hlsl b/test/tint/statements/increment/array_element.wgsl.expected.fxc.hlsl
index bb1b8e1..67d5c6b 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.fxc.hlsl
@@ -6,5 +6,8 @@
 RWByteAddressBuffer a : register(u0);
 
 void main() {
-  a.Store(4u, asuint((a.Load(4u) + 1u)));
+  uint tint_symbol_2 = 0u;
+  a.GetDimensions(tint_symbol_2);
+  uint tint_symbol_3 = (tint_symbol_2 / 4u);
+  a.Store((4u * min(1u, (tint_symbol_3 - 1u))), asuint((a.Load((4u * min(1u, (tint_symbol_3 - 1u)))) + 1u)));
 }
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.glsl b/test/tint/statements/increment/array_element.wgsl.expected.glsl
index d671224..0f81be8 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.glsl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.glsl
@@ -5,7 +5,9 @@
   uint inner[];
 } v;
 void tint_symbol() {
-  v.inner[1] = (v.inner[1] + 1u);
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(1), v_1);
+  v.inner[v_2] = (v.inner[v_2] + 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/increment/array_element.wgsl.expected.ir.dxc.hlsl
index 63cf2b0..0836c18 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,11 @@
 
 RWByteAddressBuffer a : register(u0);
 void main() {
-  a.Store(4u, (a.Load(4u) + 1u));
+  uint v = 0u;
+  a.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(1)), v_1) * 4u);
+  a.Store((0u + v_2), (a.Load((0u + v_2)) + 1u));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/increment/array_element.wgsl.expected.ir.fxc.hlsl
index 63cf2b0..0836c18 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.ir.fxc.hlsl
@@ -1,7 +1,11 @@
 
 RWByteAddressBuffer a : register(u0);
 void main() {
-  a.Store(4u, (a.Load(4u) + 1u));
+  uint v = 0u;
+  a.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(1)), v_1) * 4u);
+  a.Store((0u + v_2), (a.Load((0u + v_2)) + 1u));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.ir.msl b/test/tint/statements/increment/array_element.wgsl.expected.ir.msl
index 102c72f..098ddfa 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.ir.msl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.ir.msl
@@ -15,8 +15,11 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* a;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.a)[1] = ((*tint_module_vars.a)[1] + 1u);
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  device uint* const v_1 = (&(*tint_module_vars.a)[min(uint(1), v)]);
+  (*v_1) = ((*v_1) + 1u);
 }
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.msl b/test/tint/statements/increment/array_element.wgsl.expected.msl
index 4d41bf9..cdfdb5d 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.msl
+++ b/test/tint/statements/increment/array_element.wgsl.expected.msl
@@ -14,7 +14,12 @@
     T elements[N];
 };
 
-void tint_symbol(device tint_array<uint, 1>* const tint_symbol_2) {
-  (*(tint_symbol_2))[1] = ((*(tint_symbol_2))[1] + 1u);
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+void tint_symbol(const constant TintArrayLengths* const tint_symbol_2, device tint_array<uint, 1>* const tint_symbol_3) {
+  uint const tint_symbol_1_save = min(1u, (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u));
+  (*(tint_symbol_3))[tint_symbol_1_save] = ((*(tint_symbol_3))[tint_symbol_1_save] + 1u);
 }
 
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.spvasm b/test/tint/statements/increment/array_element.wgsl.expected.spvasm
index 27c2e5e..6fcef60 100644
--- a/test/tint/statements/increment/array_element.wgsl.expected.spvasm
+++ b/test/tint/statements/increment/array_element.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 20
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %20 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -24,20 +25,26 @@
           %1 = OpVariable %_ptr_StorageBuffer_a_block StorageBuffer
        %void = OpTypeVoid
           %8 = OpTypeFunction %void
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_1 = OpConstant %int 1
-     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
        %main = OpFunction %void None %8
           %9 = OpLabel
-         %10 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %int_1
-         %15 = OpLoad %uint %10 None
-         %16 = OpIAdd %uint %15 %uint_1
-               OpStore %10 %16 None
+         %10 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %13 = OpArrayLength %uint %1 0
+         %14 = OpISub %uint %13 %uint_1
+         %16 = OpBitcast %uint %int_1
+         %19 = OpExtInst %uint %20 UMin %16 %14
+         %21 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %19
+         %23 = OpLoad %uint %21 None
+         %24 = OpIAdd %uint %23 %uint_1
+               OpStore %21 %24 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %8
-         %19 = OpLabel
+         %26 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl
index 32aba90..649cf69 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/increment/complex.wgsl.expected.dxc.hlsl
@@ -38,10 +38,13 @@
 
 void main() {
   {
+    uint tint_symbol_5 = 0u;
+    buffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = (tint_symbol_5 / 64u);
     int tint_symbol_save = idx1();
     int tint_symbol_save_1 = idx2();
     int tint_symbol_1 = idx3();
-    buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) + 1)));
+    buffer.Store((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))))) + 1)));
     while (true) {
       if (!((v < 10u))) {
         break;
@@ -49,10 +52,13 @@
       {
       }
       {
+        uint tint_symbol_7 = 0u;
+        buffer.GetDimensions(tint_symbol_7);
+        uint tint_symbol_8 = (tint_symbol_7 / 64u);
         int tint_symbol_2_save = idx4();
         int tint_symbol_2_save_1 = idx5();
         int tint_symbol_3 = idx6();
-        buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) + 1)));
+        buffer.Store((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))))) + 1)));
       }
     }
   }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl
index 32aba90..649cf69 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/increment/complex.wgsl.expected.fxc.hlsl
@@ -38,10 +38,13 @@
 
 void main() {
   {
+    uint tint_symbol_5 = 0u;
+    buffer.GetDimensions(tint_symbol_5);
+    uint tint_symbol_6 = (tint_symbol_5 / 64u);
     int tint_symbol_save = idx1();
     int tint_symbol_save_1 = idx2();
     int tint_symbol_1 = idx3();
-    buffer.Store((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_save)) + (16u * uint(tint_symbol_save_1))) + (4u * uint(tint_symbol_1))))) + 1)));
+    buffer.Store((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_save), (tint_symbol_6 - 1u))) + (16u * min(uint(tint_symbol_save_1), 3u))) + (4u * min(uint(tint_symbol_1), 3u))))) + 1)));
     while (true) {
       if (!((v < 10u))) {
         break;
@@ -49,10 +52,13 @@
       {
       }
       {
+        uint tint_symbol_7 = 0u;
+        buffer.GetDimensions(tint_symbol_7);
+        uint tint_symbol_8 = (tint_symbol_7 / 64u);
         int tint_symbol_2_save = idx4();
         int tint_symbol_2_save_1 = idx5();
         int tint_symbol_3 = idx6();
-        buffer.Store((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))), asuint((asint(buffer.Load((((64u * uint(tint_symbol_2_save)) + (16u * uint(tint_symbol_2_save_1))) + (4u * uint(tint_symbol_3))))) + 1)));
+        buffer.Store((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))), asuint((asint(buffer.Load((((64u * min(uint(tint_symbol_2_save), (tint_symbol_8 - 1u))) + (16u * min(uint(tint_symbol_2_save_1), 3u))) + (4u * min(uint(tint_symbol_3), 3u))))) + 1)));
       }
     }
   }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.glsl b/test/tint/statements/increment/complex.wgsl.expected.glsl
index 4477509..78ce2f6 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.glsl
+++ b/test/tint/statements/increment/complex.wgsl.expected.glsl
@@ -38,18 +38,26 @@
   {
     int v_2 = idx1();
     int v_3 = idx2();
-    int v_4 = idx3();
-    v_1.inner[v_2].a[v_3][v_4] = (v_1.inner[v_2].a[v_3][v_4] + 1);
+    uint v_4 = (uint(v_1.inner.length()) - 1u);
+    uint v_5 = min(uint(v_2), v_4);
+    uint v_6 = min(uint(v_3), 3u);
+    int v_7 = idx3();
+    int v_8 = (v_1.inner[v_5].a[v_6][min(uint(v_7), 3u)] + 1);
+    v_1.inner[v_5].a[v_6][min(uint(v_7), 3u)] = v_8;
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_5 = idx4();
-        int v_6 = idx5();
-        int v_7 = idx6();
-        v_1.inner[v_5].a[v_6][v_7] = (v_1.inner[v_5].a[v_6][v_7] + 1);
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = (uint(v_1.inner.length()) - 1u);
+        uint v_12 = min(uint(v_9), v_11);
+        uint v_13 = min(uint(v_10), 3u);
+        int v_14 = idx6();
+        int v_15 = (v_1.inner[v_12].a[v_13][min(uint(v_14), 3u)] + 1);
+        v_1.inner[v_12].a[v_13][min(uint(v_14), 3u)] = v_15;
       }
       continue;
     }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.ir.dxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.ir.dxc.hlsl
index 70a76e9..50d2db9 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/statements/increment/complex.wgsl.expected.ir.dxc.hlsl
@@ -35,24 +35,30 @@
   {
     int v_1 = idx1();
     int v_2 = idx2();
-    uint v_3 = (uint(v_1) * 64u);
-    uint v_4 = (uint(v_2) * 16u);
-    int v_5 = idx3();
-    int v_6 = (asint(buffer.Load((((0u + v_3) + v_4) + (uint(v_5) * 4u)))) + int(1));
-    buffer.Store((((0u + v_3) + v_4) + (uint(v_5) * 4u)), asuint(v_6));
+    uint v_3 = 0u;
+    buffer.GetDimensions(v_3);
+    uint v_4 = ((v_3 / 64u) - 1u);
+    uint v_5 = min(uint(v_1), v_4);
+    uint v_6 = (min(uint(v_2), 3u) * 16u);
+    int v_7 = idx3();
+    int v_8 = (asint(buffer.Load((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)))) + int(1));
+    buffer.Store((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)), asuint(v_8));
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_7 = idx4();
-        int v_8 = idx5();
-        uint v_9 = (uint(v_7) * 64u);
-        uint v_10 = (uint(v_8) * 16u);
-        int v_11 = idx6();
-        int v_12 = (asint(buffer.Load((((0u + v_9) + v_10) + (uint(v_11) * 4u)))) + int(1));
-        buffer.Store((((0u + v_9) + v_10) + (uint(v_11) * 4u)), asuint(v_12));
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = 0u;
+        buffer.GetDimensions(v_11);
+        uint v_12 = ((v_11 / 64u) - 1u);
+        uint v_13 = min(uint(v_9), v_12);
+        uint v_14 = (min(uint(v_10), 3u) * 16u);
+        int v_15 = idx6();
+        int v_16 = (asint(buffer.Load((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)))) + int(1));
+        buffer.Store((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)), asuint(v_16));
       }
       continue;
     }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.ir.fxc.hlsl b/test/tint/statements/increment/complex.wgsl.expected.ir.fxc.hlsl
index 70a76e9..50d2db9 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/statements/increment/complex.wgsl.expected.ir.fxc.hlsl
@@ -35,24 +35,30 @@
   {
     int v_1 = idx1();
     int v_2 = idx2();
-    uint v_3 = (uint(v_1) * 64u);
-    uint v_4 = (uint(v_2) * 16u);
-    int v_5 = idx3();
-    int v_6 = (asint(buffer.Load((((0u + v_3) + v_4) + (uint(v_5) * 4u)))) + int(1));
-    buffer.Store((((0u + v_3) + v_4) + (uint(v_5) * 4u)), asuint(v_6));
+    uint v_3 = 0u;
+    buffer.GetDimensions(v_3);
+    uint v_4 = ((v_3 / 64u) - 1u);
+    uint v_5 = min(uint(v_1), v_4);
+    uint v_6 = (min(uint(v_2), 3u) * 16u);
+    int v_7 = idx3();
+    int v_8 = (asint(buffer.Load((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)))) + int(1));
+    buffer.Store((((0u + (v_5 * 64u)) + v_6) + (min(uint(v_7), 3u) * 4u)), asuint(v_8));
     while(true) {
       if ((v < 10u)) {
       } else {
         break;
       }
       {
-        int v_7 = idx4();
-        int v_8 = idx5();
-        uint v_9 = (uint(v_7) * 64u);
-        uint v_10 = (uint(v_8) * 16u);
-        int v_11 = idx6();
-        int v_12 = (asint(buffer.Load((((0u + v_9) + v_10) + (uint(v_11) * 4u)))) + int(1));
-        buffer.Store((((0u + v_9) + v_10) + (uint(v_11) * 4u)), asuint(v_12));
+        int v_9 = idx4();
+        int v_10 = idx5();
+        uint v_11 = 0u;
+        buffer.GetDimensions(v_11);
+        uint v_12 = ((v_11 / 64u) - 1u);
+        uint v_13 = min(uint(v_9), v_12);
+        uint v_14 = (min(uint(v_10), 3u) * 16u);
+        int v_15 = idx6();
+        int v_16 = (asint(buffer.Load((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)))) + int(1));
+        buffer.Store((((0u + (v_13 * 64u)) + v_14) + (min(uint(v_15), 3u) * 4u)), asuint(v_16));
       }
       continue;
     }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.ir.msl b/test/tint/statements/increment/complex.wgsl.expected.ir.msl
index 3d66e6d..a525efd 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.ir.msl
+++ b/test/tint/statements/increment/complex.wgsl.expected.ir.msl
@@ -20,8 +20,12 @@
 struct tint_module_vars_struct {
   device tint_array<S, 1>* tint_symbol;
   thread uint* v;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 int idx1(tint_module_vars_struct tint_module_vars) {
   (*tint_module_vars.v) = ((*tint_module_vars.v) + 1u);
   return 1;
@@ -55,19 +59,28 @@
 void tint_symbol_1(tint_module_vars_struct tint_module_vars) {
   {
     int const v_1 = idx1(tint_module_vars);
-    device int4* const v_2 = (&(*tint_module_vars.tint_symbol)[v_1].a[idx2(tint_module_vars)]);
-    int const v_3 = idx3(tint_module_vars);
-    (*v_2)[v_3] = as_type<int>((as_type<uint>((*v_2)[v_3]) + as_type<uint>(1)));
+    int const v_2 = idx2(tint_module_vars);
+    uint const v_3 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 64u) - 1u);
+    uint const v_4 = min(uint(v_1), v_3);
+    device int4* const v_5 = (&(*tint_module_vars.tint_symbol)[v_4].a[min(uint(v_2), 3u)]);
+    int const v_6 = idx3(tint_module_vars);
+    int const v_7 = as_type<int>((as_type<uint>((*v_5)[min(uint(v_6), 3u)]) + as_type<uint>(1)));
+    (*v_5)[min(uint(v_6), 3u)] = v_7;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.v) < 10u)) {
       } else {
         break;
       }
       {
-        int const v_4 = idx4(tint_module_vars);
-        device int4* const v_5 = (&(*tint_module_vars.tint_symbol)[v_4].a[idx5(tint_module_vars)]);
-        int const v_6 = idx6(tint_module_vars);
-        (*v_5)[v_6] = as_type<int>((as_type<uint>((*v_5)[v_6]) + as_type<uint>(1)));
+        int const v_8 = idx4(tint_module_vars);
+        int const v_9 = idx5(tint_module_vars);
+        uint const v_10 = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 64u) - 1u);
+        uint const v_11 = min(uint(v_8), v_10);
+        device int4* const v_12 = (&(*tint_module_vars.tint_symbol)[v_11].a[min(uint(v_9), 3u)]);
+        int const v_13 = idx6(tint_module_vars);
+        int const v_14 = as_type<int>((as_type<uint>((*v_12)[min(uint(v_13), 3u)]) + as_type<uint>(1)));
+        (*v_12)[min(uint(v_13), 3u)] = v_14;
       }
       continue;
     }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.msl b/test/tint/statements/increment/complex.wgsl.expected.msl
index 66c01ef..7e08d63 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.msl
+++ b/test/tint/statements/increment/complex.wgsl.expected.msl
@@ -14,10 +14,17 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_private_vars_struct {
   uint v;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct S {
   /* 0x0000 */ tint_array<int4, 4> a;
 };
@@ -52,15 +59,16 @@
   return 2;
 }
 
-void tint_symbol_1(thread tint_private_vars_struct* const tint_private_vars, device tint_array<S, 1>* const tint_symbol_10) {
+void tint_symbol_1(thread tint_private_vars_struct* const tint_private_vars, const constant TintArrayLengths* const tint_symbol_10, device tint_array<S, 1>* const tint_symbol_11) {
   {
     int const tint_symbol_6 = idx1(tint_private_vars);
     int const tint_symbol_7 = idx2(tint_private_vars);
-    int const tint_symbol_2_save = tint_symbol_6;
-    int const tint_symbol_2_save_1 = tint_symbol_7;
+    uint const tint_symbol_2_save = min(uint(tint_symbol_6), (((*(tint_symbol_10)).array_lengths[0u][0u] / 64u) - 1u));
+    uint const tint_symbol_2_save_1 = min(uint(tint_symbol_7), 3u);
     int const tint_symbol_3 = idx3(tint_private_vars);
-    (*(tint_symbol_10))[tint_symbol_2_save].a[tint_symbol_2_save_1][tint_symbol_3] = as_type<int>((as_type<uint>((*(tint_symbol_10))[tint_symbol_2_save].a[tint_symbol_2_save_1][tint_symbol_3]) + as_type<uint>(1)));
+    (*(tint_symbol_11))[tint_symbol_2_save].a[tint_symbol_2_save_1][min(uint(tint_symbol_3), 3u)] = as_type<int>((as_type<uint>((*(tint_symbol_11))[tint_symbol_2_save].a[tint_symbol_2_save_1][min(uint(tint_symbol_3), 3u)]) + as_type<uint>(1)));
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false);
       if (!(((*(tint_private_vars)).v < 10u))) {
         break;
       }
@@ -69,10 +77,10 @@
       {
         int const tint_symbol_8 = idx4(tint_private_vars);
         int const tint_symbol_9 = idx5(tint_private_vars);
-        int const tint_symbol_4_save = tint_symbol_8;
-        int const tint_symbol_4_save_1 = tint_symbol_9;
+        uint const tint_symbol_4_save = min(uint(tint_symbol_8), (((*(tint_symbol_10)).array_lengths[0u][0u] / 64u) - 1u));
+        uint const tint_symbol_4_save_1 = min(uint(tint_symbol_9), 3u);
         int const tint_symbol_5 = idx6(tint_private_vars);
-        (*(tint_symbol_10))[tint_symbol_4_save].a[tint_symbol_4_save_1][tint_symbol_5] = as_type<int>((as_type<uint>((*(tint_symbol_10))[tint_symbol_4_save].a[tint_symbol_4_save_1][tint_symbol_5]) + as_type<uint>(1)));
+        (*(tint_symbol_11))[tint_symbol_4_save].a[tint_symbol_4_save_1][min(uint(tint_symbol_5), 3u)] = as_type<int>((as_type<uint>((*(tint_symbol_11))[tint_symbol_4_save].a[tint_symbol_4_save_1][min(uint(tint_symbol_5), 3u)]) + as_type<uint>(1)));
       }
     }
   }
diff --git a/test/tint/statements/increment/complex.wgsl.expected.spvasm b/test/tint/statements/increment/complex.wgsl.expected.spvasm
index 4289c2c..ed32919 100644
--- a/test/tint/statements/increment/complex.wgsl.expected.spvasm
+++ b/test/tint/statements/increment/complex.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 81
+; Bound: 106
 ; Schema: 0
                OpCapability Shader
+         %63 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
                OpExecutionMode %unused_entry_point LocalSize 1 1 1
@@ -50,8 +51,10 @@
       %int_0 = OpConstant %int 0
        %void = OpTypeVoid
          %47 = OpTypeFunction %void
-%_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
+%_ptr_StorageBuffer__runtimearr_S = OpTypePointer StorageBuffer %_runtimearr_S
      %uint_0 = OpConstant %uint 0
+     %uint_3 = OpConstant %uint 3
+%_ptr_StorageBuffer_v4int = OpTypePointer StorageBuffer %v4int
 %_ptr_StorageBuffer_int = OpTypePointer StorageBuffer %int
     %uint_10 = OpConstant %uint 10
        %bool = OpTypeBool
@@ -103,41 +106,63 @@
          %49 = OpLabel
          %54 = OpFunctionCall %int %idx1
          %55 = OpFunctionCall %int %idx2
-         %56 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %54 %uint_0 %55
-         %59 = OpFunctionCall %int %idx3
-         %60 = OpAccessChain %_ptr_StorageBuffer_int %56 %59
-         %62 = OpLoad %int %60 None
-         %63 = OpIAdd %int %62 %int_1
-         %64 = OpAccessChain %_ptr_StorageBuffer_int %56 %59
-               OpStore %64 %63 None
+         %56 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %1 %uint_0
+         %59 = OpArrayLength %uint %1 0
+         %60 = OpISub %uint %59 %uint_1
+         %61 = OpBitcast %uint %54
+         %62 = OpExtInst %uint %63 UMin %61 %60
+         %64 = OpBitcast %uint %55
+         %65 = OpExtInst %uint %63 UMin %64 %uint_3
+         %67 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %62 %uint_0 %65
+         %69 = OpFunctionCall %int %idx3
+         %70 = OpBitcast %uint %69
+         %71 = OpExtInst %uint %63 UMin %70 %uint_3
+         %72 = OpAccessChain %_ptr_StorageBuffer_int %67 %71
+         %74 = OpLoad %int %72 None
+         %75 = OpIAdd %int %74 %int_1
+         %76 = OpBitcast %uint %69
+         %77 = OpExtInst %uint %63 UMin %76 %uint_3
+         %78 = OpAccessChain %_ptr_StorageBuffer_int %67 %77
+               OpStore %78 %75 None
                OpBranch %52
          %52 = OpLabel
                OpLoopMerge %53 %51 None
                OpBranch %50
          %50 = OpLabel
-         %65 = OpLoad %uint %v None
-         %66 = OpULessThan %bool %65 %uint_10
-               OpSelectionMerge %69 None
-               OpBranchConditional %66 %69 %70
-         %70 = OpLabel
+         %79 = OpLoad %uint %v None
+         %80 = OpULessThan %bool %79 %uint_10
+               OpSelectionMerge %83 None
+               OpBranchConditional %80 %83 %84
+         %84 = OpLabel
                OpBranch %53
-         %69 = OpLabel
+         %83 = OpLabel
                OpBranch %51
          %51 = OpLabel
-         %71 = OpFunctionCall %int %idx4
-         %72 = OpFunctionCall %int %idx5
-         %73 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %71 %uint_0 %72
-         %74 = OpFunctionCall %int %idx6
-         %75 = OpAccessChain %_ptr_StorageBuffer_int %73 %74
-         %76 = OpLoad %int %75 None
-         %77 = OpIAdd %int %76 %int_1
-         %78 = OpAccessChain %_ptr_StorageBuffer_int %73 %74
-               OpStore %78 %77 None
+         %85 = OpFunctionCall %int %idx4
+         %86 = OpFunctionCall %int %idx5
+         %87 = OpAccessChain %_ptr_StorageBuffer__runtimearr_S %1 %uint_0
+         %88 = OpArrayLength %uint %1 0
+         %89 = OpISub %uint %88 %uint_1
+         %90 = OpBitcast %uint %85
+         %91 = OpExtInst %uint %63 UMin %90 %89
+         %92 = OpBitcast %uint %86
+         %93 = OpExtInst %uint %63 UMin %92 %uint_3
+         %94 = OpAccessChain %_ptr_StorageBuffer_v4int %1 %uint_0 %91 %uint_0 %93
+         %95 = OpFunctionCall %int %idx6
+         %96 = OpBitcast %uint %95
+         %97 = OpExtInst %uint %63 UMin %96 %uint_3
+         %98 = OpAccessChain %_ptr_StorageBuffer_int %94 %97
+         %99 = OpLoad %int %98 None
+        %100 = OpIAdd %int %99 %int_1
+        %101 = OpBitcast %uint %95
+        %102 = OpExtInst %uint %63 UMin %101 %uint_3
+        %103 = OpAccessChain %_ptr_StorageBuffer_int %94 %102
+               OpStore %103 %100 None
                OpBranch %52
          %53 = OpLabel
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %47
-         %80 = OpLabel
+        %105 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.ir.msl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.ir.msl
index 4620c07..1aa5603 100644
--- a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.ir.msl
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.ir.msl
@@ -5,9 +5,13 @@
   device uint* i;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   {
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.i) < 10u)) {
       } else {
         break;
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl
index ee23499..a25d81a 100644
--- a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(device uint* const tint_symbol_1) {
   for(; (*(tint_symbol_1) < 10u); *(tint_symbol_1) = (*(tint_symbol_1) + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.ir.msl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.ir.msl
index afca7bb..550762b 100644
--- a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.ir.msl
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.ir.msl
@@ -5,10 +5,14 @@
   device uint* i;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
   {
     (*tint_module_vars.i) = ((*tint_module_vars.i) + 1u);
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       if (((*tint_module_vars.i) < 10u)) {
       } else {
         break;
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl
index b29a247..91602a6 100644
--- a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl
@@ -1,8 +1,13 @@
 #include <metal_stdlib>
 
 using namespace metal;
+
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_symbol(device uint* const tint_symbol_1) {
   for(*(tint_symbol_1) = (*(tint_symbol_1) + 1u); (*(tint_symbol_1) < 10u); ) {
+    TINT_ISOLATE_UB(tint_volatile_false);
   }
 }
 
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.dxc.hlsl b/test/tint/statements/increment/vector_component.wgsl.expected.dxc.hlsl
index f820fba..4dc8030 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.dxc.hlsl
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.dxc.hlsl
@@ -7,6 +7,6 @@
 
 void main() {
   int tint_symbol_1 = 1;
-  a.Store((4u * uint(tint_symbol_1)), asuint((a.Load((4u * uint(tint_symbol_1))) + 1u)));
+  a.Store((4u * min(uint(tint_symbol_1), 3u)), asuint((a.Load((4u * min(uint(tint_symbol_1), 3u))) + 1u)));
   a.Store(8u, asuint((a.Load(8u) + 1u)));
 }
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.fxc.hlsl b/test/tint/statements/increment/vector_component.wgsl.expected.fxc.hlsl
index f820fba..4dc8030 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.fxc.hlsl
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.fxc.hlsl
@@ -7,6 +7,6 @@
 
 void main() {
   int tint_symbol_1 = 1;
-  a.Store((4u * uint(tint_symbol_1)), asuint((a.Load((4u * uint(tint_symbol_1))) + 1u)));
+  a.Store((4u * min(uint(tint_symbol_1), 3u)), asuint((a.Load((4u * min(uint(tint_symbol_1), 3u))) + 1u)));
   a.Store(8u, asuint((a.Load(8u) + 1u)));
 }
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.glsl b/test/tint/statements/increment/vector_component.wgsl.expected.glsl
index 32e1156..037cfc9 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.glsl
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.glsl
@@ -5,7 +5,7 @@
   uvec4 inner;
 } v;
 void tint_symbol() {
-  v.inner[1] = (v.inner.y + 1u);
+  v.inner[1u] = (v.inner.y + 1u);
   v.inner[2u] = (v.inner.z + 1u);
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.ir.msl b/test/tint/statements/increment/vector_component.wgsl.expected.ir.msl
index 1a1b677..8065294 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.ir.msl
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.ir.msl
@@ -6,6 +6,6 @@
 };
 
 void tint_symbol(tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.a)[1] = ((*tint_module_vars.a)[1] + 1u);
+  (*tint_module_vars.a)[1u] = ((*tint_module_vars.a)[1u] + 1u);
   (*tint_module_vars.a)[2u] = ((*tint_module_vars.a)[2u] + 1u);
 }
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.msl b/test/tint/statements/increment/vector_component.wgsl.expected.msl
index 8728854..dbf3049 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.msl
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 void tint_symbol(device uint4* const tint_symbol_3) {
   int const tint_symbol_2 = 1;
-  (*(tint_symbol_3))[tint_symbol_2] = ((*(tint_symbol_3))[tint_symbol_2] + 1u);
+  (*(tint_symbol_3))[min(uint(tint_symbol_2), 3u)] = ((*(tint_symbol_3))[min(uint(tint_symbol_2), 3u)] + 1u);
   (*(tint_symbol_3))[2] = ((*(tint_symbol_3))[2] + 1u);
 }
 
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.spvasm b/test/tint/statements/increment/vector_component.wgsl.expected.spvasm
index b751eff..99e188d 100644
--- a/test/tint/statements/increment/vector_component.wgsl.expected.spvasm
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 31
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -26,29 +26,27 @@
 %_ptr_StorageBuffer_v4uint = OpTypePointer StorageBuffer %v4uint
      %uint_0 = OpConstant %uint 0
 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-        %int = OpTypeInt 32 1
-      %int_1 = OpConstant %int 1
      %uint_1 = OpConstant %uint 1
      %uint_2 = OpConstant %uint 2
        %main = OpFunction %void None %8
           %9 = OpLabel
          %10 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %13 = OpAccessChain %_ptr_StorageBuffer_uint %10 %int_1
-         %17 = OpLoad %uint %13 None
-         %18 = OpIAdd %uint %17 %uint_1
+         %13 = OpAccessChain %_ptr_StorageBuffer_uint %10 %uint_1
+         %16 = OpLoad %uint %13 None
+         %17 = OpIAdd %uint %16 %uint_1
+         %18 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+         %19 = OpAccessChain %_ptr_StorageBuffer_uint %18 %uint_1
+               OpStore %19 %17 None
          %20 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %21 = OpAccessChain %_ptr_StorageBuffer_uint %20 %int_1
-               OpStore %21 %18 None
-         %22 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %23 = OpAccessChain %_ptr_StorageBuffer_uint %22 %uint_2
-         %25 = OpLoad %uint %23 None
-         %26 = OpIAdd %uint %25 %uint_1
-         %27 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
-         %28 = OpAccessChain %_ptr_StorageBuffer_uint %27 %uint_2
-               OpStore %28 %26 None
+         %21 = OpAccessChain %_ptr_StorageBuffer_uint %20 %uint_2
+         %23 = OpLoad %uint %21 None
+         %24 = OpIAdd %uint %23 %uint_1
+         %25 = OpAccessChain %_ptr_StorageBuffer_v4uint %1 %uint_0
+         %26 = OpAccessChain %_ptr_StorageBuffer_uint %25 %uint_2
+               OpStore %26 %24 None
                OpReturn
                OpFunctionEnd
 %unused_entry_point = OpFunction %void None %8
-         %30 = OpLabel
+         %28 = OpLabel
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/struct/type_initializer.wgsl.expected.glsl b/test/tint/struct/type_initializer.wgsl.expected.glsl
index a189d1d..8828e88 100644
--- a/test/tint/struct/type_initializer.wgsl.expected.glsl
+++ b/test/tint/struct/type_initializer.wgsl.expected.glsl
@@ -41,5 +41,5 @@
   S1 subexpr_nested_nonempty_with_expr = S2(1, S1(2, x, (x + 1), nested_nonempty.i.f.d)).f;
   T aosoa_empty[2] = T[2](T(int[2](0, 0)), T(int[2](0, 0)));
   T aosoa_nonempty[2] = T[2](T(int[2](1, 2)), T(int[2](3, 4)));
-  T aosoa_nonempty_with_expr[2] = T[2](T(int[2](1, (aosoa_nonempty[0].a[0] + 1))), aosoa_nonempty[1]);
+  T aosoa_nonempty_with_expr[2] = T[2](T(int[2](1, (aosoa_nonempty[0u].a[0u] + 1))), aosoa_nonempty[1u]);
 }
diff --git a/test/tint/struct/type_initializer.wgsl.expected.ir.dxc.hlsl b/test/tint/struct/type_initializer.wgsl.expected.ir.dxc.hlsl
index f88508e..a96f5ad 100644
--- a/test/tint/struct/type_initializer.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/struct/type_initializer.wgsl.expected.ir.dxc.hlsl
@@ -43,9 +43,9 @@
   S1 subexpr_nested_nonempty_with_expr = v_4.f;
   T aosoa_empty[2] = (T[2])0;
   T aosoa_nonempty[2] = {{{int(1), int(2)}}, {{int(3), int(4)}}};
-  int v_5[2] = {int(1), (aosoa_nonempty[int(0)].a[int(0)] + int(1))};
+  int v_5[2] = {int(1), (aosoa_nonempty[0u].a[0u] + int(1))};
   T v_6 = {v_5};
-  T v_7 = aosoa_nonempty[int(1)];
+  T v_7 = aosoa_nonempty[1u];
   T aosoa_nonempty_with_expr[2] = {v_6, v_7};
 }
 
diff --git a/test/tint/struct/type_initializer.wgsl.expected.ir.fxc.hlsl b/test/tint/struct/type_initializer.wgsl.expected.ir.fxc.hlsl
index f88508e..a96f5ad 100644
--- a/test/tint/struct/type_initializer.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/struct/type_initializer.wgsl.expected.ir.fxc.hlsl
@@ -43,9 +43,9 @@
   S1 subexpr_nested_nonempty_with_expr = v_4.f;
   T aosoa_empty[2] = (T[2])0;
   T aosoa_nonempty[2] = {{{int(1), int(2)}}, {{int(3), int(4)}}};
-  int v_5[2] = {int(1), (aosoa_nonempty[int(0)].a[int(0)] + int(1))};
+  int v_5[2] = {int(1), (aosoa_nonempty[0u].a[0u] + int(1))};
   T v_6 = {v_5};
-  T v_7 = aosoa_nonempty[int(1)];
+  T v_7 = aosoa_nonempty[1u];
   T aosoa_nonempty_with_expr[2] = {v_6, v_7};
 }
 
diff --git a/test/tint/struct/type_initializer.wgsl.expected.ir.msl b/test/tint/struct/type_initializer.wgsl.expected.ir.msl
index 5b31bfe..8b5ae82 100644
--- a/test/tint/struct/type_initializer.wgsl.expected.ir.msl
+++ b/test/tint/struct/type_initializer.wgsl.expected.ir.msl
@@ -52,5 +52,5 @@
   S1 const subexpr_nested_nonempty_with_expr = S2{.e=1, .f=S1{.a=2, .b=x, .c=as_type<int>((as_type<uint>(x) + as_type<uint>(1))), .d=nested_nonempty.i.f.d}}.f;
   tint_array<T, 2> const aosoa_empty = tint_array<T, 2>{};
   tint_array<T, 2> const aosoa_nonempty = tint_array<T, 2>{T{.a=tint_array<int, 2>{1, 2}}, T{.a=tint_array<int, 2>{3, 4}}};
-  tint_array<T, 2> const aosoa_nonempty_with_expr = tint_array<T, 2>{T{.a=tint_array<int, 2>{1, as_type<int>((as_type<uint>(aosoa_nonempty[0].a[0]) + as_type<uint>(1)))}}, aosoa_nonempty[1]};
+  tint_array<T, 2> const aosoa_nonempty_with_expr = tint_array<T, 2>{T{.a=tint_array<int, 2>{1, as_type<int>((as_type<uint>(aosoa_nonempty[0u].a[0u]) + as_type<uint>(1)))}}, aosoa_nonempty[1u]};
 }
diff --git a/test/tint/types/buffers/storage.wgsl.expected.dxc.hlsl b/test/tint/types/buffers/storage.wgsl.expected.dxc.hlsl
index fc91938..adf7fcf 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/buffers/storage.wgsl.expected.dxc.hlsl
@@ -1,6 +1,9 @@
 ByteAddressBuffer weights : register(t0);
 
 void main() {
-  float a = asfloat(weights.Load(0u));
+  uint tint_symbol_1 = 0u;
+  weights.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  float a = asfloat(weights.Load((4u * min(0u, (tint_symbol_2 - 1u)))));
   return;
 }
diff --git a/test/tint/types/buffers/storage.wgsl.expected.fxc.hlsl b/test/tint/types/buffers/storage.wgsl.expected.fxc.hlsl
index fc91938..adf7fcf 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.fxc.hlsl
+++ b/test/tint/types/buffers/storage.wgsl.expected.fxc.hlsl
@@ -1,6 +1,9 @@
 ByteAddressBuffer weights : register(t0);
 
 void main() {
-  float a = asfloat(weights.Load(0u));
+  uint tint_symbol_1 = 0u;
+  weights.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  float a = asfloat(weights.Load((4u * min(0u, (tint_symbol_2 - 1u)))));
   return;
 }
diff --git a/test/tint/types/buffers/storage.wgsl.expected.glsl b/test/tint/types/buffers/storage.wgsl.expected.glsl
index 924fdde..d461d97 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.glsl
+++ b/test/tint/types/buffers/storage.wgsl.expected.glsl
@@ -7,5 +7,7 @@
   float inner[];
 } v;
 void main() {
-  float a = v.inner[0];
+  uint v_1 = (uint(v.inner.length()) - 1u);
+  uint v_2 = min(uint(0), v_1);
+  float a = v.inner[v_2];
 }
diff --git a/test/tint/types/buffers/storage.wgsl.expected.ir.dxc.hlsl b/test/tint/types/buffers/storage.wgsl.expected.ir.dxc.hlsl
index d2144fa..b8c4b7d 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/buffers/storage.wgsl.expected.ir.dxc.hlsl
@@ -1,6 +1,9 @@
 
 ByteAddressBuffer weights : register(t0);
 void main() {
-  float a = asfloat(weights.Load(0u));
+  uint v = 0u;
+  weights.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  float a = asfloat(weights.Load((0u + (min(uint(int(0)), v_1) * 4u))));
 }
 
diff --git a/test/tint/types/buffers/storage.wgsl.expected.ir.fxc.hlsl b/test/tint/types/buffers/storage.wgsl.expected.ir.fxc.hlsl
index d2144fa..b8c4b7d 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/buffers/storage.wgsl.expected.ir.fxc.hlsl
@@ -1,6 +1,9 @@
 
 ByteAddressBuffer weights : register(t0);
 void main() {
-  float a = asfloat(weights.Load(0u));
+  uint v = 0u;
+  weights.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  float a = asfloat(weights.Load((0u + (min(uint(int(0)), v_1) * 4u))));
 }
 
diff --git a/test/tint/types/buffers/storage.wgsl.expected.ir.msl b/test/tint/types/buffers/storage.wgsl.expected.ir.msl
index 9aa6166..51f6589 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.ir.msl
+++ b/test/tint/types/buffers/storage.wgsl.expected.ir.msl
@@ -15,9 +15,11 @@
 
 struct tint_module_vars_struct {
   const device tint_array<float, 1>* weights;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
-fragment void tint_symbol(const device tint_array<float, 1>* weights [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.weights=weights};
-  float a = (*tint_module_vars.weights)[0];
+fragment void tint_symbol(const device tint_array<float, 1>* weights [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.weights=weights, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  float a = (*tint_module_vars.weights)[min(uint(0), v)];
 }
diff --git a/test/tint/types/buffers/storage.wgsl.expected.msl b/test/tint/types/buffers/storage.wgsl.expected.msl
index fa82898..858994d 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.msl
+++ b/test/tint/types/buffers/storage.wgsl.expected.msl
@@ -18,8 +18,12 @@
   /* 0x0000 */ tint_array<float, 1> arr;
 };
 
-fragment void tint_symbol(const device tint_symbol_2* tint_symbol_1 [[buffer(0)]]) {
-  float a = (*(tint_symbol_1)).arr[0];
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+fragment void tint_symbol(const device tint_symbol_2* tint_symbol_1 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_3 [[buffer(30)]]) {
+  float a = (*(tint_symbol_1)).arr[min(0u, (((*(tint_symbol_3)).array_lengths[0u][0u] / 4u) - 1u))];
   return;
 }
 
diff --git a/test/tint/types/buffers/storage.wgsl.expected.spvasm b/test/tint/types/buffers/storage.wgsl.expected.spvasm
index 9b064b1..728d588 100644
--- a/test/tint/types/buffers/storage.wgsl.expected.spvasm
+++ b/test/tint/types/buffers/storage.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 19
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
+         %21 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main"
                OpExecutionMode %main OriginUpperLeft
@@ -24,17 +25,24 @@
           %1 = OpVariable %_ptr_StorageBuffer_weights_block StorageBuffer
        %void = OpTypeVoid
           %8 = OpTypeFunction %void
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_Function_float = OpTypePointer Function %float
        %main = OpFunction %void None %8
           %9 = OpLabel
           %a = OpVariable %_ptr_Function_float Function
-         %10 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %int_0
-         %16 = OpLoad %float %10 None
-               OpStore %a %16
+         %10 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %1 %uint_0
+         %14 = OpArrayLength %uint %1 0
+         %15 = OpISub %uint %14 %uint_1
+         %17 = OpBitcast %uint %int_0
+         %20 = OpExtInst %uint %21 UMin %17 %15
+         %22 = OpAccessChain %_ptr_StorageBuffer_float %1 %uint_0 %20
+         %24 = OpLoad %float %22 None
+               OpStore %a %24
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/buffers/uniform.wgsl.expected.ir.msl b/test/tint/types/buffers/uniform.wgsl.expected.ir.msl
index 41d0df7..f97e1f8 100644
--- a/test/tint/types/buffers/uniform.wgsl.expected.ir.msl
+++ b/test/tint/types/buffers/uniform.wgsl.expected.ir.msl
@@ -7,5 +7,5 @@
 
 fragment void tint_symbol(const constant float2* weights [[buffer(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.weights=weights};
-  float a = (*tint_module_vars.weights)[0];
+  float a = (*tint_module_vars.weights)[0u];
 }
diff --git a/test/tint/types/buffers/uniform.wgsl.expected.spvasm b/test/tint/types/buffers/uniform.wgsl.expected.spvasm
index 756a61d..d2f1ad4 100644
--- a/test/tint/types/buffers/uniform.wgsl.expected.spvasm
+++ b/test/tint/types/buffers/uniform.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 21
+; Bound: 19
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -27,15 +27,13 @@
        %uint = OpTypeInt 32 0
      %uint_0 = OpConstant %uint 0
 %_ptr_Uniform_float = OpTypePointer Uniform %float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
 %_ptr_Function_float = OpTypePointer Function %float
        %main = OpFunction %void None %8
           %9 = OpLabel
           %a = OpVariable %_ptr_Function_float Function
          %10 = OpAccessChain %_ptr_Uniform_v2float %1 %uint_0
-         %14 = OpAccessChain %_ptr_Uniform_float %10 %int_0
-         %18 = OpLoad %float %14 None
-               OpStore %a %18
+         %14 = OpAccessChain %_ptr_Uniform_float %10 %uint_0
+         %16 = OpLoad %float %14 None
+               OpStore %a %16
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl
index 9cf0831..e61786f 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl
@@ -1,7 +1,10 @@
 RWByteAddressBuffer output : register(u0);
 
 void main_inner(uint subgroup_invocation_id, uint subgroup_size) {
-  output.Store((4u * subgroup_invocation_id), asuint(subgroup_size));
+  uint tint_symbol_1 = 0u;
+  output.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  output.Store((4u * min(subgroup_invocation_id, (tint_symbol_2 - 1u))), asuint(subgroup_size));
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.dxc.hlsl b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
index c6004cc..b38a8ce 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,9 @@
 
 RWByteAddressBuffer output : register(u0);
 void main_inner(uint subgroup_invocation_id, uint subgroup_size) {
-  output.Store((0u + (subgroup_invocation_id * 4u)), subgroup_size);
+  uint v = 0u;
+  output.GetDimensions(v);
+  output.Store((0u + (min(subgroup_invocation_id, ((v / 4u) - 1u)) * 4u)), subgroup_size);
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.msl
index 56d8bae..48018c6 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.ir.msl
@@ -15,13 +15,14 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* output;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.output)[subgroup_invocation_id] = subgroup_size;
+  (*tint_module_vars.output)[min(subgroup_invocation_id, (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u))] = subgroup_size;
 }
 
-kernel void tint_symbol(uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
+kernel void tint_symbol(uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(subgroup_invocation_id, subgroup_size, tint_module_vars);
 }
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.msl b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.msl
index c79a68a..b8d93f7 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.msl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.msl
@@ -14,16 +14,20 @@
     T elements[N];
 };
 
-struct tint_symbol_3 {
+struct tint_symbol_4 {
   /* 0x0000 */ tint_array<uint, 1> arr;
 };
 
-void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, device tint_array<uint, 1>* const tint_symbol_1) {
-  (*(tint_symbol_1))[subgroup_invocation_id] = subgroup_size;
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, device tint_array<uint, 1>* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  (*(tint_symbol_1))[min(subgroup_invocation_id, (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u))] = subgroup_size;
 }
 
-kernel void tint_symbol(device tint_symbol_3* tint_symbol_2 [[buffer(0)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
-  tint_symbol_inner(subgroup_invocation_id, subgroup_size, &((*(tint_symbol_2)).arr));
+kernel void tint_symbol(device tint_symbol_4* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
+  tint_symbol_inner(subgroup_invocation_id, subgroup_size, &((*(tint_symbol_3)).arr), tint_symbol_5);
   return;
 }
 
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm
index de661c6..e25860d 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpCapability GroupNonUniform
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_subgroup_invocation_id_Input %main_subgroup_size_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -34,21 +35,27 @@
 %main_subgroup_size_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %13 = OpTypeFunction %void %uint %uint
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
-         %19 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+         %26 = OpTypeFunction %void
  %main_inner = OpFunction %void None %13
 %subgroup_invocation_id = OpFunctionParameter %uint
 %subgroup_size = OpFunctionParameter %uint
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %subgroup_invocation_id
-               OpStore %15 %subgroup_size None
+         %15 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %18 = OpArrayLength %uint %1 0
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpExtInst %uint %22 UMin %subgroup_invocation_id %19
+         %23 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %21
+               OpStore %23 %subgroup_size None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %19
-         %20 = OpLabel
-         %21 = OpLoad %uint %main_subgroup_invocation_id_Input None
-         %22 = OpLoad %uint %main_subgroup_size_Input None
-         %23 = OpFunctionCall %void %main_inner %21 %22
+       %main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpLoad %uint %main_subgroup_invocation_id_Input None
+         %29 = OpLoad %uint %main_subgroup_size_Input None
+         %30 = OpFunctionCall %void %main_inner %28 %29
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
index 9d79e16..07f9a5b 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
@@ -6,12 +6,15 @@
 };
 
 void main_inner(ComputeInputs inputs) {
-  output.Store((4u * inputs.subgroup_invocation_id), asuint(inputs.subgroup_size));
+  uint tint_symbol_1 = 0u;
+  output.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  output.Store((4u * min(inputs.subgroup_invocation_id, (tint_symbol_2 - 1u))), asuint(inputs.subgroup_size));
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  ComputeInputs tint_symbol = {WaveGetLaneIndex(), WaveGetLaneCount()};
-  main_inner(tint_symbol);
+  ComputeInputs tint_symbol_3 = {WaveGetLaneIndex(), WaveGetLaneCount()};
+  main_inner(tint_symbol_3);
   return;
 }
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
index 3ac97da..29faeeb 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
@@ -6,12 +6,14 @@
 
 RWByteAddressBuffer output : register(u0);
 void main_inner(ComputeInputs inputs) {
-  output.Store((0u + (inputs.subgroup_invocation_id * 4u)), inputs.subgroup_size);
+  uint v = 0u;
+  output.GetDimensions(v);
+  output.Store((0u + (min(inputs.subgroup_invocation_id, ((v / 4u) - 1u)) * 4u)), inputs.subgroup_size);
 }
 
 [numthreads(1, 1, 1)]
 void main() {
-  ComputeInputs v = {WaveGetLaneIndex(), WaveGetLaneCount()};
-  main_inner(v);
+  ComputeInputs v_1 = {WaveGetLaneIndex(), WaveGetLaneCount()};
+  main_inner(v_1);
 }
 
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.msl
index 430a7d4..153c52f 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.ir.msl
@@ -20,13 +20,14 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* output;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(ComputeInputs inputs, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.output)[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+  (*tint_module_vars.output)[min(inputs.subgroup_invocation_id, (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u))] = inputs.subgroup_size;
 }
 
-kernel void tint_symbol(uint ComputeInputs_subgroup_invocation_id [[thread_index_in_simdgroup]], uint ComputeInputs_subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
+kernel void tint_symbol(uint ComputeInputs_subgroup_invocation_id [[thread_index_in_simdgroup]], uint ComputeInputs_subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(ComputeInputs{.subgroup_invocation_id=ComputeInputs_subgroup_invocation_id, .subgroup_size=ComputeInputs_subgroup_size}, tint_module_vars);
 }
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl
index fe8631c..c484c4e 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl
@@ -14,22 +14,26 @@
     T elements[N];
 };
 
-struct tint_symbol_4 {
+struct tint_symbol_5 {
   /* 0x0000 */ tint_array<uint, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct ComputeInputs {
   uint subgroup_invocation_id;
   uint subgroup_size;
 };
 
-void tint_symbol_inner(ComputeInputs inputs, device tint_array<uint, 1>* const tint_symbol_2) {
-  (*(tint_symbol_2))[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+void tint_symbol_inner(ComputeInputs inputs, device tint_array<uint, 1>* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
+  (*(tint_symbol_2))[min(inputs.subgroup_invocation_id, (((*(tint_symbol_3)).array_lengths[0u][0u] / 4u) - 1u))] = inputs.subgroup_size;
 }
 
-kernel void tint_symbol(device tint_symbol_4* tint_symbol_3 [[buffer(0)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
+kernel void tint_symbol(device tint_symbol_5* tint_symbol_4 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_6 [[buffer(30)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
   ComputeInputs const tint_symbol_1 = ComputeInputs{.subgroup_invocation_id=subgroup_invocation_id, .subgroup_size=subgroup_size};
-  tint_symbol_inner(tint_symbol_1, &((*(tint_symbol_3)).arr));
+  tint_symbol_inner(tint_symbol_1, &((*(tint_symbol_4)).arr), tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm
index 35f42b2..d7ccfbd 100644
--- a/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability GroupNonUniform
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_subgroup_invocation_id_Input %main_subgroup_size_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -39,23 +40,29 @@
        %void = OpTypeVoid
 %ComputeInputs = OpTypeStruct %uint %uint
          %13 = OpTypeFunction %void %ComputeInputs
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
-         %21 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+         %28 = OpTypeFunction %void
  %main_inner = OpFunction %void None %13
      %inputs = OpFunctionParameter %ComputeInputs
          %14 = OpLabel
          %15 = OpCompositeExtract %uint %inputs 0
-         %16 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %15
-         %19 = OpCompositeExtract %uint %inputs 1
-               OpStore %16 %19 None
+         %16 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %19 = OpArrayLength %uint %1 0
+         %20 = OpISub %uint %19 %uint_1
+         %22 = OpExtInst %uint %23 UMin %15 %20
+         %24 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %22
+         %26 = OpCompositeExtract %uint %inputs 1
+               OpStore %24 %26 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpLoad %uint %main_subgroup_invocation_id_Input None
-         %24 = OpLoad %uint %main_subgroup_size_Input None
-         %25 = OpCompositeConstruct %ComputeInputs %23 %24
-         %26 = OpFunctionCall %void %main_inner %25
+       %main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpLoad %uint %main_subgroup_invocation_id_Input None
+         %31 = OpLoad %uint %main_subgroup_size_Input None
+         %32 = OpCompositeConstruct %ComputeInputs %30 %31
+         %33 = OpFunctionCall %void %main_inner %32
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.dxc.hlsl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.dxc.hlsl
index cf9946b..31dc828 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.dxc.hlsl
@@ -1,7 +1,10 @@
 RWByteAddressBuffer output : register(u0);
 
 void main_inner(uint subgroup_invocation_id, uint subgroup_size) {
-  output.Store((4u * subgroup_invocation_id), asuint(subgroup_size));
+  uint tint_symbol_1 = 0u;
+  output.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  output.Store((4u * min(subgroup_invocation_id, (tint_symbol_2 - 1u))), asuint(subgroup_size));
 }
 
 void main() {
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.dxc.hlsl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
index c3a47ea..16b113f 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.dxc.hlsl
@@ -1,7 +1,9 @@
 
 RWByteAddressBuffer output : register(u0);
 void main_inner(uint subgroup_invocation_id, uint subgroup_size) {
-  output.Store((0u + (subgroup_invocation_id * 4u)), subgroup_size);
+  uint v = 0u;
+  output.GetDimensions(v);
+  output.Store((0u + (min(subgroup_invocation_id, ((v / 4u) - 1u)) * 4u)), subgroup_size);
 }
 
 void main() {
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.msl
index 354275f..818bf7d 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.ir.msl
@@ -15,13 +15,14 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* output;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.output)[subgroup_invocation_id] = subgroup_size;
+  (*tint_module_vars.output)[min(subgroup_invocation_id, (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u))] = subgroup_size;
 }
 
-fragment void tint_symbol(uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
+fragment void tint_symbol(uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(subgroup_invocation_id, subgroup_size, tint_module_vars);
 }
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.msl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.msl
index e4773aa..039f64c 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.msl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.msl
@@ -14,16 +14,20 @@
     T elements[N];
 };
 
-struct tint_symbol_3 {
+struct tint_symbol_4 {
   /* 0x0000 */ tint_array<uint, 1> arr;
 };
 
-void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, device tint_array<uint, 1>* const tint_symbol_1) {
-  (*(tint_symbol_1))[subgroup_invocation_id] = subgroup_size;
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
+void tint_symbol_inner(uint subgroup_invocation_id, uint subgroup_size, device tint_array<uint, 1>* const tint_symbol_1, const constant TintArrayLengths* const tint_symbol_2) {
+  (*(tint_symbol_1))[min(subgroup_invocation_id, (((*(tint_symbol_2)).array_lengths[0u][0u] / 4u) - 1u))] = subgroup_size;
 }
 
-fragment void tint_symbol(device tint_symbol_3* tint_symbol_2 [[buffer(0)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
-  tint_symbol_inner(subgroup_invocation_id, subgroup_size, &((*(tint_symbol_2)).arr));
+fragment void tint_symbol(device tint_symbol_4* tint_symbol_3 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_5 [[buffer(30)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
+  tint_symbol_inner(subgroup_invocation_id, subgroup_size, &((*(tint_symbol_3)).arr), tint_symbol_5);
   return;
 }
 
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.spvasm
index 0433dd5..847dff2 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 24
+; Bound: 31
 ; Schema: 0
                OpCapability Shader
                OpCapability GroupNonUniform
+         %22 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main" %main_subgroup_invocation_id_Input %main_subgroup_size_Input
                OpExecutionMode %main OriginUpperLeft
@@ -36,21 +37,27 @@
 %main_subgroup_size_Input = OpVariable %_ptr_Input_uint Input
        %void = OpTypeVoid
          %13 = OpTypeFunction %void %uint %uint
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
-         %19 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+         %26 = OpTypeFunction %void
  %main_inner = OpFunction %void None %13
 %subgroup_invocation_id = OpFunctionParameter %uint
 %subgroup_size = OpFunctionParameter %uint
          %14 = OpLabel
-         %15 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %subgroup_invocation_id
-               OpStore %15 %subgroup_size None
+         %15 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %18 = OpArrayLength %uint %1 0
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpExtInst %uint %22 UMin %subgroup_invocation_id %19
+         %23 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %21
+               OpStore %23 %subgroup_size None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %19
-         %20 = OpLabel
-         %21 = OpLoad %uint %main_subgroup_invocation_id_Input None
-         %22 = OpLoad %uint %main_subgroup_size_Input None
-         %23 = OpFunctionCall %void %main_inner %21 %22
+       %main = OpFunction %void None %26
+         %27 = OpLabel
+         %28 = OpLoad %uint %main_subgroup_invocation_id_Input None
+         %29 = OpLoad %uint %main_subgroup_size_Input None
+         %30 = OpFunctionCall %void %main_inner %28 %29
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.dxc.hlsl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
index f32544d..1bb627d 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
@@ -6,11 +6,14 @@
 };
 
 void main_inner(FragmentInputs inputs) {
-  output.Store((4u * inputs.subgroup_invocation_id), asuint(inputs.subgroup_size));
+  uint tint_symbol_1 = 0u;
+  output.GetDimensions(tint_symbol_1);
+  uint tint_symbol_2 = (tint_symbol_1 / 4u);
+  output.Store((4u * min(inputs.subgroup_invocation_id, (tint_symbol_2 - 1u))), asuint(inputs.subgroup_size));
 }
 
 void main() {
-  FragmentInputs tint_symbol = {WaveGetLaneIndex(), WaveGetLaneCount()};
-  main_inner(tint_symbol);
+  FragmentInputs tint_symbol_3 = {WaveGetLaneIndex(), WaveGetLaneCount()};
+  main_inner(tint_symbol_3);
   return;
 }
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
index 22272af..dd15851 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.dxc.hlsl
@@ -6,11 +6,13 @@
 
 RWByteAddressBuffer output : register(u0);
 void main_inner(FragmentInputs inputs) {
-  output.Store((0u + (inputs.subgroup_invocation_id * 4u)), inputs.subgroup_size);
+  uint v = 0u;
+  output.GetDimensions(v);
+  output.Store((0u + (min(inputs.subgroup_invocation_id, ((v / 4u) - 1u)) * 4u)), inputs.subgroup_size);
 }
 
 void main() {
-  FragmentInputs v = {WaveGetLaneIndex(), WaveGetLaneCount()};
-  main_inner(v);
+  FragmentInputs v_1 = {WaveGetLaneIndex(), WaveGetLaneCount()};
+  main_inner(v_1);
 }
 
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.msl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.msl
index e52db92..474e048 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.msl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.ir.msl
@@ -20,13 +20,14 @@
 
 struct tint_module_vars_struct {
   device tint_array<uint, 1>* output;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 void tint_symbol_inner(FragmentInputs inputs, tint_module_vars_struct tint_module_vars) {
-  (*tint_module_vars.output)[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+  (*tint_module_vars.output)[min(inputs.subgroup_invocation_id, (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u))] = inputs.subgroup_size;
 }
 
-fragment void tint_symbol(uint FragmentInputs_subgroup_invocation_id [[thread_index_in_simdgroup]], uint FragmentInputs_subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]]) {
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output};
+fragment void tint_symbol(uint FragmentInputs_subgroup_invocation_id [[thread_index_in_simdgroup]], uint FragmentInputs_subgroup_size [[threads_per_simdgroup]], device tint_array<uint, 1>* output [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.output=output, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(FragmentInputs{.subgroup_invocation_id=FragmentInputs_subgroup_invocation_id, .subgroup_size=FragmentInputs_subgroup_size}, tint_module_vars);
 }
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.msl b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.msl
index f423b1d..245ce77 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.msl
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.msl
@@ -14,22 +14,26 @@
     T elements[N];
 };
 
-struct tint_symbol_4 {
+struct tint_symbol_5 {
   /* 0x0000 */ tint_array<uint, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 struct FragmentInputs {
   uint subgroup_invocation_id;
   uint subgroup_size;
 };
 
-void tint_symbol_inner(FragmentInputs inputs, device tint_array<uint, 1>* const tint_symbol_2) {
-  (*(tint_symbol_2))[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+void tint_symbol_inner(FragmentInputs inputs, device tint_array<uint, 1>* const tint_symbol_2, const constant TintArrayLengths* const tint_symbol_3) {
+  (*(tint_symbol_2))[min(inputs.subgroup_invocation_id, (((*(tint_symbol_3)).array_lengths[0u][0u] / 4u) - 1u))] = inputs.subgroup_size;
 }
 
-fragment void tint_symbol(device tint_symbol_4* tint_symbol_3 [[buffer(0)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
+fragment void tint_symbol(device tint_symbol_5* tint_symbol_4 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_6 [[buffer(30)]], uint subgroup_invocation_id [[thread_index_in_simdgroup]], uint subgroup_size [[threads_per_simdgroup]]) {
   FragmentInputs const tint_symbol_1 = FragmentInputs{.subgroup_invocation_id=subgroup_invocation_id, .subgroup_size=subgroup_size};
-  tint_symbol_inner(tint_symbol_1, &((*(tint_symbol_3)).arr));
+  tint_symbol_inner(tint_symbol_1, &((*(tint_symbol_4)).arr), tint_symbol_6);
   return;
 }
 
diff --git a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.spvasm b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.spvasm
index dc4d481..1c9449e 100644
--- a/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.spvasm
+++ b/test/tint/types/functions/shader_io/fragment_subgroup_builtins_struct.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 27
+; Bound: 34
 ; Schema: 0
                OpCapability Shader
                OpCapability GroupNonUniform
+         %23 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint Fragment %main "main" %main_subgroup_invocation_id_Input %main_subgroup_size_Input
                OpExecutionMode %main OriginUpperLeft
@@ -41,23 +42,29 @@
        %void = OpTypeVoid
 %FragmentInputs = OpTypeStruct %uint %uint
          %13 = OpTypeFunction %void %FragmentInputs
-%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
      %uint_0 = OpConstant %uint 0
-         %21 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+         %28 = OpTypeFunction %void
  %main_inner = OpFunction %void None %13
      %inputs = OpFunctionParameter %FragmentInputs
          %14 = OpLabel
          %15 = OpCompositeExtract %uint %inputs 0
-         %16 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %15
-         %19 = OpCompositeExtract %uint %inputs 1
-               OpStore %16 %19 None
+         %16 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %1 %uint_0
+         %19 = OpArrayLength %uint %1 0
+         %20 = OpISub %uint %19 %uint_1
+         %22 = OpExtInst %uint %23 UMin %15 %20
+         %24 = OpAccessChain %_ptr_StorageBuffer_uint %1 %uint_0 %22
+         %26 = OpCompositeExtract %uint %inputs 1
+               OpStore %24 %26 None
                OpReturn
                OpFunctionEnd
-       %main = OpFunction %void None %21
-         %22 = OpLabel
-         %23 = OpLoad %uint %main_subgroup_invocation_id_Input None
-         %24 = OpLoad %uint %main_subgroup_size_Input None
-         %25 = OpCompositeConstruct %FragmentInputs %23 %24
-         %26 = OpFunctionCall %void %main_inner %25
+       %main = OpFunction %void None %28
+         %29 = OpLabel
+         %30 = OpLoad %uint %main_subgroup_invocation_id_Input None
+         %31 = OpLoad %uint %main_subgroup_size_Input None
+         %32 = OpCompositeConstruct %FragmentInputs %30 %31
+         %33 = OpFunctionCall %void %main_inner %32
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.dxc.hlsl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.dxc.hlsl
index 989e64a..9133fe8 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.dxc.hlsl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.dxc.hlsl
@@ -19,9 +19,12 @@
 }
 
 void bar(float a, float b) {
+  uint tint_symbol_3 = 0u;
+  storages.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
   p = a;
   w = b;
-  storages.Store(0u, asuint(asfloat(uniforms.Load(0u))));
+  storages.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(asfloat(uniforms.Load(0u))));
   zoo();
 }
 
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.fxc.hlsl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.fxc.hlsl
index 989e64a..9133fe8 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.fxc.hlsl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.fxc.hlsl
@@ -19,9 +19,12 @@
 }
 
 void bar(float a, float b) {
+  uint tint_symbol_3 = 0u;
+  storages.GetDimensions(tint_symbol_3);
+  uint tint_symbol_4 = (tint_symbol_3 / 4u);
   p = a;
   w = b;
-  storages.Store(0u, asuint(asfloat(uniforms.Load(0u))));
+  storages.Store((4u * min(0u, (tint_symbol_4 - 1u))), asuint(asfloat(uniforms.Load(0u))));
   zoo();
 }
 
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.glsl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.glsl
index 06b2716..62ee64d 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.glsl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.glsl
@@ -18,7 +18,9 @@
 void bar(float a, float b) {
   p = a;
   w = b;
-  v_1.inner[0] = v.inner.x;
+  uint v_2 = (uint(v_1.inner.length()) - 1u);
+  uint v_3 = min(uint(0), v_2);
+  v_1.inner[v_3] = v.inner.x;
   zoo();
 }
 void foo(float a) {
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.dxc.hlsl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.dxc.hlsl
index 34ae5b8..2ed73d5 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.dxc.hlsl
@@ -17,7 +17,11 @@
 void bar(float a, float b) {
   p = a;
   w = b;
-  storages.Store(0u, asuint(asfloat(uniforms.Load(0u))));
+  uint v = 0u;
+  storages.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  storages.Store((0u + v_2), asuint(asfloat(uniforms.Load(0u))));
   zoo();
 }
 
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.fxc.hlsl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.fxc.hlsl
index 34ae5b8..2ed73d5 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.fxc.hlsl
@@ -17,7 +17,11 @@
 void bar(float a, float b) {
   p = a;
   w = b;
-  storages.Store(0u, asuint(asfloat(uniforms.Load(0u))));
+  uint v = 0u;
+  storages.GetDimensions(v);
+  uint v_1 = ((v / 4u) - 1u);
+  uint v_2 = (min(uint(int(0)), v_1) * 4u);
+  storages.Store((0u + v_2), asuint(asfloat(uniforms.Load(0u))));
   zoo();
 }
 
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.msl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.msl
index 38b1a79..b153f23 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.msl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.ir.msl
@@ -18,6 +18,7 @@
   threadgroup float* w;
   const device float2* uniforms;
   device tint_array<float, 1>* storages;
+  const constant tint_array<uint4, 1>* tint_storage_buffer_sizes;
 };
 
 struct tint_symbol_2 {
@@ -34,7 +35,9 @@
 void bar(float a, float b, tint_module_vars_struct tint_module_vars) {
   (*tint_module_vars.p) = a;
   (*tint_module_vars.w) = b;
-  (*tint_module_vars.storages)[0] = (*tint_module_vars.uniforms)[0u];
+  uint const v = (((*tint_module_vars.tint_storage_buffer_sizes)[0u][0u] / 4u) - 1u);
+  device float* const v_1 = (&(*tint_module_vars.storages)[min(uint(0), v)]);
+  (*v_1) = (*tint_module_vars.uniforms)[0u];
   zoo(tint_module_vars);
 }
 
@@ -52,8 +55,8 @@
   foo(1.0f, tint_module_vars);
 }
 
-kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v [[threadgroup(0)]], const device float2* uniforms [[buffer(1)]], device tint_array<float, 1>* storages [[buffer(0)]]) {
+kernel void tint_symbol(uint tint_local_index [[thread_index_in_threadgroup]], threadgroup tint_symbol_2* v_2 [[threadgroup(0)]], const device float2* uniforms [[buffer(1)]], device tint_array<float, 1>* storages [[buffer(0)]], const constant tint_array<uint4, 1>* tint_storage_buffer_sizes [[buffer(30)]]) {
   thread float p = 0.0f;
-  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.p=(&p), .w=(&(*v).tint_symbol_1), .uniforms=uniforms, .storages=storages};
+  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.p=(&p), .w=(&(*v_2).tint_symbol_1), .uniforms=uniforms, .storages=storages, .tint_storage_buffer_sizes=tint_storage_buffer_sizes};
   tint_symbol_inner(tint_local_index, tint_module_vars);
 }
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.msl b/test/tint/types/module_scope_used_in_functions.wgsl.expected.msl
index ddf7ed0..4c3a9f0 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.msl
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.msl
@@ -18,10 +18,14 @@
   float p;
 };
 
-struct tint_symbol_13 {
+struct tint_symbol_16 {
   /* 0x0000 */ tint_array<float, 1> arr;
 };
 
+struct TintArrayLengths {
+  /* 0x0000 */ tint_array<uint4, 1> array_lengths;
+};
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup float* const tint_symbol_1) {
   if ((local_idx < 1u)) {
     *(tint_symbol_1) = 0.0f;
@@ -36,28 +40,28 @@
   (*(tint_private_vars)).p = ((*(tint_private_vars)).p * 2.0f);
 }
 
-void bar(float a, float b, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_2, device tint_array<float, 1>* const tint_symbol_3, const device float2* const tint_symbol_4) {
+void bar(float a, float b, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_2, device tint_array<float, 1>* const tint_symbol_3, const constant TintArrayLengths* const tint_symbol_4, const device float2* const tint_symbol_5) {
   (*(tint_private_vars)).p = a;
   *(tint_symbol_2) = b;
-  (*(tint_symbol_3))[0] = (*(tint_symbol_4))[0];
+  (*(tint_symbol_3))[min(0u, (((*(tint_symbol_4)).array_lengths[0u][0u] / 4u) - 1u))] = (*(tint_symbol_5))[0];
   zoo(tint_private_vars);
 }
 
-void foo(float a, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_5, device tint_array<float, 1>* const tint_symbol_6, const device float2* const tint_symbol_7) {
+void foo(float a, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_6, device tint_array<float, 1>* const tint_symbol_7, const constant TintArrayLengths* const tint_symbol_8, const device float2* const tint_symbol_9) {
   float const b = 2.0f;
-  bar(a, b, tint_private_vars, tint_symbol_5, tint_symbol_6, tint_symbol_7);
+  bar(a, b, tint_private_vars, tint_symbol_6, tint_symbol_7, tint_symbol_8, tint_symbol_9);
   no_uses();
 }
 
-void tint_symbol_inner(uint local_invocation_index, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_8, device tint_array<float, 1>* const tint_symbol_9, const device float2* const tint_symbol_10) {
-  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_8);
-  foo(1.0f, tint_private_vars, tint_symbol_8, tint_symbol_9, tint_symbol_10);
+void tint_symbol_inner(uint local_invocation_index, thread tint_private_vars_struct* const tint_private_vars, threadgroup float* const tint_symbol_10, device tint_array<float, 1>* const tint_symbol_11, const constant TintArrayLengths* const tint_symbol_12, const device float2* const tint_symbol_13) {
+  tint_zero_workgroup_memory(local_invocation_index, tint_symbol_10);
+  foo(1.0f, tint_private_vars, tint_symbol_10, tint_symbol_11, tint_symbol_12, tint_symbol_13);
 }
 
-kernel void tint_symbol(device tint_symbol_13* tint_symbol_12 [[buffer(0)]], const device float2* tint_symbol_14 [[buffer(1)]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
+kernel void tint_symbol(device tint_symbol_16* tint_symbol_15 [[buffer(0)]], const constant TintArrayLengths* tint_symbol_17 [[buffer(30)]], const device float2* tint_symbol_18 [[buffer(1)]], uint local_invocation_index [[thread_index_in_threadgroup]]) {
   thread tint_private_vars_struct tint_private_vars = {};
-  threadgroup float tint_symbol_11;
-  tint_symbol_inner(local_invocation_index, &(tint_private_vars), &(tint_symbol_11), &((*(tint_symbol_12)).arr), tint_symbol_14);
+  threadgroup float tint_symbol_14;
+  tint_symbol_inner(local_invocation_index, &(tint_private_vars), &(tint_symbol_14), &((*(tint_symbol_15)).arr), tint_symbol_17, tint_symbol_18);
   return;
 }
 
diff --git a/test/tint/types/module_scope_used_in_functions.wgsl.expected.spvasm b/test/tint/types/module_scope_used_in_functions.wgsl.expected.spvasm
index 33a106e..fd6edb9 100644
--- a/test/tint/types/module_scope_used_in_functions.wgsl.expected.spvasm
+++ b/test/tint/types/module_scope_used_in_functions.wgsl.expected.spvasm
@@ -1,9 +1,10 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 68
+; Bound: 75
 ; Schema: 0
                OpCapability Shader
+         %42 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main" %main_local_invocation_index_Input
                OpExecutionMode %main LocalSize 1 1 1
@@ -58,15 +59,16 @@
          %20 = OpTypeFunction %void
         %b_0 = OpConstant %float 2
          %30 = OpTypeFunction %void %float %float
-%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
+%_ptr_StorageBuffer__runtimearr_float = OpTypePointer StorageBuffer %_runtimearr_float
      %uint_0 = OpConstant %uint 0
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
 %_ptr_StorageBuffer_v2float = OpTypePointer StorageBuffer %v2float
 %_ptr_StorageBuffer_float_0 = OpTypePointer StorageBuffer %float
-         %45 = OpTypeFunction %void %float
-         %51 = OpTypeFunction %void %uint
-     %uint_1 = OpConstant %uint 1
+         %53 = OpTypeFunction %void %float
+         %59 = OpTypeFunction %void %uint
        %bool = OpTypeBool
     %float_0 = OpConstant %float 0
      %uint_2 = OpConstant %uint 2
@@ -89,38 +91,43 @@
          %31 = OpLabel
                OpStore %p %a None
                OpStore %w %b None
-         %32 = OpAccessChain %_ptr_StorageBuffer_float %11 %uint_0 %int_0
-         %37 = OpAccessChain %_ptr_StorageBuffer_v2float %7 %uint_0
-         %39 = OpAccessChain %_ptr_StorageBuffer_float_0 %37 %uint_0
-         %41 = OpLoad %float %39 None
-               OpStore %32 %41 None
-         %42 = OpFunctionCall %void %zoo
+         %32 = OpAccessChain %_ptr_StorageBuffer__runtimearr_float %11 %uint_0
+         %35 = OpArrayLength %uint %11 0
+         %36 = OpISub %uint %35 %uint_1
+         %38 = OpBitcast %uint %int_0
+         %41 = OpExtInst %uint %42 UMin %38 %36
+         %43 = OpAccessChain %_ptr_StorageBuffer_float %11 %uint_0 %41
+         %45 = OpAccessChain %_ptr_StorageBuffer_v2float %7 %uint_0
+         %47 = OpAccessChain %_ptr_StorageBuffer_float_0 %45 %uint_0
+         %49 = OpLoad %float %47 None
+               OpStore %43 %49 None
+         %50 = OpFunctionCall %void %zoo
                OpReturn
                OpFunctionEnd
-        %foo = OpFunction %void None %45
+        %foo = OpFunction %void None %53
         %a_0 = OpFunctionParameter %float
-         %46 = OpLabel
-         %47 = OpFunctionCall %void %bar %a_0 %b_0
-         %48 = OpFunctionCall %void %no_uses
+         %54 = OpLabel
+         %55 = OpFunctionCall %void %bar %a_0 %b_0
+         %56 = OpFunctionCall %void %no_uses
                OpReturn
                OpFunctionEnd
- %main_inner = OpFunction %void None %51
+ %main_inner = OpFunction %void None %59
 %tint_local_index = OpFunctionParameter %uint
-         %52 = OpLabel
-         %53 = OpULessThan %bool %tint_local_index %uint_1
-               OpSelectionMerge %56 None
-               OpBranchConditional %53 %57 %56
-         %57 = OpLabel
+         %60 = OpLabel
+         %61 = OpULessThan %bool %tint_local_index %uint_1
+               OpSelectionMerge %63 None
+               OpBranchConditional %61 %64 %63
+         %64 = OpLabel
                OpStore %w %float_0 None
-               OpBranch %56
-         %56 = OpLabel
+               OpBranch %63
+         %63 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-         %62 = OpFunctionCall %void %foo %float_1
+         %69 = OpFunctionCall %void %foo %float_1
                OpReturn
                OpFunctionEnd
        %main = OpFunction %void None %20
-         %65 = OpLabel
-         %66 = OpLoad %uint %main_local_invocation_index_Input None
-         %67 = OpFunctionCall %void %main_inner %66
+         %72 = OpLabel
+         %73 = OpLoad %uint %main_local_invocation_index_Input None
+         %74 = OpFunctionCall %void %main_inner %73
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.glsl b/test/tint/types/texture/depth/2d.wgsl.expected.glsl
index 2425b71..5a1cabf 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.glsl
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.glsl
@@ -1,7 +1,17 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D t_f;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 dims = uvec2(textureSize(t_f, 0));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 dims = uvec2(textureSize(t_f, int(min(uint(0), v_1))));
 }
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/depth/2d.wgsl.expected.ir.dxc.hlsl
index a96ae57..c34b7a9 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/depth/2d.wgsl.expected.ir.fxc.hlsl
index a96ae57..c34b7a9 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.ir.msl b/test/tint/types/texture/depth/2d.wgsl.expected.ir.msl
index 9577975..e2b8d70 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.ir.msl
@@ -7,6 +7,6 @@
 
 kernel void tint_symbol(depth2d<float, access::sample> t_f [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f};
-  uint const v = uint(0);
+  uint const v = min(uint(0), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 dims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
 }
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.msl b/test/tint/types/texture/depth/2d.wgsl.expected.msl
index d5b42dc..d6191ea 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.msl
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 kernel void tint_symbol(depth2d<float, access::sample> tint_symbol_1 [[texture(0)]]) {
-  uint2 dims = uint2(tint_symbol_1.get_width(0), tint_symbol_1.get_height(0));
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 dims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return;
 }
 
diff --git a/test/tint/types/texture/depth/2d.wgsl.expected.spvasm b/test/tint/types/texture/depth/2d.wgsl.expected.spvasm
index 8957fdc..5e265fe 100644
--- a/test/tint/types/texture/depth/2d.wgsl.expected.spvasm
+++ b/test/tint/types/texture/depth/2d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 17
+; Bound: 23
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -20,15 +21,20 @@
        %void = OpTypeVoid
           %7 = OpTypeFunction %void
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+     %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %7
           %8 = OpLabel
        %dims = OpVariable %_ptr_Function_v2uint Function
           %9 = OpLoad %3 %t_f None
-         %10 = OpImageQuerySizeLod %v2uint %9 %int_0
-               OpStore %dims %10
+         %10 = OpImageQueryLevels %uint %9
+         %12 = OpISub %uint %10 %uint_1
+         %14 = OpBitcast %uint %int_0
+         %17 = OpExtInst %uint %18 UMin %14 %12
+         %19 = OpImageQuerySizeLod %v2uint %9 %17
+               OpStore %dims %19
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.glsl b/test/tint/types/texture/depth/2d_array.wgsl.expected.glsl
index 2e6a6a8..af3ad28 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.glsl
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.glsl
@@ -1,7 +1,17 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray t_f;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 dims = uvec2(textureSize(t_f, 0).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 dims = uvec2(textureSize(t_f, int(min(uint(0), v_1))).xy);
 }
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.dxc.hlsl
index 315994f..0c58738 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z, v.w);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.fxc.hlsl
index 315994f..0c58738 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z, v.w);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.msl b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.msl
index 1e22c6f..932084c 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.ir.msl
@@ -7,6 +7,6 @@
 
 kernel void tint_symbol(depth2d_array<float, access::sample> t_f [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f};
-  uint const v = uint(0);
+  uint const v = min(uint(0), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 dims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
 }
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.msl b/test/tint/types/texture/depth/2d_array.wgsl.expected.msl
index 6f36a2d..bb17e7e 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.msl
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 kernel void tint_symbol(depth2d_array<float, access::sample> tint_symbol_1 [[texture(0)]]) {
-  uint2 dims = uint2(tint_symbol_1.get_width(0), tint_symbol_1.get_height(0));
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 dims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return;
 }
 
diff --git a/test/tint/types/texture/depth/2d_array.wgsl.expected.spvasm b/test/tint/types/texture/depth/2d_array.wgsl.expected.spvasm
index c7b479d..793f0e4 100644
--- a/test/tint/types/texture/depth/2d_array.wgsl.expected.spvasm
+++ b/test/tint/types/texture/depth/2d_array.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 19
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -20,17 +21,22 @@
        %void = OpTypeVoid
           %7 = OpTypeFunction %void
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %7
           %8 = OpLabel
        %dims = OpVariable %_ptr_Function_v2uint Function
           %9 = OpLoad %3 %t_f None
-         %10 = OpImageQuerySizeLod %v3uint %9 %int_0
-         %15 = OpVectorShuffle %v2uint %10 %10 0 1
-               OpStore %dims %15
+         %10 = OpImageQueryLevels %uint %9
+         %12 = OpISub %uint %10 %uint_1
+         %14 = OpBitcast %uint %int_0
+         %17 = OpExtInst %uint %18 UMin %14 %12
+         %19 = OpImageQuerySizeLod %v3uint %9 %17
+         %21 = OpVectorShuffle %v2uint %19 %19 0 1
+               OpStore %dims %21
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.glsl b/test/tint/types/texture/depth/cube.wgsl.expected.glsl
index 319dc93..d34a5d6 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.glsl
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.glsl
@@ -1,7 +1,17 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube t_f;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 dims = uvec2(textureSize(t_f, 0));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 dims = uvec2(textureSize(t_f, int(min(uint(0), v_1))));
 }
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/depth/cube.wgsl.expected.ir.dxc.hlsl
index a8813a1..4a5b49a 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/depth/cube.wgsl.expected.ir.fxc.hlsl
index a8813a1..4a5b49a 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
+  uint3 v_1 = (0u).xxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.ir.msl b/test/tint/types/texture/depth/cube.wgsl.expected.ir.msl
index bc23274..35e9240 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.ir.msl
@@ -7,6 +7,6 @@
 
 kernel void tint_symbol(depthcube<float, access::sample> t_f [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f};
-  uint const v = uint(0);
+  uint const v = min(uint(0), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 dims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
 }
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.msl b/test/tint/types/texture/depth/cube.wgsl.expected.msl
index 0726ef2..c4b1cde 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.msl
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 kernel void tint_symbol(depthcube<float, access::sample> tint_symbol_1 [[texture(0)]]) {
-  uint2 dims = uint2(tint_symbol_1.get_width(0), tint_symbol_1.get_height(0));
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 dims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return;
 }
 
diff --git a/test/tint/types/texture/depth/cube.wgsl.expected.spvasm b/test/tint/types/texture/depth/cube.wgsl.expected.spvasm
index 5e94447..a29e33d 100644
--- a/test/tint/types/texture/depth/cube.wgsl.expected.spvasm
+++ b/test/tint/types/texture/depth/cube.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 17
+; Bound: 23
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -20,15 +21,20 @@
        %void = OpTypeVoid
           %7 = OpTypeFunction %void
        %uint = OpTypeInt 32 0
-     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+     %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %7
           %8 = OpLabel
        %dims = OpVariable %_ptr_Function_v2uint Function
           %9 = OpLoad %3 %t_f None
-         %10 = OpImageQuerySizeLod %v2uint %9 %int_0
-               OpStore %dims %10
+         %10 = OpImageQueryLevels %uint %9
+         %12 = OpISub %uint %10 %uint_1
+         %14 = OpBitcast %uint %int_0
+         %17 = OpExtInst %uint %18 UMin %14 %12
+         %19 = OpImageQuerySizeLod %v2uint %9 %17
+               OpStore %dims %19
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.glsl b/test/tint/types/texture/depth/cube_array.wgsl.expected.glsl
index b0ab81d..0a38be7 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.glsl
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.glsl
@@ -1,7 +1,17 @@
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray t_f;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 dims = uvec2(textureSize(t_f, 0).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 dims = uvec2(textureSize(t_f, int(min(uint(0), v_1))).xy);
 }
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.dxc.hlsl
index d9eb7bb..fc37a1f 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.dxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z, v.w);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.fxc.hlsl
index d9eb7bb..fc37a1f 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.fxc.hlsl
@@ -3,7 +3,9 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(0)), v.x, v.y, v.z, v.w);
-  uint2 dims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
+  uint4 v_1 = (0u).xxxx;
+  t_f.GetDimensions(uint(min(uint(int(0)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 dims = v_1.xy;
 }
 
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.msl b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.msl
index b6d4451..1b2372f 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.ir.msl
@@ -7,6 +7,6 @@
 
 kernel void tint_symbol(depthcube_array<float, access::sample> t_f [[texture(0)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f};
-  uint const v = uint(0);
+  uint const v = min(uint(0), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 dims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
 }
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.msl b/test/tint/types/texture/depth/cube_array.wgsl.expected.msl
index 2352cfd..dc2e59c 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.msl
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.msl
@@ -2,7 +2,8 @@
 
 using namespace metal;
 kernel void tint_symbol(depthcube_array<float, access::sample> tint_symbol_1 [[texture(0)]]) {
-  uint2 dims = uint2(tint_symbol_1.get_width(0), tint_symbol_1.get_height(0));
+  uint const level_idx = min(0u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 dims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
   return;
 }
 
diff --git a/test/tint/types/texture/depth/cube_array.wgsl.expected.spvasm b/test/tint/types/texture/depth/cube_array.wgsl.expected.spvasm
index d7d9d76..c363bfb 100644
--- a/test/tint/types/texture/depth/cube_array.wgsl.expected.spvasm
+++ b/test/tint/types/texture/depth/cube_array.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 19
+; Bound: 25
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %18 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -21,17 +22,22 @@
        %void = OpTypeVoid
           %7 = OpTypeFunction %void
        %uint = OpTypeInt 32 0
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
         %int = OpTypeInt 32 1
       %int_0 = OpConstant %int 0
+     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %7
           %8 = OpLabel
        %dims = OpVariable %_ptr_Function_v2uint Function
           %9 = OpLoad %3 %t_f None
-         %10 = OpImageQuerySizeLod %v3uint %9 %int_0
-         %15 = OpVectorShuffle %v2uint %10 %10 0 1
-               OpStore %dims %15
+         %10 = OpImageQueryLevels %uint %9
+         %12 = OpISub %uint %10 %uint_1
+         %14 = OpBitcast %uint %int_0
+         %17 = OpExtInst %uint %18 UMin %14 %12
+         %19 = OpImageQuerySizeLod %v3uint %9 %17
+         %21 = OpVectorShuffle %v2uint %19 %19 0 1
+               OpStore %dims %21
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.glsl b/test/tint/types/texture/sampled/1d.wgsl.expected.glsl
index f75a715..23ad77a 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D t_f;
 uniform highp isampler2D t_i;
 uniform highp usampler2D t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uint fdims = uvec2(textureSize(t_f, 1)).x;
-  uint idims = uvec2(textureSize(t_i, 1)).x;
-  uint udims = uvec2(textureSize(t_u, 1)).x;
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uint fdims = uvec2(textureSize(t_f, int(min(uint(1), v_1)))).x;
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uint idims = uvec2(textureSize(t_i, int(min(uint(1), v_2)))).x;
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uint udims = uvec2(textureSize(t_u, int(min(uint(1), v_3)))).x;
 }
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.dxc.hlsl
index 082a71b..19fdd3f 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint2 v = (0u).xx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y);
-  uint fdims = v.x;
+  t_f.GetDimensions(0u, v.x, v.y);
   uint2 v_1 = (0u).xx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y);
-  uint idims = v_1.x;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint fdims = v_1.x;
   uint2 v_2 = (0u).xx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y);
-  uint udims = v_2.x;
+  t_i.GetDimensions(0u, v_2.x, v_2.y);
+  uint2 v_3 = (0u).xx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.y - 1u))), v_3.x, v_3.y);
+  uint idims = v_3.x;
+  uint2 v_4 = (0u).xx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y);
+  uint2 v_5 = (0u).xx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.y - 1u))), v_5.x, v_5.y);
+  uint udims = v_5.x;
 }
 
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.fxc.hlsl
index 082a71b..19fdd3f 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint2 v = (0u).xx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y);
-  uint fdims = v.x;
+  t_f.GetDimensions(0u, v.x, v.y);
   uint2 v_1 = (0u).xx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y);
-  uint idims = v_1.x;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.y - 1u))), v_1.x, v_1.y);
+  uint fdims = v_1.x;
   uint2 v_2 = (0u).xx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y);
-  uint udims = v_2.x;
+  t_i.GetDimensions(0u, v_2.x, v_2.y);
+  uint2 v_3 = (0u).xx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.y - 1u))), v_3.x, v_3.y);
+  uint idims = v_3.x;
+  uint2 v_4 = (0u).xx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y);
+  uint2 v_5 = (0u).xx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.y - 1u))), v_5.x, v_5.y);
+  uint udims = v_5.x;
 }
 
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.msl
index bcd5ac8..1e8817d 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.ir.msl
@@ -9,7 +9,10 @@
 
 kernel void tint_symbol(texture1d<float, access::sample> t_f [[texture(0)]], texture1d<int, access::sample> t_i [[texture(1)]], texture1d<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
+  min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint fdims = uint(tint_module_vars.t_f.get_width());
+  min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint idims = uint(tint_module_vars.t_i.get_width());
+  min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint udims = uint(tint_module_vars.t_u.get_width());
 }
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.msl b/test/tint/types/texture/sampled/1d.wgsl.expected.msl
index d0d9933..17a493a 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.msl
@@ -2,8 +2,11 @@
 
 using namespace metal;
 kernel void tint_symbol(texture1d<float, access::sample> tint_symbol_1 [[texture(0)]], texture1d<int, access::sample> tint_symbol_2 [[texture(1)]], texture1d<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
   uint fdims = tint_symbol_1.get_width(0);
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
   uint idims = tint_symbol_2.get_width(0);
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
   uint udims = tint_symbol_3.get_width(0);
   return;
 }
diff --git a/test/tint/types/texture/sampled/1d.wgsl.expected.spvasm b/test/tint/types/texture/sampled/1d.wgsl.expected.spvasm
index f3d9996..24e46a5 100644
--- a/test/tint/types/texture/sampled/1d.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/1d.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 28
+; Bound: 42
 ; Schema: 0
                OpCapability Shader
                OpCapability Sampled1D
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,6 +37,7 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
 %_ptr_Function_uint = OpTypePointer Function %uint
        %main = OpFunction %void None %15
@@ -44,13 +46,25 @@
       %idims = OpVariable %_ptr_Function_uint Function
       %udims = OpVariable %_ptr_Function_uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %uint %17 %int_1
-               OpStore %fdims %18
-         %22 = OpLoad %7 %t_i None
-         %23 = OpImageQuerySizeLod %uint %22 %int_1
-               OpStore %idims %23
-         %25 = OpLoad %11 %t_u None
-         %26 = OpImageQuerySizeLod %uint %25 %int_1
-               OpStore %udims %26
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %uint %17 %23
+               OpStore %fdims %25
+         %28 = OpLoad %7 %t_i None
+         %29 = OpImageQueryLevels %uint %28
+         %30 = OpISub %uint %29 %uint_1
+         %31 = OpBitcast %uint %int_1
+         %32 = OpExtInst %uint %24 UMin %31 %30
+         %33 = OpImageQuerySizeLod %uint %28 %32
+               OpStore %idims %33
+         %35 = OpLoad %11 %t_u None
+         %36 = OpImageQueryLevels %uint %35
+         %37 = OpISub %uint %36 %uint_1
+         %38 = OpBitcast %uint %int_1
+         %39 = OpExtInst %uint %24 UMin %38 %37
+         %40 = OpImageQuerySizeLod %uint %35 %39
+               OpStore %udims %40
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.glsl b/test/tint/types/texture/sampled/2d.wgsl.expected.glsl
index 666847f..b11a228 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2D t_f;
 uniform highp isampler2D t_i;
 uniform highp usampler2D t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 fdims = uvec2(textureSize(t_f, 1));
-  uvec2 idims = uvec2(textureSize(t_i, 1));
-  uvec2 udims = uvec2(textureSize(t_u, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 fdims = uvec2(textureSize(t_f, int(min(uint(1), v_1))));
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uvec2 idims = uvec2(textureSize(t_i, int(min(uint(1), v_2))));
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uvec2 udims = uvec2(textureSize(t_u, int(min(uint(1), v_3))));
 }
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.dxc.hlsl
index 3822640..d6c9ba6 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
   uint3 v_1 = (0u).xxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 fdims = v_1.xy;
   uint3 v_2 = (0u).xxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 idims = v_3.xy;
+  uint3 v_4 = (0u).xxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint3 v_5 = (0u).xxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.z - 1u))), v_5.x, v_5.y, v_5.z);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.fxc.hlsl
index 3822640..d6c9ba6 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
   uint3 v_1 = (0u).xxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 fdims = v_1.xy;
   uint3 v_2 = (0u).xxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 idims = v_3.xy;
+  uint3 v_4 = (0u).xxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint3 v_5 = (0u).xxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.z - 1u))), v_5.x, v_5.y, v_5.z);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.msl
index 25e6c24..517534a 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.ir.msl
@@ -9,10 +9,10 @@
 
 kernel void tint_symbol(texture2d<float, access::sample> t_f [[texture(0)]], texture2d<int, access::sample> t_i [[texture(1)]], texture2d<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 fdims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
-  uint const v_1 = uint(1);
+  uint const v_1 = min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint2 idims = uint2(tint_module_vars.t_i.get_width(v_1), tint_module_vars.t_i.get_height(v_1));
-  uint const v_2 = uint(1);
+  uint const v_2 = min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint2 udims = uint2(tint_module_vars.t_u.get_width(v_2), tint_module_vars.t_u.get_height(v_2));
 }
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.msl b/test/tint/types/texture/sampled/2d.wgsl.expected.msl
index d24cbab..023b4c6 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.msl
@@ -2,9 +2,12 @@
 
 using namespace metal;
 kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_1 [[texture(0)]], texture2d<int, access::sample> tint_symbol_2 [[texture(1)]], texture2d<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
-  uint2 fdims = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
-  uint2 idims = uint2(tint_symbol_2.get_width(1), tint_symbol_2.get_height(1));
-  uint2 udims = uint2(tint_symbol_3.get_width(1), tint_symbol_3.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 fdims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  uint2 idims = uint2(tint_symbol_2.get_width(level_idx_1), tint_symbol_2.get_height(level_idx_1));
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
+  uint2 udims = uint2(tint_symbol_3.get_width(level_idx_2), tint_symbol_3.get_height(level_idx_2));
   return;
 }
 
diff --git a/test/tint/types/texture/sampled/2d.wgsl.expected.spvasm b/test/tint/types/texture/sampled/2d.wgsl.expected.spvasm
index 6fb7072..ec4ef75 100644
--- a/test/tint/types/texture/sampled/2d.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/2d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,8 +36,9 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
-     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %15
          %16 = OpLabel
@@ -44,13 +46,25 @@
       %idims = OpVariable %_ptr_Function_v2uint Function
       %udims = OpVariable %_ptr_Function_v2uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %v2uint %17 %int_1
-               OpStore %fdims %18
-         %23 = OpLoad %7 %t_i None
-         %24 = OpImageQuerySizeLod %v2uint %23 %int_1
-               OpStore %idims %24
-         %26 = OpLoad %11 %t_u None
-         %27 = OpImageQuerySizeLod %v2uint %26 %int_1
-               OpStore %udims %27
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %v2uint %17 %23
+               OpStore %fdims %25
+         %29 = OpLoad %7 %t_i None
+         %30 = OpImageQueryLevels %uint %29
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %24 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v2uint %29 %33
+               OpStore %idims %34
+         %36 = OpLoad %11 %t_u None
+         %37 = OpImageQueryLevels %uint %36
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpBitcast %uint %int_1
+         %40 = OpExtInst %uint %24 UMin %39 %38
+         %41 = OpImageQuerySizeLod %v2uint %36 %40
+               OpStore %udims %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.glsl b/test/tint/types/texture/sampled/2d_array.wgsl.expected.glsl
index 8e93953..2c0c7cd 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler2DArray t_f;
 uniform highp isampler2DArray t_i;
 uniform highp usampler2DArray t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 fdims = uvec2(textureSize(t_f, 1).xy);
-  uvec2 idims = uvec2(textureSize(t_i, 1).xy);
-  uvec2 udims = uvec2(textureSize(t_u, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 fdims = uvec2(textureSize(t_f, int(min(uint(1), v_1))).xy);
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uvec2 idims = uvec2(textureSize(t_i, int(min(uint(1), v_2))).xy);
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uvec2 udims = uvec2(textureSize(t_u, int(min(uint(1), v_3))).xy);
 }
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.dxc.hlsl
index 79e8448..5dda79f 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 fdims = v_1.xy;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 idims = v_3.xy;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.fxc.hlsl
index 79e8448..5dda79f 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 fdims = v_1.xy;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 idims = v_3.xy;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.msl
index aa0715a..f6d0bc7 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.ir.msl
@@ -9,10 +9,10 @@
 
 kernel void tint_symbol(texture2d_array<float, access::sample> t_f [[texture(0)]], texture2d_array<int, access::sample> t_i [[texture(1)]], texture2d_array<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 fdims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
-  uint const v_1 = uint(1);
+  uint const v_1 = min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint2 idims = uint2(tint_module_vars.t_i.get_width(v_1), tint_module_vars.t_i.get_height(v_1));
-  uint const v_2 = uint(1);
+  uint const v_2 = min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint2 udims = uint2(tint_module_vars.t_u.get_width(v_2), tint_module_vars.t_u.get_height(v_2));
 }
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.msl b/test/tint/types/texture/sampled/2d_array.wgsl.expected.msl
index d16efb2..8bb5c5d 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.msl
@@ -2,9 +2,12 @@
 
 using namespace metal;
 kernel void tint_symbol(texture2d_array<float, access::sample> tint_symbol_1 [[texture(0)]], texture2d_array<int, access::sample> tint_symbol_2 [[texture(1)]], texture2d_array<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
-  uint2 fdims = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
-  uint2 idims = uint2(tint_symbol_2.get_width(1), tint_symbol_2.get_height(1));
-  uint2 udims = uint2(tint_symbol_3.get_width(1), tint_symbol_3.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 fdims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  uint2 idims = uint2(tint_symbol_2.get_width(level_idx_1), tint_symbol_2.get_height(level_idx_1));
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
+  uint2 udims = uint2(tint_symbol_3.get_width(level_idx_2), tint_symbol_3.get_height(level_idx_2));
   return;
 }
 
diff --git a/test/tint/types/texture/sampled/2d_array.wgsl.expected.spvasm b/test/tint/types/texture/sampled/2d_array.wgsl.expected.spvasm
index ef06f6c..4a8c2a0 100644
--- a/test/tint/types/texture/sampled/2d_array.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/2d_array.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,8 +36,9 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %15
@@ -45,16 +47,28 @@
       %idims = OpVariable %_ptr_Function_v2uint Function
       %udims = OpVariable %_ptr_Function_v2uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %v3uint %17 %int_1
-         %21 = OpVectorShuffle %v2uint %18 %18 0 1
-               OpStore %fdims %21
-         %25 = OpLoad %7 %t_i None
-         %26 = OpImageQuerySizeLod %v3uint %25 %int_1
-         %27 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %idims %27
-         %29 = OpLoad %11 %t_u None
-         %30 = OpImageQuerySizeLod %v3uint %29 %int_1
-         %31 = OpVectorShuffle %v2uint %30 %30 0 1
-               OpStore %udims %31
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %v3uint %17 %23
+         %27 = OpVectorShuffle %v2uint %25 %25 0 1
+               OpStore %fdims %27
+         %31 = OpLoad %7 %t_i None
+         %32 = OpImageQueryLevels %uint %31
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %24 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %31 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+               OpStore %idims %37
+         %39 = OpLoad %11 %t_u None
+         %40 = OpImageQueryLevels %uint %39
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %int_1
+         %43 = OpExtInst %uint %24 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %39 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+               OpStore %udims %45
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.glsl b/test/tint/types/texture/sampled/3d.wgsl.expected.glsl
index 972a5d1..e76f5ff 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp sampler3D t_f;
 uniform highp isampler3D t_i;
 uniform highp usampler3D t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec3 fdims = uvec3(textureSize(t_f, 1));
-  uvec3 idims = uvec3(textureSize(t_i, 1));
-  uvec3 udims = uvec3(textureSize(t_u, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec3 fdims = uvec3(textureSize(t_f, int(min(uint(1), v_1))));
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uvec3 idims = uvec3(textureSize(t_i, int(min(uint(1), v_2))));
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uvec3 udims = uvec3(textureSize(t_u, int(min(uint(1), v_3))));
 }
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.dxc.hlsl
index baf6250..6327197 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 fdims = v.xyz;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint3 idims = v_1.xyz;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 fdims = v_1.xyz;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint3 udims = v_2.xyz;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 idims = v_3.xyz;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint3 udims = v_5.xyz;
 }
 
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.fxc.hlsl
index baf6250..6327197 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint3 fdims = v.xyz;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint3 idims = v_1.xyz;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint3 fdims = v_1.xyz;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint3 udims = v_2.xyz;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint3 idims = v_3.xyz;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint3 udims = v_5.xyz;
 }
 
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.msl
index 013a7b7..9157066 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.ir.msl
@@ -9,10 +9,10 @@
 
 kernel void tint_symbol(texture3d<float, access::sample> t_f [[texture(0)]], texture3d<int, access::sample> t_i [[texture(1)]], texture3d<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint3 fdims = uint3(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v), tint_module_vars.t_f.get_depth(v));
-  uint const v_1 = uint(1);
+  uint const v_1 = min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint3 idims = uint3(tint_module_vars.t_i.get_width(v_1), tint_module_vars.t_i.get_height(v_1), tint_module_vars.t_i.get_depth(v_1));
-  uint const v_2 = uint(1);
+  uint const v_2 = min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint3 udims = uint3(tint_module_vars.t_u.get_width(v_2), tint_module_vars.t_u.get_height(v_2), tint_module_vars.t_u.get_depth(v_2));
 }
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.msl b/test/tint/types/texture/sampled/3d.wgsl.expected.msl
index f0f0065..9e419e7 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.msl
@@ -2,9 +2,12 @@
 
 using namespace metal;
 kernel void tint_symbol(texture3d<float, access::sample> tint_symbol_1 [[texture(0)]], texture3d<int, access::sample> tint_symbol_2 [[texture(1)]], texture3d<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
-  uint3 fdims = uint3(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1), tint_symbol_1.get_depth(1));
-  uint3 idims = uint3(tint_symbol_2.get_width(1), tint_symbol_2.get_height(1), tint_symbol_2.get_depth(1));
-  uint3 udims = uint3(tint_symbol_3.get_width(1), tint_symbol_3.get_height(1), tint_symbol_3.get_depth(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint3 fdims = uint3(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx), tint_symbol_1.get_depth(level_idx));
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  uint3 idims = uint3(tint_symbol_2.get_width(level_idx_1), tint_symbol_2.get_height(level_idx_1), tint_symbol_2.get_depth(level_idx_1));
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
+  uint3 udims = uint3(tint_symbol_3.get_width(level_idx_2), tint_symbol_3.get_height(level_idx_2), tint_symbol_3.get_depth(level_idx_2));
   return;
 }
 
diff --git a/test/tint/types/texture/sampled/3d.wgsl.expected.spvasm b/test/tint/types/texture/sampled/3d.wgsl.expected.spvasm
index 5d9cf5b..b24a53f 100644
--- a/test/tint/types/texture/sampled/3d.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/3d.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,8 +36,9 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
 %_ptr_Function_v3uint = OpTypePointer Function %v3uint
        %main = OpFunction %void None %15
          %16 = OpLabel
@@ -44,13 +46,25 @@
       %idims = OpVariable %_ptr_Function_v3uint Function
       %udims = OpVariable %_ptr_Function_v3uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %v3uint %17 %int_1
-               OpStore %fdims %18
-         %23 = OpLoad %7 %t_i None
-         %24 = OpImageQuerySizeLod %v3uint %23 %int_1
-               OpStore %idims %24
-         %26 = OpLoad %11 %t_u None
-         %27 = OpImageQuerySizeLod %v3uint %26 %int_1
-               OpStore %udims %27
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %v3uint %17 %23
+               OpStore %fdims %25
+         %29 = OpLoad %7 %t_i None
+         %30 = OpImageQueryLevels %uint %29
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %24 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v3uint %29 %33
+               OpStore %idims %34
+         %36 = OpLoad %11 %t_u None
+         %37 = OpImageQueryLevels %uint %36
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpBitcast %uint %int_1
+         %40 = OpExtInst %uint %24 UMin %39 %38
+         %41 = OpImageQuerySizeLod %v3uint %36 %40
+               OpStore %udims %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.glsl b/test/tint/types/texture/sampled/cube.wgsl.expected.glsl
index 2ebef3c..e13147a 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 310 es
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCube t_f;
 uniform highp isamplerCube t_i;
 uniform highp usamplerCube t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 fdims = uvec2(textureSize(t_f, 1));
-  uvec2 idims = uvec2(textureSize(t_i, 1));
-  uvec2 udims = uvec2(textureSize(t_u, 1));
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 fdims = uvec2(textureSize(t_f, int(min(uint(1), v_1))));
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uvec2 idims = uvec2(textureSize(t_i, int(min(uint(1), v_2))));
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uvec2 udims = uvec2(textureSize(t_u, int(min(uint(1), v_3))));
 }
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.dxc.hlsl
index a480066..d1d64c1 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
   uint3 v_1 = (0u).xxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 fdims = v_1.xy;
   uint3 v_2 = (0u).xxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 idims = v_3.xy;
+  uint3 v_4 = (0u).xxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint3 v_5 = (0u).xxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.z - 1u))), v_5.x, v_5.y, v_5.z);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.fxc.hlsl
index a480066..d1d64c1 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint3 v = (0u).xxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z);
   uint3 v_1 = (0u).xxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.z - 1u))), v_1.x, v_1.y, v_1.z);
+  uint2 fdims = v_1.xy;
   uint3 v_2 = (0u).xxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z);
+  uint3 v_3 = (0u).xxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.z - 1u))), v_3.x, v_3.y, v_3.z);
+  uint2 idims = v_3.xy;
+  uint3 v_4 = (0u).xxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z);
+  uint3 v_5 = (0u).xxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.z - 1u))), v_5.x, v_5.y, v_5.z);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.msl
index e98ee0a..fb85c3e 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.ir.msl
@@ -9,10 +9,10 @@
 
 kernel void tint_symbol(texturecube<float, access::sample> t_f [[texture(0)]], texturecube<int, access::sample> t_i [[texture(1)]], texturecube<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 fdims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
-  uint const v_1 = uint(1);
+  uint const v_1 = min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint2 idims = uint2(tint_module_vars.t_i.get_width(v_1), tint_module_vars.t_i.get_height(v_1));
-  uint const v_2 = uint(1);
+  uint const v_2 = min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint2 udims = uint2(tint_module_vars.t_u.get_width(v_2), tint_module_vars.t_u.get_height(v_2));
 }
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.msl b/test/tint/types/texture/sampled/cube.wgsl.expected.msl
index 3b6c618..8641186 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.msl
@@ -2,9 +2,12 @@
 
 using namespace metal;
 kernel void tint_symbol(texturecube<float, access::sample> tint_symbol_1 [[texture(0)]], texturecube<int, access::sample> tint_symbol_2 [[texture(1)]], texturecube<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
-  uint2 fdims = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
-  uint2 idims = uint2(tint_symbol_2.get_width(1), tint_symbol_2.get_height(1));
-  uint2 udims = uint2(tint_symbol_3.get_width(1), tint_symbol_3.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 fdims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  uint2 idims = uint2(tint_symbol_2.get_width(level_idx_1), tint_symbol_2.get_height(level_idx_1));
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
+  uint2 udims = uint2(tint_symbol_3.get_width(level_idx_2), tint_symbol_3.get_height(level_idx_2));
   return;
 }
 
diff --git a/test/tint/types/texture/sampled/cube.wgsl.expected.spvasm b/test/tint/types/texture/sampled/cube.wgsl.expected.spvasm
index e04dac0..932dcef 100644
--- a/test/tint/types/texture/sampled/cube.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/cube.wgsl.expected.spvasm
@@ -1,10 +1,11 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 29
+; Bound: 43
 ; Schema: 0
                OpCapability Shader
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -35,8 +36,9 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
-     %v2uint = OpTypeVector %uint 2
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %15
          %16 = OpLabel
@@ -44,13 +46,25 @@
       %idims = OpVariable %_ptr_Function_v2uint Function
       %udims = OpVariable %_ptr_Function_v2uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %v2uint %17 %int_1
-               OpStore %fdims %18
-         %23 = OpLoad %7 %t_i None
-         %24 = OpImageQuerySizeLod %v2uint %23 %int_1
-               OpStore %idims %24
-         %26 = OpLoad %11 %t_u None
-         %27 = OpImageQuerySizeLod %v2uint %26 %int_1
-               OpStore %udims %27
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %v2uint %17 %23
+               OpStore %fdims %25
+         %29 = OpLoad %7 %t_i None
+         %30 = OpImageQueryLevels %uint %29
+         %31 = OpISub %uint %30 %uint_1
+         %32 = OpBitcast %uint %int_1
+         %33 = OpExtInst %uint %24 UMin %32 %31
+         %34 = OpImageQuerySizeLod %v2uint %29 %33
+               OpStore %idims %34
+         %36 = OpLoad %11 %t_u None
+         %37 = OpImageQueryLevels %uint %36
+         %38 = OpISub %uint %37 %uint_1
+         %39 = OpBitcast %uint %int_1
+         %40 = OpExtInst %uint %24 UMin %39 %38
+         %41 = OpImageQuerySizeLod %v2uint %36 %40
+               OpStore %udims %41
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.glsl b/test/tint/types/texture/sampled/cube_array.wgsl.expected.glsl
index 934b8d2..32a9cf9 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.glsl
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.glsl
@@ -1,11 +1,25 @@
 #version 460
 
+
+struct TintTextureUniformData {
+  uint tint_builtin_value_0;
+  uint tint_builtin_value_1;
+  uint tint_builtin_value_2;
+};
+
+layout(binding = 0, std140)
+uniform tint_symbol_1_1_ubo {
+  TintTextureUniformData inner;
+} v;
 uniform highp samplerCubeArray t_f;
 uniform highp isamplerCubeArray t_i;
 uniform highp usamplerCubeArray t_u;
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
-  uvec2 fdims = uvec2(textureSize(t_f, 1).xy);
-  uvec2 idims = uvec2(textureSize(t_i, 1).xy);
-  uvec2 udims = uvec2(textureSize(t_u, 1).xy);
+  uint v_1 = (v.inner.tint_builtin_value_0 - 1u);
+  uvec2 fdims = uvec2(textureSize(t_f, int(min(uint(1), v_1))).xy);
+  uint v_2 = (v.inner.tint_builtin_value_1 - 1u);
+  uvec2 idims = uvec2(textureSize(t_i, int(min(uint(1), v_2))).xy);
+  uint v_3 = (v.inner.tint_builtin_value_2 - 1u);
+  uvec2 udims = uvec2(textureSize(t_u, int(min(uint(1), v_3))).xy);
 }
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.dxc.hlsl b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.dxc.hlsl
index 5fe31ca..646ec33 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.dxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 fdims = v_1.xy;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 idims = v_3.xy;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.fxc.hlsl b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.fxc.hlsl
index 5fe31ca..646ec33 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.fxc.hlsl
@@ -5,13 +5,19 @@
 [numthreads(1, 1, 1)]
 void main() {
   uint4 v = (0u).xxxx;
-  t_f.GetDimensions(uint(int(1)), v.x, v.y, v.z, v.w);
-  uint2 fdims = v.xy;
+  t_f.GetDimensions(0u, v.x, v.y, v.z, v.w);
   uint4 v_1 = (0u).xxxx;
-  t_i.GetDimensions(uint(int(1)), v_1.x, v_1.y, v_1.z, v_1.w);
-  uint2 idims = v_1.xy;
+  t_f.GetDimensions(uint(min(uint(int(1)), (v.w - 1u))), v_1.x, v_1.y, v_1.z, v_1.w);
+  uint2 fdims = v_1.xy;
   uint4 v_2 = (0u).xxxx;
-  t_u.GetDimensions(uint(int(1)), v_2.x, v_2.y, v_2.z, v_2.w);
-  uint2 udims = v_2.xy;
+  t_i.GetDimensions(0u, v_2.x, v_2.y, v_2.z, v_2.w);
+  uint4 v_3 = (0u).xxxx;
+  t_i.GetDimensions(uint(min(uint(int(1)), (v_2.w - 1u))), v_3.x, v_3.y, v_3.z, v_3.w);
+  uint2 idims = v_3.xy;
+  uint4 v_4 = (0u).xxxx;
+  t_u.GetDimensions(0u, v_4.x, v_4.y, v_4.z, v_4.w);
+  uint4 v_5 = (0u).xxxx;
+  t_u.GetDimensions(uint(min(uint(int(1)), (v_4.w - 1u))), v_5.x, v_5.y, v_5.z, v_5.w);
+  uint2 udims = v_5.xy;
 }
 
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.msl b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.msl
index 8dd4951..7cd0274 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.msl
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.ir.msl
@@ -9,10 +9,10 @@
 
 kernel void tint_symbol(texturecube_array<float, access::sample> t_f [[texture(0)]], texturecube_array<int, access::sample> t_i [[texture(1)]], texturecube_array<uint, access::sample> t_u [[texture(2)]]) {
   tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.t_f=t_f, .t_i=t_i, .t_u=t_u};
-  uint const v = uint(1);
+  uint const v = min(uint(1), (tint_module_vars.t_f.get_num_mip_levels() - 1u));
   uint2 fdims = uint2(tint_module_vars.t_f.get_width(v), tint_module_vars.t_f.get_height(v));
-  uint const v_1 = uint(1);
+  uint const v_1 = min(uint(1), (tint_module_vars.t_i.get_num_mip_levels() - 1u));
   uint2 idims = uint2(tint_module_vars.t_i.get_width(v_1), tint_module_vars.t_i.get_height(v_1));
-  uint const v_2 = uint(1);
+  uint const v_2 = min(uint(1), (tint_module_vars.t_u.get_num_mip_levels() - 1u));
   uint2 udims = uint2(tint_module_vars.t_u.get_width(v_2), tint_module_vars.t_u.get_height(v_2));
 }
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.msl b/test/tint/types/texture/sampled/cube_array.wgsl.expected.msl
index a8607d5..233af6b 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.msl
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.msl
@@ -2,9 +2,12 @@
 
 using namespace metal;
 kernel void tint_symbol(texturecube_array<float, access::sample> tint_symbol_1 [[texture(0)]], texturecube_array<int, access::sample> tint_symbol_2 [[texture(1)]], texturecube_array<uint, access::sample> tint_symbol_3 [[texture(2)]]) {
-  uint2 fdims = uint2(tint_symbol_1.get_width(1), tint_symbol_1.get_height(1));
-  uint2 idims = uint2(tint_symbol_2.get_width(1), tint_symbol_2.get_height(1));
-  uint2 udims = uint2(tint_symbol_3.get_width(1), tint_symbol_3.get_height(1));
+  uint const level_idx = min(1u, (tint_symbol_1.get_num_mip_levels() - 1u));
+  uint2 fdims = uint2(tint_symbol_1.get_width(level_idx), tint_symbol_1.get_height(level_idx));
+  uint const level_idx_1 = min(1u, (tint_symbol_2.get_num_mip_levels() - 1u));
+  uint2 idims = uint2(tint_symbol_2.get_width(level_idx_1), tint_symbol_2.get_height(level_idx_1));
+  uint const level_idx_2 = min(1u, (tint_symbol_3.get_num_mip_levels() - 1u));
+  uint2 udims = uint2(tint_symbol_3.get_width(level_idx_2), tint_symbol_3.get_height(level_idx_2));
   return;
 }
 
diff --git a/test/tint/types/texture/sampled/cube_array.wgsl.expected.spvasm b/test/tint/types/texture/sampled/cube_array.wgsl.expected.spvasm
index 322aa27..beac6ee 100644
--- a/test/tint/types/texture/sampled/cube_array.wgsl.expected.spvasm
+++ b/test/tint/types/texture/sampled/cube_array.wgsl.expected.spvasm
@@ -1,11 +1,12 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 33
+; Bound: 47
 ; Schema: 0
                OpCapability Shader
                OpCapability SampledCubeArray
                OpCapability ImageQuery
+         %24 = OpExtInstImport "GLSL.std.450"
                OpMemoryModel Logical GLSL450
                OpEntryPoint GLCompute %main "main"
                OpExecutionMode %main LocalSize 1 1 1
@@ -36,8 +37,9 @@
         %t_u = OpVariable %_ptr_UniformConstant_11 UniformConstant
        %void = OpTypeVoid
          %15 = OpTypeFunction %void
-     %v3uint = OpTypeVector %uint 3
+     %uint_1 = OpConstant %uint 1
       %int_1 = OpConstant %int 1
+     %v3uint = OpTypeVector %uint 3
      %v2uint = OpTypeVector %uint 2
 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
        %main = OpFunction %void None %15
@@ -46,16 +48,28 @@
       %idims = OpVariable %_ptr_Function_v2uint Function
       %udims = OpVariable %_ptr_Function_v2uint Function
          %17 = OpLoad %3 %t_f None
-         %18 = OpImageQuerySizeLod %v3uint %17 %int_1
-         %21 = OpVectorShuffle %v2uint %18 %18 0 1
-               OpStore %fdims %21
-         %25 = OpLoad %7 %t_i None
-         %26 = OpImageQuerySizeLod %v3uint %25 %int_1
-         %27 = OpVectorShuffle %v2uint %26 %26 0 1
-               OpStore %idims %27
-         %29 = OpLoad %11 %t_u None
-         %30 = OpImageQuerySizeLod %v3uint %29 %int_1
-         %31 = OpVectorShuffle %v2uint %30 %30 0 1
-               OpStore %udims %31
+         %18 = OpImageQueryLevels %uint %17
+         %19 = OpISub %uint %18 %uint_1
+         %21 = OpBitcast %uint %int_1
+         %23 = OpExtInst %uint %24 UMin %21 %19
+         %25 = OpImageQuerySizeLod %v3uint %17 %23
+         %27 = OpVectorShuffle %v2uint %25 %25 0 1
+               OpStore %fdims %27
+         %31 = OpLoad %7 %t_i None
+         %32 = OpImageQueryLevels %uint %31
+         %33 = OpISub %uint %32 %uint_1
+         %34 = OpBitcast %uint %int_1
+         %35 = OpExtInst %uint %24 UMin %34 %33
+         %36 = OpImageQuerySizeLod %v3uint %31 %35
+         %37 = OpVectorShuffle %v2uint %36 %36 0 1
+               OpStore %idims %37
+         %39 = OpLoad %11 %t_u None
+         %40 = OpImageQueryLevels %uint %39
+         %41 = OpISub %uint %40 %uint_1
+         %42 = OpBitcast %uint %int_1
+         %43 = OpExtInst %uint %24 UMin %42 %41
+         %44 = OpImageQuerySizeLod %v3uint %39 %43
+         %45 = OpVectorShuffle %v2uint %44 %44 0 1
+               OpStore %udims %45
                OpReturn
                OpFunctionEnd
diff --git a/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.ir.msl b/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.ir.msl
index 02aad41..4d50db2 100644
--- a/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.ir.msl
+++ b/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<tint_array<int, 3>, 2>* zero;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<tint_array<int, 3>, 2> tint_symbol_1;
 };
@@ -26,6 +29,7 @@
     uint v_1 = 0u;
     v_1 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_2 = v_1;
       if ((v_2 >= 6u)) {
         break;
diff --git a/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.msl b/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.msl
index a969ce3..b32f26b 100644
--- a/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.msl
+++ b/test/tint/var/initialization/workgroup/array/array_i32.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<tint_array<int, 3>, 2>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 6u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = (idx / 3u);
     uint const i_1 = (idx % 3u);
     (*(tint_symbol_1))[i][i_1] = 0;
diff --git a/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.ir.msl b/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.ir.msl
index ed037d3..1fc2b21 100644
--- a/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.ir.msl
+++ b/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<int, 3>* zero;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int, 3> tint_symbol_1;
 };
@@ -26,6 +29,7 @@
     uint v_1 = 0u;
     v_1 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_2 = v_1;
       if ((v_2 >= 3u)) {
         break;
diff --git a/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.msl b/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.msl
index 65f938e..f18d653 100644
--- a/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.msl
+++ b/test/tint/var/initialization/workgroup/array/i32.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int, 3>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 3u); idx = (idx + 1u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_1))[i] = 0;
   }
diff --git a/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.ir.msl b/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.ir.msl
index 346fecc..d49d33e 100644
--- a/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.ir.msl
+++ b/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.ir.msl
@@ -17,6 +17,9 @@
   threadgroup tint_array<int, 23>* zero;
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 struct tint_symbol_2 {
   tint_array<int, 23> tint_symbol_1;
 };
@@ -26,6 +29,7 @@
     uint v_1 = 0u;
     v_1 = tint_local_index;
     while(true) {
+      TINT_ISOLATE_UB(tint_volatile_false)
       uint const v_2 = v_1;
       if ((v_2 >= 23u)) {
         break;
diff --git a/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.msl b/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.msl
index 41edfba..60badb1 100644
--- a/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.msl
+++ b/test/tint/var/initialization/workgroup/array/u32_large.wgsl.expected.msl
@@ -14,8 +14,12 @@
     T elements[N];
 };
 
+#define TINT_ISOLATE_UB(VOLATILE_NAME) \
+  {volatile bool VOLATILE_NAME = false; if (VOLATILE_NAME) break;}
+
 void tint_zero_workgroup_memory(uint local_idx, threadgroup tint_array<int, 23>* const tint_symbol_1) {
   for(uint idx = local_idx; (idx < 23u); idx = (idx + 13u)) {
+    TINT_ISOLATE_UB(tint_volatile_false);
     uint const i = idx;
     (*(tint_symbol_1))[i] = 0;
   }
diff --git a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.glsl b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.glsl
index 1e2741f..004540e 100644
--- a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.glsl
+++ b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.glsl
@@ -204,106 +204,106 @@
     m99 = mat2(vec2(0.0f), vec2(0.0f));
   }
   barrier();
-  m00[0][0] = 1.0f;
-  m01[0][0] = 1.0f;
-  m02[0][0] = 1.0f;
-  m03[0][0] = 1.0f;
-  m04[0][0] = 1.0f;
-  m05[0][0] = 1.0f;
-  m06[0][0] = 1.0f;
-  m07[0][0] = 1.0f;
-  m08[0][0] = 1.0f;
-  m09[0][0] = 1.0f;
-  m10[0][0] = 1.0f;
-  m11[0][0] = 1.0f;
-  m12[0][0] = 1.0f;
-  m13[0][0] = 1.0f;
-  m14[0][0] = 1.0f;
-  m15[0][0] = 1.0f;
-  m16[0][0] = 1.0f;
-  m17[0][0] = 1.0f;
-  m18[0][0] = 1.0f;
-  m19[0][0] = 1.0f;
-  m20[0][0] = 1.0f;
-  m21[0][0] = 1.0f;
-  m22[0][0] = 1.0f;
-  m23[0][0] = 1.0f;
-  m24[0][0] = 1.0f;
-  m25[0][0] = 1.0f;
-  m26[0][0] = 1.0f;
-  m27[0][0] = 1.0f;
-  m28[0][0] = 1.0f;
-  m29[0][0] = 1.0f;
-  m30[0][0] = 1.0f;
-  m31[0][0] = 1.0f;
-  m32[0][0] = 1.0f;
-  m33[0][0] = 1.0f;
-  m34[0][0] = 1.0f;
-  m35[0][0] = 1.0f;
-  m36[0][0] = 1.0f;
-  m37[0][0] = 1.0f;
-  m38[0][0] = 1.0f;
-  m39[0][0] = 1.0f;
-  m40[0][0] = 1.0f;
-  m41[0][0] = 1.0f;
-  m42[0][0] = 1.0f;
-  m43[0][0] = 1.0f;
-  m44[0][0] = 1.0f;
-  m45[0][0] = 1.0f;
-  m46[0][0] = 1.0f;
-  m47[0][0] = 1.0f;
-  m48[0][0] = 1.0f;
-  m49[0][0] = 1.0f;
-  m50[0][0] = 1.0f;
-  m51[0][0] = 1.0f;
-  m52[0][0] = 1.0f;
-  m53[0][0] = 1.0f;
-  m54[0][0] = 1.0f;
-  m55[0][0] = 1.0f;
-  m56[0][0] = 1.0f;
-  m57[0][0] = 1.0f;
-  m58[0][0] = 1.0f;
-  m59[0][0] = 1.0f;
-  m60[0][0] = 1.0f;
-  m61[0][0] = 1.0f;
-  m62[0][0] = 1.0f;
-  m63[0][0] = 1.0f;
-  m64[0][0] = 1.0f;
-  m65[0][0] = 1.0f;
-  m66[0][0] = 1.0f;
-  m67[0][0] = 1.0f;
-  m68[0][0] = 1.0f;
-  m69[0][0] = 1.0f;
-  m70[0][0] = 1.0f;
-  m71[0][0] = 1.0f;
-  m72[0][0] = 1.0f;
-  m73[0][0] = 1.0f;
-  m74[0][0] = 1.0f;
-  m75[0][0] = 1.0f;
-  m76[0][0] = 1.0f;
-  m77[0][0] = 1.0f;
-  m78[0][0] = 1.0f;
-  m79[0][0] = 1.0f;
-  m80[0][0] = 1.0f;
-  m81[0][0] = 1.0f;
-  m82[0][0] = 1.0f;
-  m83[0][0] = 1.0f;
-  m84[0][0] = 1.0f;
-  m85[0][0] = 1.0f;
-  m86[0][0] = 1.0f;
-  m87[0][0] = 1.0f;
-  m88[0][0] = 1.0f;
-  m89[0][0] = 1.0f;
-  m90[0][0] = 1.0f;
-  m91[0][0] = 1.0f;
-  m92[0][0] = 1.0f;
-  m93[0][0] = 1.0f;
-  m94[0][0] = 1.0f;
-  m95[0][0] = 1.0f;
-  m96[0][0] = 1.0f;
-  m97[0][0] = 1.0f;
-  m98[0][0] = 1.0f;
-  m99[0][0] = 1.0f;
+  m00[0u][0u] = 1.0f;
+  m01[0u][0u] = 1.0f;
+  m02[0u][0u] = 1.0f;
+  m03[0u][0u] = 1.0f;
+  m04[0u][0u] = 1.0f;
+  m05[0u][0u] = 1.0f;
+  m06[0u][0u] = 1.0f;
+  m07[0u][0u] = 1.0f;
+  m08[0u][0u] = 1.0f;
+  m09[0u][0u] = 1.0f;
+  m10[0u][0u] = 1.0f;
+  m11[0u][0u] = 1.0f;
+  m12[0u][0u] = 1.0f;
+  m13[0u][0u] = 1.0f;
+  m14[0u][0u] = 1.0f;
+  m15[0u][0u] = 1.0f;
+  m16[0u][0u] = 1.0f;
+  m17[0u][0u] = 1.0f;
+  m18[0u][0u] = 1.0f;
+  m19[0u][0u] = 1.0f;
+  m20[0u][0u] = 1.0f;
+  m21[0u][0u] = 1.0f;
+  m22[0u][0u] = 1.0f;
+  m23[0u][0u] = 1.0f;
+  m24[0u][0u] = 1.0f;
+  m25[0u][0u] = 1.0f;
+  m26[0u][0u] = 1.0f;
+  m27[0u][0u] = 1.0f;
+  m28[0u][0u] = 1.0f;
+  m29[0u][0u] = 1.0f;
+  m30[0u][0u] = 1.0f;
+  m31[0u][0u] = 1.0f;
+  m32[0u][0u] = 1.0f;
+  m33[0u][0u] = 1.0f;
+  m34[0u][0u] = 1.0f;
+  m35[0u][0u] = 1.0f;
+  m36[0u][0u] = 1.0f;
+  m37[0u][0u] = 1.0f;
+  m38[0u][0u] = 1.0f;
+  m39[0u][0u] = 1.0f;
+  m40[0u][0u] = 1.0f;
+  m41[0u][0u] = 1.0f;
+  m42[0u][0u] = 1.0f;
+  m43[0u][0u] = 1.0f;
+  m44[0u][0u] = 1.0f;
+  m45[0u][0u] = 1.0f;
+  m46[0u][0u] = 1.0f;
+  m47[0u][0u] = 1.0f;
+  m48[0u][0u] = 1.0f;
+  m49[0u][0u] = 1.0f;
+  m50[0u][0u] = 1.0f;
+  m51[0u][0u] = 1.0f;
+  m52[0u][0u] = 1.0f;
+  m53[0u][0u] = 1.0f;
+  m54[0u][0u] = 1.0f;
+  m55[0u][0u] = 1.0f;
+  m56[0u][0u] = 1.0f;
+  m57[0u][0u] = 1.0f;
+  m58[0u][0u] = 1.0f;
+  m59[0u][0u] = 1.0f;
+  m60[0u][0u] = 1.0f;
+  m61[0u][0u] = 1.0f;
+  m62[0u][0u] = 1.0f;
+  m63[0u][0u] = 1.0f;
+  m64[0u][0u] = 1.0f;
+  m65[0u][0u] = 1.0f;
+  m66[0u][0u] = 1.0f;
+  m67[0u][0u] = 1.0f;
+  m68[0u][0u] = 1.0f;
+  m69[0u][0u] = 1.0f;
+  m70[0u][0u] = 1.0f;
+  m71[0u][0u] = 1.0f;
+  m72[0u][0u] = 1.0f;
+  m73[0u][0u] = 1.0f;
+  m74[0u][0u] = 1.0f;
+  m75[0u][0u] = 1.0f;
+  m76[0u][0u] = 1.0f;
+  m77[0u][0u] = 1.0f;
+  m78[0u][0u] = 1.0f;
+  m79[0u][0u] = 1.0f;
+  m80[0u][0u] = 1.0f;
+  m81[0u][0u] = 1.0f;
+  m82[0u][0u] = 1.0f;
+  m83[0u][0u] = 1.0f;
+  m84[0u][0u] = 1.0f;
+  m85[0u][0u] = 1.0f;
+  m86[0u][0u] = 1.0f;
+  m87[0u][0u] = 1.0f;
+  m88[0u][0u] = 1.0f;
+  m89[0u][0u] = 1.0f;
+  m90[0u][0u] = 1.0f;
+  m91[0u][0u] = 1.0f;
+  m92[0u][0u] = 1.0f;
+  m93[0u][0u] = 1.0f;
+  m94[0u][0u] = 1.0f;
+  m95[0u][0u] = 1.0f;
+  m96[0u][0u] = 1.0f;
+  m97[0u][0u] = 1.0f;
+  m98[0u][0u] = 1.0f;
+  m99[0u][0u] = 1.0f;
 }
 layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
 void main() {
diff --git a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.dxc.hlsl b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.dxc.hlsl
index 7290271..2163033 100644
--- a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.dxc.hlsl
+++ b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.dxc.hlsl
@@ -207,106 +207,106 @@
     m99 = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  m00[int(0)].x = 1.0f;
-  m01[int(0)].x = 1.0f;
-  m02[int(0)].x = 1.0f;
-  m03[int(0)].x = 1.0f;
-  m04[int(0)].x = 1.0f;
-  m05[int(0)].x = 1.0f;
-  m06[int(0)].x = 1.0f;
-  m07[int(0)].x = 1.0f;
-  m08[int(0)].x = 1.0f;
-  m09[int(0)].x = 1.0f;
-  m10[int(0)].x = 1.0f;
-  m11[int(0)].x = 1.0f;
-  m12[int(0)].x = 1.0f;
-  m13[int(0)].x = 1.0f;
-  m14[int(0)].x = 1.0f;
-  m15[int(0)].x = 1.0f;
-  m16[int(0)].x = 1.0f;
-  m17[int(0)].x = 1.0f;
-  m18[int(0)].x = 1.0f;
-  m19[int(0)].x = 1.0f;
-  m20[int(0)].x = 1.0f;
-  m21[int(0)].x = 1.0f;
-  m22[int(0)].x = 1.0f;
-  m23[int(0)].x = 1.0f;
-  m24[int(0)].x = 1.0f;
-  m25[int(0)].x = 1.0f;
-  m26[int(0)].x = 1.0f;
-  m27[int(0)].x = 1.0f;
-  m28[int(0)].x = 1.0f;
-  m29[int(0)].x = 1.0f;
-  m30[int(0)].x = 1.0f;
-  m31[int(0)].x = 1.0f;
-  m32[int(0)].x = 1.0f;
-  m33[int(0)].x = 1.0f;
-  m34[int(0)].x = 1.0f;
-  m35[int(0)].x = 1.0f;
-  m36[int(0)].x = 1.0f;
-  m37[int(0)].x = 1.0f;
-  m38[int(0)].x = 1.0f;
-  m39[int(0)].x = 1.0f;
-  m40[int(0)].x = 1.0f;
-  m41[int(0)].x = 1.0f;
-  m42[int(0)].x = 1.0f;
-  m43[int(0)].x = 1.0f;
-  m44[int(0)].x = 1.0f;
-  m45[int(0)].x = 1.0f;
-  m46[int(0)].x = 1.0f;
-  m47[int(0)].x = 1.0f;
-  m48[int(0)].x = 1.0f;
-  m49[int(0)].x = 1.0f;
-  m50[int(0)].x = 1.0f;
-  m51[int(0)].x = 1.0f;
-  m52[int(0)].x = 1.0f;
-  m53[int(0)].x = 1.0f;
-  m54[int(0)].x = 1.0f;
-  m55[int(0)].x = 1.0f;
-  m56[int(0)].x = 1.0f;
-  m57[int(0)].x = 1.0f;
-  m58[int(0)].x = 1.0f;
-  m59[int(0)].x = 1.0f;
-  m60[int(0)].x = 1.0f;
-  m61[int(0)].x = 1.0f;
-  m62[int(0)].x = 1.0f;
-  m63[int(0)].x = 1.0f;
-  m64[int(0)].x = 1.0f;
-  m65[int(0)].x = 1.0f;
-  m66[int(0)].x = 1.0f;
-  m67[int(0)].x = 1.0f;
-  m68[int(0)].x = 1.0f;
-  m69[int(0)].x = 1.0f;
-  m70[int(0)].x = 1.0f;
-  m71[int(0)].x = 1.0f;
-  m72[int(0)].x = 1.0f;
-  m73[int(0)].x = 1.0f;
-  m74[int(0)].x = 1.0f;
-  m75[int(0)].x = 1.0f;
-  m76[int(0)].x = 1.0f;
-  m77[int(0)].x = 1.0f;
-  m78[int(0)].x = 1.0f;
-  m79[int(0)].x = 1.0f;
-  m80[int(0)].x = 1.0f;
-  m81[int(0)].x = 1.0f;
-  m82[int(0)].x = 1.0f;
-  m83[int(0)].x = 1.0f;
-  m84[int(0)].x = 1.0f;
-  m85[int(0)].x = 1.0f;
-  m86[int(0)].x = 1.0f;
-  m87[int(0)].x = 1.0f;
-  m88[int(0)].x = 1.0f;
-  m89[int(0)].x = 1.0f;
-  m90[int(0)].x = 1.0f;
-  m91[int(0)].x = 1.0f;
-  m92[int(0)].x = 1.0f;
-  m93[int(0)].x = 1.0f;
-  m94[int(0)].x = 1.0f;
-  m95[int(0)].x = 1.0f;
-  m96[int(0)].x = 1.0f;
-  m97[int(0)].x = 1.0f;
-  m98[int(0)].x = 1.0f;
-  m99[int(0)].x = 1.0f;
+  m00[0u].x = 1.0f;
+  m01[0u].x = 1.0f;
+  m02[0u].x = 1.0f;
+  m03[0u].x = 1.0f;
+  m04[0u].x = 1.0f;
+  m05[0u].x = 1.0f;
+  m06[0u].x = 1.0f;
+  m07[0u].x = 1.0f;
+  m08[0u].x = 1.0f;
+  m09[0u].x = 1.0f;
+  m10[0u].x = 1.0f;
+  m11[0u].x = 1.0f;
+  m12[0u].x = 1.0f;
+  m13[0u].x = 1.0f;
+  m14[0u].x = 1.0f;
+  m15[0u].x = 1.0f;
+  m16[0u].x = 1.0f;
+  m17[0u].x = 1.0f;
+  m18[0u].x = 1.0f;
+  m19[0u].x = 1.0f;
+  m20[0u].x = 1.0f;
+  m21[0u].x = 1.0f;
+  m22[0u].x = 1.0f;
+  m23[0u].x = 1.0f;
+  m24[0u].x = 1.0f;
+  m25[0u].x = 1.0f;
+  m26[0u].x = 1.0f;
+  m27[0u].x = 1.0f;
+  m28[0u].x = 1.0f;
+  m29[0u].x = 1.0f;
+  m30[0u].x = 1.0f;
+  m31[0u].x = 1.0f;
+  m32[0u].x = 1.0f;
+  m33[0u].x = 1.0f;
+  m34[0u].x = 1.0f;
+  m35[0u].x = 1.0f;
+  m36[0u].x = 1.0f;
+  m37[0u].x = 1.0f;
+  m38[0u].x = 1.0f;
+  m39[0u].x = 1.0f;
+  m40[0u].x = 1.0f;
+  m41[0u].x = 1.0f;
+  m42[0u].x = 1.0f;
+  m43[0u].x = 1.0f;
+  m44[0u].x = 1.0f;
+  m45[0u].x = 1.0f;
+  m46[0u].x = 1.0f;
+  m47[0u].x = 1.0f;
+  m48[0u].x = 1.0f;
+  m49[0u].x = 1.0f;
+  m50[0u].x = 1.0f;
+  m51[0u].x = 1.0f;
+  m52[0u].x = 1.0f;
+  m53[0u].x = 1.0f;
+  m54[0u].x = 1.0f;
+  m55[0u].x = 1.0f;
+  m56[0u].x = 1.0f;
+  m57[0u].x = 1.0f;
+  m58[0u].x = 1.0f;
+  m59[0u].x = 1.0f;
+  m60[0u].x = 1.0f;
+  m61[0u].x = 1.0f;
+  m62[0u].x = 1.0f;
+  m63[0u].x = 1.0f;
+  m64[0u].x = 1.0f;
+  m65[0u].x = 1.0f;
+  m66[0u].x = 1.0f;
+  m67[0u].x = 1.0f;
+  m68[0u].x = 1.0f;
+  m69[0u].x = 1.0f;
+  m70[0u].x = 1.0f;
+  m71[0u].x = 1.0f;
+  m72[0u].x = 1.0f;
+  m73[0u].x = 1.0f;
+  m74[0u].x = 1.0f;
+  m75[0u].x = 1.0f;
+  m76[0u].x = 1.0f;
+  m77[0u].x = 1.0f;
+  m78[0u].x = 1.0f;
+  m79[0u].x = 1.0f;
+  m80[0u].x = 1.0f;
+  m81[0u].x = 1.0f;
+  m82[0u].x = 1.0f;
+  m83[0u].x = 1.0f;
+  m84[0u].x = 1.0f;
+  m85[0u].x = 1.0f;
+  m86[0u].x = 1.0f;
+  m87[0u].x = 1.0f;
+  m88[0u].x = 1.0f;
+  m89[0u].x = 1.0f;
+  m90[0u].x = 1.0f;
+  m91[0u].x = 1.0f;
+  m92[0u].x = 1.0f;
+  m93[0u].x = 1.0f;
+  m94[0u].x = 1.0f;
+  m95[0u].x = 1.0f;
+  m96[0u].x = 1.0f;
+  m97[0u].x = 1.0f;
+  m98[0u].x = 1.0f;
+  m99[0u].x = 1.0f;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.fxc.hlsl b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.fxc.hlsl
index 7290271..2163033 100644
--- a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.fxc.hlsl
+++ b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.fxc.hlsl
@@ -207,106 +207,106 @@
     m99 = float2x2((0.0f).xx, (0.0f).xx);
   }
   GroupMemoryBarrierWithGroupSync();
-  m00[int(0)].x = 1.0f;
-  m01[int(0)].x = 1.0f;
-  m02[int(0)].x = 1.0f;
-  m03[int(0)].x = 1.0f;
-  m04[int(0)].x = 1.0f;
-  m05[int(0)].x = 1.0f;
-  m06[int(0)].x = 1.0f;
-  m07[int(0)].x = 1.0f;
-  m08[int(0)].x = 1.0f;
-  m09[int(0)].x = 1.0f;
-  m10[int(0)].x = 1.0f;
-  m11[int(0)].x = 1.0f;
-  m12[int(0)].x = 1.0f;
-  m13[int(0)].x = 1.0f;
-  m14[int(0)].x = 1.0f;
-  m15[int(0)].x = 1.0f;
-  m16[int(0)].x = 1.0f;
-  m17[int(0)].x = 1.0f;
-  m18[int(0)].x = 1.0f;
-  m19[int(0)].x = 1.0f;
-  m20[int(0)].x = 1.0f;
-  m21[int(0)].x = 1.0f;
-  m22[int(0)].x = 1.0f;
-  m23[int(0)].x = 1.0f;
-  m24[int(0)].x = 1.0f;
-  m25[int(0)].x = 1.0f;
-  m26[int(0)].x = 1.0f;
-  m27[int(0)].x = 1.0f;
-  m28[int(0)].x = 1.0f;
-  m29[int(0)].x = 1.0f;
-  m30[int(0)].x = 1.0f;
-  m31[int(0)].x = 1.0f;
-  m32[int(0)].x = 1.0f;
-  m33[int(0)].x = 1.0f;
-  m34[int(0)].x = 1.0f;
-  m35[int(0)].x = 1.0f;
-  m36[int(0)].x = 1.0f;
-  m37[int(0)].x = 1.0f;
-  m38[int(0)].x = 1.0f;
-  m39[int(0)].x = 1.0f;
-  m40[int(0)].x = 1.0f;
-  m41[int(0)].x = 1.0f;
-  m42[int(0)].x = 1.0f;
-  m43[int(0)].x = 1.0f;
-  m44[int(0)].x = 1.0f;
-  m45[int(0)].x = 1.0f;
-  m46[int(0)].x = 1.0f;
-  m47[int(0)].x = 1.0f;
-  m48[int(0)].x = 1.0f;
-  m49[int(0)].x = 1.0f;
-  m50[int(0)].x = 1.0f;
-  m51[int(0)].x = 1.0f;
-  m52[int(0)].x = 1.0f;
-  m53[int(0)].x = 1.0f;
-  m54[int(0)].x = 1.0f;
-  m55[int(0)].x = 1.0f;
-  m56[int(0)].x = 1.0f;
-  m57[int(0)].x = 1.0f;
-  m58[int(0)].x = 1.0f;
-  m59[int(0)].x = 1.0f;
-  m60[int(0)].x = 1.0f;
-  m61[int(0)].x = 1.0f;
-  m62[int(0)].x = 1.0f;
-  m63[int(0)].x = 1.0f;
-  m64[int(0)].x = 1.0f;
-  m65[int(0)].x = 1.0f;
-  m66[int(0)].x = 1.0f;
-  m67[int(0)].x = 1.0f;
-  m68[int(0)].x = 1.0f;
-  m69[int(0)].x = 1.0f;
-  m70[int(0)].x = 1.0f;
-  m71[int(0)].x = 1.0f;
-  m72[int(0)].x = 1.0f;
-  m73[int(0)].x = 1.0f;
-  m74[int(0)].x = 1.0f;
-  m75[int(0)].x = 1.0f;
-  m76[int(0)].x = 1.0f;
-  m77[int(0)].x = 1.0f;
-  m78[int(0)].x = 1.0f;
-  m79[int(0)].x = 1.0f;
-  m80[int(0)].x = 1.0f;
-  m81[int(0)].x = 1.0f;
-  m82[int(0)].x = 1.0f;
-  m83[int(0)].x = 1.0f;
-  m84[int(0)].x = 1.0f;
-  m85[int(0)].x = 1.0f;
-  m86[int(0)].x = 1.0f;
-  m87[int(0)].x = 1.0f;
-  m88[int(0)].x = 1.0f;
-  m89[int(0)].x = 1.0f;
-  m90[int(0)].x = 1.0f;
-  m91[int(0)].x = 1.0f;
-  m92[int(0)].x = 1.0f;
-  m93[int(0)].x = 1.0f;
-  m94[int(0)].x = 1.0f;
-  m95[int(0)].x = 1.0f;
-  m96[int(0)].x = 1.0f;
-  m97[int(0)].x = 1.0f;
-  m98[int(0)].x = 1.0f;
-  m99[int(0)].x = 1.0f;
+  m00[0u].x = 1.0f;
+  m01[0u].x = 1.0f;
+  m02[0u].x = 1.0f;
+  m03[0u].x = 1.0f;
+  m04[0u].x = 1.0f;
+  m05[0u].x = 1.0f;
+  m06[0u].x = 1.0f;
+  m07[0u].x = 1.0f;
+  m08[0u].x = 1.0f;
+  m09[0u].x = 1.0f;
+  m10[0u].x = 1.0f;
+  m11[0u].x = 1.0f;
+  m12[0u].x = 1.0f;
+  m13[0u].x = 1.0f;
+  m14[0u].x = 1.0f;
+  m15[0u].x = 1.0f;
+  m16[0u].x = 1.0f;
+  m17[0u].x = 1.0f;
+  m18[0u].x = 1.0f;
+  m19[0u].x = 1.0f;
+  m20[0u].x = 1.0f;
+  m21[0u].x = 1.0f;
+  m22[0u].x = 1.0f;
+  m23[0u].x = 1.0f;
+  m24[0u].x = 1.0f;
+  m25[0u].x = 1.0f;
+  m26[0u].x = 1.0f;
+  m27[0u].x = 1.0f;
+  m28[0u].x = 1.0f;
+  m29[0u].x = 1.0f;
+  m30[0u].x = 1.0f;
+  m31[0u].x = 1.0f;
+  m32[0u].x = 1.0f;
+  m33[0u].x = 1.0f;
+  m34[0u].x = 1.0f;
+  m35[0u].x = 1.0f;
+  m36[0u].x = 1.0f;
+  m37[0u].x = 1.0f;
+  m38[0u].x = 1.0f;
+  m39[0u].x = 1.0f;
+  m40[0u].x = 1.0f;
+  m41[0u].x = 1.0f;
+  m42[0u].x = 1.0f;
+  m43[0u].x = 1.0f;
+  m44[0u].x = 1.0f;
+  m45[0u].x = 1.0f;
+  m46[0u].x = 1.0f;
+  m47[0u].x = 1.0f;
+  m48[0u].x = 1.0f;
+  m49[0u].x = 1.0f;
+  m50[0u].x = 1.0f;
+  m51[0u].x = 1.0f;
+  m52[0u].x = 1.0f;
+  m53[0u].x = 1.0f;
+  m54[0u].x = 1.0f;
+  m55[0u].x = 1.0f;
+  m56[0u].x = 1.0f;
+  m57[0u].x = 1.0f;
+  m58[0u].x = 1.0f;
+  m59[0u].x = 1.0f;
+  m60[0u].x = 1.0f;
+  m61[0u].x = 1.0f;
+  m62[0u].x = 1.0f;
+  m63[0u].x = 1.0f;
+  m64[0u].x = 1.0f;
+  m65[0u].x = 1.0f;
+  m66[0u].x = 1.0f;
+  m67[0u].x = 1.0f;
+  m68[0u].x = 1.0f;
+  m69[0u].x = 1.0f;
+  m70[0u].x = 1.0f;
+  m71[0u].x = 1.0f;
+  m72[0u].x = 1.0f;
+  m73[0u].x = 1.0f;
+  m74[0u].x = 1.0f;
+  m75[0u].x = 1.0f;
+  m76[0u].x = 1.0f;
+  m77[0u].x = 1.0f;
+  m78[0u].x = 1.0f;
+  m79[0u].x = 1.0f;
+  m80[0u].x = 1.0f;
+  m81[0u].x = 1.0f;
+  m82[0u].x = 1.0f;
+  m83[0u].x = 1.0f;
+  m84[0u].x = 1.0f;
+  m85[0u].x = 1.0f;
+  m86[0u].x = 1.0f;
+  m87[0u].x = 1.0f;
+  m88[0u].x = 1.0f;
+  m89[0u].x = 1.0f;
+  m90[0u].x = 1.0f;
+  m91[0u].x = 1.0f;
+  m92[0u].x = 1.0f;
+  m93[0u].x = 1.0f;
+  m94[0u].x = 1.0f;
+  m95[0u].x = 1.0f;
+  m96[0u].x = 1.0f;
+  m97[0u].x = 1.0f;
+  m98[0u].x = 1.0f;
+  m99[0u].x = 1.0f;
 }
 
 [numthreads(1, 1, 1)]
diff --git a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.msl b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.msl
index b169a22..0f6f0a0 100644
--- a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.msl
+++ b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.ir.msl
@@ -311,106 +311,106 @@
     (*tint_module_vars.m99) = float2x2(float2(0.0f), float2(0.0f));
   }
   threadgroup_barrier(mem_flags::mem_threadgroup);
-  (*tint_module_vars.m00)[0][0] = 1.0f;
-  (*tint_module_vars.m01)[0][0] = 1.0f;
-  (*tint_module_vars.m02)[0][0] = 1.0f;
-  (*tint_module_vars.m03)[0][0] = 1.0f;
-  (*tint_module_vars.m04)[0][0] = 1.0f;
-  (*tint_module_vars.m05)[0][0] = 1.0f;
-  (*tint_module_vars.m06)[0][0] = 1.0f;
-  (*tint_module_vars.m07)[0][0] = 1.0f;
-  (*tint_module_vars.m08)[0][0] = 1.0f;
-  (*tint_module_vars.m09)[0][0] = 1.0f;
-  (*tint_module_vars.m10)[0][0] = 1.0f;
-  (*tint_module_vars.m11)[0][0] = 1.0f;
-  (*tint_module_vars.m12)[0][0] = 1.0f;
-  (*tint_module_vars.m13)[0][0] = 1.0f;
-  (*tint_module_vars.m14)[0][0] = 1.0f;
-  (*tint_module_vars.m15)[0][0] = 1.0f;
-  (*tint_module_vars.m16)[0][0] = 1.0f;
-  (*tint_module_vars.m17)[0][0] = 1.0f;
-  (*tint_module_vars.m18)[0][0] = 1.0f;
-  (*tint_module_vars.m19)[0][0] = 1.0f;
-  (*tint_module_vars.m20)[0][0] = 1.0f;
-  (*tint_module_vars.m21)[0][0] = 1.0f;
-  (*tint_module_vars.m22)[0][0] = 1.0f;
-  (*tint_module_vars.m23)[0][0] = 1.0f;
-  (*tint_module_vars.m24)[0][0] = 1.0f;
-  (*tint_module_vars.m25)[0][0] = 1.0f;
-  (*tint_module_vars.m26)[0][0] = 1.0f;
-  (*tint_module_vars.m27)[0][0] = 1.0f;
-  (*tint_module_vars.m28)[0][0] = 1.0f;
-  (*tint_module_vars.m29)[0][0] = 1.0f;
-  (*tint_module_vars.m30)[0][0] = 1.0f;
-  (*tint_module_vars.m31)[0][0] = 1.0f;
-  (*tint_module_vars.m32)[0][0] = 1.0f;
-  (*tint_module_vars.m33)[0][0] = 1.0f;
-  (*tint_module_vars.m34)[0][0] = 1.0f;
-  (*tint_module_vars.m35)[0][0] = 1.0f;
-  (*tint_module_vars.m36)[0][0] = 1.0f;
-  (*tint_module_vars.m37)[0][0] = 1.0f;
-  (*tint_module_vars.m38)[0][0] = 1.0f;
-  (*tint_module_vars.m39)[0][0] = 1.0f;
-  (*tint_module_vars.m40)[0][0] = 1.0f;
-  (*tint_module_vars.m41)[0][0] = 1.0f;
-  (*tint_module_vars.m42)[0][0] = 1.0f;
-  (*tint_module_vars.m43)[0][0] = 1.0f;
-  (*tint_module_vars.m44)[0][0] = 1.0f;
-  (*tint_module_vars.m45)[0][0] = 1.0f;
-  (*tint_module_vars.m46)[0][0] = 1.0f;
-  (*tint_module_vars.m47)[0][0] = 1.0f;
-  (*tint_module_vars.m48)[0][0] = 1.0f;
-  (*tint_module_vars.m49)[0][0] = 1.0f;
-  (*tint_module_vars.m50)[0][0] = 1.0f;
-  (*tint_module_vars.m51)[0][0] = 1.0f;
-  (*tint_module_vars.m52)[0][0] = 1.0f;
-  (*tint_module_vars.m53)[0][0] = 1.0f;
-  (*tint_module_vars.m54)[0][0] = 1.0f;
-  (*tint_module_vars.m55)[0][0] = 1.0f;
-  (*tint_module_vars.m56)[0][0] = 1.0f;
-  (*tint_module_vars.m57)[0][0] = 1.0f;
-  (*tint_module_vars.m58)[0][0] = 1.0f;
-  (*tint_module_vars.m59)[0][0] = 1.0f;
-  (*tint_module_vars.m60)[0][0] = 1.0f;
-  (*tint_module_vars.m61)[0][0] = 1.0f;
-  (*tint_module_vars.m62)[0][0] = 1.0f;
-  (*tint_module_vars.m63)[0][0] = 1.0f;
-  (*tint_module_vars.m64)[0][0] = 1.0f;
-  (*tint_module_vars.m65)[0][0] = 1.0f;
-  (*tint_module_vars.m66)[0][0] = 1.0f;
-  (*tint_module_vars.m67)[0][0] = 1.0f;
-  (*tint_module_vars.m68)[0][0] = 1.0f;
-  (*tint_module_vars.m69)[0][0] = 1.0f;
-  (*tint_module_vars.m70)[0][0] = 1.0f;
-  (*tint_module_vars.m71)[0][0] = 1.0f;
-  (*tint_module_vars.m72)[0][0] = 1.0f;
-  (*tint_module_vars.m73)[0][0] = 1.0f;
-  (*tint_module_vars.m74)[0][0] = 1.0f;
-  (*tint_module_vars.m75)[0][0] = 1.0f;
-  (*tint_module_vars.m76)[0][0] = 1.0f;
-  (*tint_module_vars.m77)[0][0] = 1.0f;
-  (*tint_module_vars.m78)[0][0] = 1.0f;
-  (*tint_module_vars.m79)[0][0] = 1.0f;
-  (*tint_module_vars.m80)[0][0] = 1.0f;
-  (*tint_module_vars.m81)[0][0] = 1.0f;
-  (*tint_module_vars.m82)[0][0] = 1.0f;
-  (*tint_module_vars.m83)[0][0] = 1.0f;
-  (*tint_module_vars.m84)[0][0] = 1.0f;
-  (*tint_module_vars.m85)[0][0] = 1.0f;
-  (*tint_module_vars.m86)[0][0] = 1.0f;
-  (*tint_module_vars.m87)[0][0] = 1.0f;
-  (*tint_module_vars.m88)[0][0] = 1.0f;
-  (*tint_module_vars.m89)[0][0] = 1.0f;
-  (*tint_module_vars.m90)[0][0] = 1.0f;
-  (*tint_module_vars.m91)[0][0] = 1.0f;
-  (*tint_module_vars.m92)[0][0] = 1.0f;
-  (*tint_module_vars.m93)[0][0] = 1.0f;
-  (*tint_module_vars.m94)[0][0] = 1.0f;
-  (*tint_module_vars.m95)[0][0] = 1.0f;
-  (*tint_module_vars.m96)[0][0] = 1.0f;
-  (*tint_module_vars.m97)[0][0] = 1.0f;
-  (*tint_module_vars.m98)[0][0] = 1.0f;
-  (*tint_module_vars.m99)[0][0] = 1.0f;
+  (*tint_module_vars.m00)[0u][0u] = 1.0f;
+  (*tint_module_vars.m01)[0u][0u] = 1.0f;
+  (*tint_module_vars.m02)[0u][0u] = 1.0f;
+  (*tint_module_vars.m03)[0u][0u] = 1.0f;
+  (*tint_module_vars.m04)[0u][0u] = 1.0f;
+  (*tint_module_vars.m05)[0u][0u] = 1.0f;
+  (*tint_module_vars.m06)[0u][0u] = 1.0f;
+  (*tint_module_vars.m07)[0u][0u] = 1.0f;
+  (*tint_module_vars.m08)[0u][0u] = 1.0f;
+  (*tint_module_vars.m09)[0u][0u] = 1.0f;
+  (*tint_module_vars.m10)[0u][0u] = 1.0f;
+  (*tint_module_vars.m11)[0u][0u] = 1.0f;
+  (*tint_module_vars.m12)[0u][0u] = 1.0f;
+  (*tint_module_vars.m13)[0u][0u] = 1.0f;
+  (*tint_module_vars.m14)[0u][0u] = 1.0f;
+  (*tint_module_vars.m15)[0u][0u] = 1.0f;
+  (*tint_module_vars.m16)[0u][0u] = 1.0f;
+  (*tint_module_vars.m17)[0u][0u] = 1.0f;
+  (*tint_module_vars.m18)[0u][0u] = 1.0f;
+  (*tint_module_vars.m19)[0u][0u] = 1.0f;
+  (*tint_module_vars.m20)[0u][0u] = 1.0f;
+  (*tint_module_vars.m21)[0u][0u] = 1.0f;
+  (*tint_module_vars.m22)[0u][0u] = 1.0f;
+  (*tint_module_vars.m23)[0u][0u] = 1.0f;
+  (*tint_module_vars.m24)[0u][0u] = 1.0f;
+  (*tint_module_vars.m25)[0u][0u] = 1.0f;
+  (*tint_module_vars.m26)[0u][0u] = 1.0f;
+  (*tint_module_vars.m27)[0u][0u] = 1.0f;
+  (*tint_module_vars.m28)[0u][0u] = 1.0f;
+  (*tint_module_vars.m29)[0u][0u] = 1.0f;
+  (*tint_module_vars.m30)[0u][0u] = 1.0f;
+  (*tint_module_vars.m31)[0u][0u] = 1.0f;
+  (*tint_module_vars.m32)[0u][0u] = 1.0f;
+  (*tint_module_vars.m33)[0u][0u] = 1.0f;
+  (*tint_module_vars.m34)[0u][0u] = 1.0f;
+  (*tint_module_vars.m35)[0u][0u] = 1.0f;
+  (*tint_module_vars.m36)[0u][0u] = 1.0f;
+  (*tint_module_vars.m37)[0u][0u] = 1.0f;
+  (*tint_module_vars.m38)[0u][0u] = 1.0f;
+  (*tint_module_vars.m39)[0u][0u] = 1.0f;
+  (*tint_module_vars.m40)[0u][0u] = 1.0f;
+  (*tint_module_vars.m41)[0u][0u] = 1.0f;
+  (*tint_module_vars.m42)[0u][0u] = 1.0f;
+  (*tint_module_vars.m43)[0u][0u] = 1.0f;
+  (*tint_module_vars.m44)[0u][0u] = 1.0f;
+  (*tint_module_vars.m45)[0u][0u] = 1.0f;
+  (*tint_module_vars.m46)[0u][0u] = 1.0f;
+  (*tint_module_vars.m47)[0u][0u] = 1.0f;
+  (*tint_module_vars.m48)[0u][0u] = 1.0f;
+  (*tint_module_vars.m49)[0u][0u] = 1.0f;
+  (*tint_module_vars.m50)[0u][0u] = 1.0f;
+  (*tint_module_vars.m51)[0u][0u] = 1.0f;
+  (*tint_module_vars.m52)[0u][0u] = 1.0f;
+  (*tint_module_vars.m53)[0u][0u] = 1.0f;
+  (*tint_module_vars.m54)[0u][0u] = 1.0f;
+  (*tint_module_vars.m55)[0u][0u] = 1.0f;
+  (*tint_module_vars.m56)[0u][0u] = 1.0f;
+  (*tint_module_vars.m57)[0u][0u] = 1.0f;
+  (*tint_module_vars.m58)[0u][0u] = 1.0f;
+  (*tint_module_vars.m59)[0u][0u] = 1.0f;
+  (*tint_module_vars.m60)[0u][0u] = 1.0f;
+  (*tint_module_vars.m61)[0u][0u] = 1.0f;
+  (*tint_module_vars.m62)[0u][0u] = 1.0f;
+  (*tint_module_vars.m63)[0u][0u] = 1.0f;
+  (*tint_module_vars.m64)[0u][0u] = 1.0f;
+  (*tint_module_vars.m65)[0u][0u] = 1.0f;
+  (*tint_module_vars.m66)[0u][0u] = 1.0f;
+  (*tint_module_vars.m67)[0u][0u] = 1.0f;
+  (*tint_module_vars.m68)[0u][0u] = 1.0f;
+  (*tint_module_vars.m69)[0u][0u] = 1.0f;
+  (*tint_module_vars.m70)[0u][0u] = 1.0f;
+  (*tint_module_vars.m71)[0u][0u] = 1.0f;
+  (*tint_module_vars.m72)[0u][0u] = 1.0f;
+  (*tint_module_vars.m73)[0u][0u] = 1.0f;
+  (*tint_module_vars.m74)[0u][0u] = 1.0f;
+  (*tint_module_vars.m75)[0u][0u] = 1.0f;
+  (*tint_module_vars.m76)[0u][0u] = 1.0f;
+  (*tint_module_vars.m77)[0u][0u] = 1.0f;
+  (*tint_module_vars.m78)[0u][0u] = 1.0f;
+  (*tint_module_vars.m79)[0u][0u] = 1.0f;
+  (*tint_module_vars.m80)[0u][0u] = 1.0f;
+  (*tint_module_vars.m81)[0u][0u] = 1.0f;
+  (*tint_module_vars.m82)[0u][0u] = 1.0f;
+  (*tint_module_vars.m83)[0u][0u] = 1.0f;
+  (*tint_module_vars.m84)[0u][0u] = 1.0f;
+  (*tint_module_vars.m85)[0u][0u] = 1.0f;
+  (*tint_module_vars.m86)[0u][0u] = 1.0f;
+  (*tint_module_vars.m87)[0u][0u] = 1.0f;
+  (*tint_module_vars.m88)[0u][0u] = 1.0f;
+  (*tint_module_vars.m89)[0u][0u] = 1.0f;
+  (*tint_module_vars.m90)[0u][0u] = 1.0f;
+  (*tint_module_vars.m91)[0u][0u] = 1.0f;
+  (*tint_module_vars.m92)[0u][0u] = 1.0f;
+  (*tint_module_vars.m93)[0u][0u] = 1.0f;
+  (*tint_module_vars.m94)[0u][0u] = 1.0f;
+  (*tint_module_vars.m95)[0u][0u] = 1.0f;
+  (*tint_module_vars.m96)[0u][0u] = 1.0f;
+  (*tint_module_vars.m97)[0u][0u] = 1.0f;
+  (*tint_module_vars.m98)[0u][0u] = 1.0f;
+  (*tint_module_vars.m99)[0u][0u] = 1.0f;
 }
 
 kernel void tint_symbol(uint idx [[thread_index_in_threadgroup]], threadgroup tint_symbol_101* v [[threadgroup(0)]]) {
diff --git a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.spvasm b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.spvasm
index 79251bd..3276b4b 100644
--- a/test/tint/var/uses/many_workgroup_vars.wgsl.expected.spvasm
+++ b/test/tint/var/uses/many_workgroup_vars.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 1
-; Bound: 332
+; Bound: 331
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -227,11 +227,10 @@
      %uint_2 = OpConstant %uint 2
    %uint_264 = OpConstant %uint 264
 %_ptr_Workgroup_v2float = OpTypePointer Workgroup %v2float
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
+     %uint_0 = OpConstant %uint 0
 %_ptr_Workgroup_float = OpTypePointer Workgroup %float
     %float_1 = OpConstant %float 1
-        %328 = OpTypeFunction %void
+        %327 = OpTypeFunction %void
 %tint_symbol_inner = OpFunction %void None %111
         %idx = OpFunctionParameter %uint
         %112 = OpLabel
@@ -342,311 +341,311 @@
                OpBranch %116
         %116 = OpLabel
                OpControlBarrier %uint_2 %uint_2 %uint_264
-        %122 = OpAccessChain %_ptr_Workgroup_v2float %m00 %int_0
-        %126 = OpAccessChain %_ptr_Workgroup_float %122 %int_0
-               OpStore %126 %float_1 None
-        %129 = OpAccessChain %_ptr_Workgroup_v2float %m01 %int_0
-        %130 = OpAccessChain %_ptr_Workgroup_float %129 %int_0
-               OpStore %130 %float_1 None
-        %131 = OpAccessChain %_ptr_Workgroup_v2float %m02 %int_0
-        %132 = OpAccessChain %_ptr_Workgroup_float %131 %int_0
-               OpStore %132 %float_1 None
-        %133 = OpAccessChain %_ptr_Workgroup_v2float %m03 %int_0
-        %134 = OpAccessChain %_ptr_Workgroup_float %133 %int_0
-               OpStore %134 %float_1 None
-        %135 = OpAccessChain %_ptr_Workgroup_v2float %m04 %int_0
-        %136 = OpAccessChain %_ptr_Workgroup_float %135 %int_0
-               OpStore %136 %float_1 None
-        %137 = OpAccessChain %_ptr_Workgroup_v2float %m05 %int_0
-        %138 = OpAccessChain %_ptr_Workgroup_float %137 %int_0
-               OpStore %138 %float_1 None
-        %139 = OpAccessChain %_ptr_Workgroup_v2float %m06 %int_0
-        %140 = OpAccessChain %_ptr_Workgroup_float %139 %int_0
-               OpStore %140 %float_1 None
-        %141 = OpAccessChain %_ptr_Workgroup_v2float %m07 %int_0
-        %142 = OpAccessChain %_ptr_Workgroup_float %141 %int_0
-               OpStore %142 %float_1 None
-        %143 = OpAccessChain %_ptr_Workgroup_v2float %m08 %int_0
-        %144 = OpAccessChain %_ptr_Workgroup_float %143 %int_0
-               OpStore %144 %float_1 None
-        %145 = OpAccessChain %_ptr_Workgroup_v2float %m09 %int_0
-        %146 = OpAccessChain %_ptr_Workgroup_float %145 %int_0
-               OpStore %146 %float_1 None
-        %147 = OpAccessChain %_ptr_Workgroup_v2float %m10 %int_0
-        %148 = OpAccessChain %_ptr_Workgroup_float %147 %int_0
-               OpStore %148 %float_1 None
-        %149 = OpAccessChain %_ptr_Workgroup_v2float %m11 %int_0
-        %150 = OpAccessChain %_ptr_Workgroup_float %149 %int_0
-               OpStore %150 %float_1 None
-        %151 = OpAccessChain %_ptr_Workgroup_v2float %m12 %int_0
-        %152 = OpAccessChain %_ptr_Workgroup_float %151 %int_0
-               OpStore %152 %float_1 None
-        %153 = OpAccessChain %_ptr_Workgroup_v2float %m13 %int_0
-        %154 = OpAccessChain %_ptr_Workgroup_float %153 %int_0
-               OpStore %154 %float_1 None
-        %155 = OpAccessChain %_ptr_Workgroup_v2float %m14 %int_0
-        %156 = OpAccessChain %_ptr_Workgroup_float %155 %int_0
-               OpStore %156 %float_1 None
-        %157 = OpAccessChain %_ptr_Workgroup_v2float %m15 %int_0
-        %158 = OpAccessChain %_ptr_Workgroup_float %157 %int_0
-               OpStore %158 %float_1 None
-        %159 = OpAccessChain %_ptr_Workgroup_v2float %m16 %int_0
-        %160 = OpAccessChain %_ptr_Workgroup_float %159 %int_0
-               OpStore %160 %float_1 None
-        %161 = OpAccessChain %_ptr_Workgroup_v2float %m17 %int_0
-        %162 = OpAccessChain %_ptr_Workgroup_float %161 %int_0
-               OpStore %162 %float_1 None
-        %163 = OpAccessChain %_ptr_Workgroup_v2float %m18 %int_0
-        %164 = OpAccessChain %_ptr_Workgroup_float %163 %int_0
-               OpStore %164 %float_1 None
-        %165 = OpAccessChain %_ptr_Workgroup_v2float %m19 %int_0
-        %166 = OpAccessChain %_ptr_Workgroup_float %165 %int_0
-               OpStore %166 %float_1 None
-        %167 = OpAccessChain %_ptr_Workgroup_v2float %m20 %int_0
-        %168 = OpAccessChain %_ptr_Workgroup_float %167 %int_0
-               OpStore %168 %float_1 None
-        %169 = OpAccessChain %_ptr_Workgroup_v2float %m21 %int_0
-        %170 = OpAccessChain %_ptr_Workgroup_float %169 %int_0
-               OpStore %170 %float_1 None
-        %171 = OpAccessChain %_ptr_Workgroup_v2float %m22 %int_0
-        %172 = OpAccessChain %_ptr_Workgroup_float %171 %int_0
-               OpStore %172 %float_1 None
-        %173 = OpAccessChain %_ptr_Workgroup_v2float %m23 %int_0
-        %174 = OpAccessChain %_ptr_Workgroup_float %173 %int_0
-               OpStore %174 %float_1 None
-        %175 = OpAccessChain %_ptr_Workgroup_v2float %m24 %int_0
-        %176 = OpAccessChain %_ptr_Workgroup_float %175 %int_0
-               OpStore %176 %float_1 None
-        %177 = OpAccessChain %_ptr_Workgroup_v2float %m25 %int_0
-        %178 = OpAccessChain %_ptr_Workgroup_float %177 %int_0
-               OpStore %178 %float_1 None
-        %179 = OpAccessChain %_ptr_Workgroup_v2float %m26 %int_0
-        %180 = OpAccessChain %_ptr_Workgroup_float %179 %int_0
-               OpStore %180 %float_1 None
-        %181 = OpAccessChain %_ptr_Workgroup_v2float %m27 %int_0
-        %182 = OpAccessChain %_ptr_Workgroup_float %181 %int_0
-               OpStore %182 %float_1 None
-        %183 = OpAccessChain %_ptr_Workgroup_v2float %m28 %int_0
-        %184 = OpAccessChain %_ptr_Workgroup_float %183 %int_0
-               OpStore %184 %float_1 None
-        %185 = OpAccessChain %_ptr_Workgroup_v2float %m29 %int_0
-        %186 = OpAccessChain %_ptr_Workgroup_float %185 %int_0
-               OpStore %186 %float_1 None
-        %187 = OpAccessChain %_ptr_Workgroup_v2float %m30 %int_0
-        %188 = OpAccessChain %_ptr_Workgroup_float %187 %int_0
-               OpStore %188 %float_1 None
-        %189 = OpAccessChain %_ptr_Workgroup_v2float %m31 %int_0
-        %190 = OpAccessChain %_ptr_Workgroup_float %189 %int_0
-               OpStore %190 %float_1 None
-        %191 = OpAccessChain %_ptr_Workgroup_v2float %m32 %int_0
-        %192 = OpAccessChain %_ptr_Workgroup_float %191 %int_0
-               OpStore %192 %float_1 None
-        %193 = OpAccessChain %_ptr_Workgroup_v2float %m33 %int_0
-        %194 = OpAccessChain %_ptr_Workgroup_float %193 %int_0
-               OpStore %194 %float_1 None
-        %195 = OpAccessChain %_ptr_Workgroup_v2float %m34 %int_0
-        %196 = OpAccessChain %_ptr_Workgroup_float %195 %int_0
-               OpStore %196 %float_1 None
-        %197 = OpAccessChain %_ptr_Workgroup_v2float %m35 %int_0
-        %198 = OpAccessChain %_ptr_Workgroup_float %197 %int_0
-               OpStore %198 %float_1 None
-        %199 = OpAccessChain %_ptr_Workgroup_v2float %m36 %int_0
-        %200 = OpAccessChain %_ptr_Workgroup_float %199 %int_0
-               OpStore %200 %float_1 None
-        %201 = OpAccessChain %_ptr_Workgroup_v2float %m37 %int_0
-        %202 = OpAccessChain %_ptr_Workgroup_float %201 %int_0
-               OpStore %202 %float_1 None
-        %203 = OpAccessChain %_ptr_Workgroup_v2float %m38 %int_0
-        %204 = OpAccessChain %_ptr_Workgroup_float %203 %int_0
-               OpStore %204 %float_1 None
-        %205 = OpAccessChain %_ptr_Workgroup_v2float %m39 %int_0
-        %206 = OpAccessChain %_ptr_Workgroup_float %205 %int_0
-               OpStore %206 %float_1 None
-        %207 = OpAccessChain %_ptr_Workgroup_v2float %m40 %int_0
-        %208 = OpAccessChain %_ptr_Workgroup_float %207 %int_0
-               OpStore %208 %float_1 None
-        %209 = OpAccessChain %_ptr_Workgroup_v2float %m41 %int_0
-        %210 = OpAccessChain %_ptr_Workgroup_float %209 %int_0
-               OpStore %210 %float_1 None
-        %211 = OpAccessChain %_ptr_Workgroup_v2float %m42 %int_0
-        %212 = OpAccessChain %_ptr_Workgroup_float %211 %int_0
-               OpStore %212 %float_1 None
-        %213 = OpAccessChain %_ptr_Workgroup_v2float %m43 %int_0
-        %214 = OpAccessChain %_ptr_Workgroup_float %213 %int_0
-               OpStore %214 %float_1 None
-        %215 = OpAccessChain %_ptr_Workgroup_v2float %m44 %int_0
-        %216 = OpAccessChain %_ptr_Workgroup_float %215 %int_0
-               OpStore %216 %float_1 None
-        %217 = OpAccessChain %_ptr_Workgroup_v2float %m45 %int_0
-        %218 = OpAccessChain %_ptr_Workgroup_float %217 %int_0
-               OpStore %218 %float_1 None
-        %219 = OpAccessChain %_ptr_Workgroup_v2float %m46 %int_0
-        %220 = OpAccessChain %_ptr_Workgroup_float %219 %int_0
-               OpStore %220 %float_1 None
-        %221 = OpAccessChain %_ptr_Workgroup_v2float %m47 %int_0
-        %222 = OpAccessChain %_ptr_Workgroup_float %221 %int_0
-               OpStore %222 %float_1 None
-        %223 = OpAccessChain %_ptr_Workgroup_v2float %m48 %int_0
-        %224 = OpAccessChain %_ptr_Workgroup_float %223 %int_0
-               OpStore %224 %float_1 None
-        %225 = OpAccessChain %_ptr_Workgroup_v2float %m49 %int_0
-        %226 = OpAccessChain %_ptr_Workgroup_float %225 %int_0
-               OpStore %226 %float_1 None
-        %227 = OpAccessChain %_ptr_Workgroup_v2float %m50 %int_0
-        %228 = OpAccessChain %_ptr_Workgroup_float %227 %int_0
-               OpStore %228 %float_1 None
-        %229 = OpAccessChain %_ptr_Workgroup_v2float %m51 %int_0
-        %230 = OpAccessChain %_ptr_Workgroup_float %229 %int_0
-               OpStore %230 %float_1 None
-        %231 = OpAccessChain %_ptr_Workgroup_v2float %m52 %int_0
-        %232 = OpAccessChain %_ptr_Workgroup_float %231 %int_0
-               OpStore %232 %float_1 None
-        %233 = OpAccessChain %_ptr_Workgroup_v2float %m53 %int_0
-        %234 = OpAccessChain %_ptr_Workgroup_float %233 %int_0
-               OpStore %234 %float_1 None
-        %235 = OpAccessChain %_ptr_Workgroup_v2float %m54 %int_0
-        %236 = OpAccessChain %_ptr_Workgroup_float %235 %int_0
-               OpStore %236 %float_1 None
-        %237 = OpAccessChain %_ptr_Workgroup_v2float %m55 %int_0
-        %238 = OpAccessChain %_ptr_Workgroup_float %237 %int_0
-               OpStore %238 %float_1 None
-        %239 = OpAccessChain %_ptr_Workgroup_v2float %m56 %int_0
-        %240 = OpAccessChain %_ptr_Workgroup_float %239 %int_0
-               OpStore %240 %float_1 None
-        %241 = OpAccessChain %_ptr_Workgroup_v2float %m57 %int_0
-        %242 = OpAccessChain %_ptr_Workgroup_float %241 %int_0
-               OpStore %242 %float_1 None
-        %243 = OpAccessChain %_ptr_Workgroup_v2float %m58 %int_0
-        %244 = OpAccessChain %_ptr_Workgroup_float %243 %int_0
-               OpStore %244 %float_1 None
-        %245 = OpAccessChain %_ptr_Workgroup_v2float %m59 %int_0
-        %246 = OpAccessChain %_ptr_Workgroup_float %245 %int_0
-               OpStore %246 %float_1 None
-        %247 = OpAccessChain %_ptr_Workgroup_v2float %m60 %int_0
-        %248 = OpAccessChain %_ptr_Workgroup_float %247 %int_0
-               OpStore %248 %float_1 None
-        %249 = OpAccessChain %_ptr_Workgroup_v2float %m61 %int_0
-        %250 = OpAccessChain %_ptr_Workgroup_float %249 %int_0
-               OpStore %250 %float_1 None
-        %251 = OpAccessChain %_ptr_Workgroup_v2float %m62 %int_0
-        %252 = OpAccessChain %_ptr_Workgroup_float %251 %int_0
-               OpStore %252 %float_1 None
-        %253 = OpAccessChain %_ptr_Workgroup_v2float %m63 %int_0
-        %254 = OpAccessChain %_ptr_Workgroup_float %253 %int_0
-               OpStore %254 %float_1 None
-        %255 = OpAccessChain %_ptr_Workgroup_v2float %m64 %int_0
-        %256 = OpAccessChain %_ptr_Workgroup_float %255 %int_0
-               OpStore %256 %float_1 None
-        %257 = OpAccessChain %_ptr_Workgroup_v2float %m65 %int_0
-        %258 = OpAccessChain %_ptr_Workgroup_float %257 %int_0
-               OpStore %258 %float_1 None
-        %259 = OpAccessChain %_ptr_Workgroup_v2float %m66 %int_0
-        %260 = OpAccessChain %_ptr_Workgroup_float %259 %int_0
-               OpStore %260 %float_1 None
-        %261 = OpAccessChain %_ptr_Workgroup_v2float %m67 %int_0
-        %262 = OpAccessChain %_ptr_Workgroup_float %261 %int_0
-               OpStore %262 %float_1 None
-        %263 = OpAccessChain %_ptr_Workgroup_v2float %m68 %int_0
-        %264 = OpAccessChain %_ptr_Workgroup_float %263 %int_0
-               OpStore %264 %float_1 None
-        %265 = OpAccessChain %_ptr_Workgroup_v2float %m69 %int_0
-        %266 = OpAccessChain %_ptr_Workgroup_float %265 %int_0
-               OpStore %266 %float_1 None
-        %267 = OpAccessChain %_ptr_Workgroup_v2float %m70 %int_0
-        %268 = OpAccessChain %_ptr_Workgroup_float %267 %int_0
-               OpStore %268 %float_1 None
-        %269 = OpAccessChain %_ptr_Workgroup_v2float %m71 %int_0
-        %270 = OpAccessChain %_ptr_Workgroup_float %269 %int_0
-               OpStore %270 %float_1 None
-        %271 = OpAccessChain %_ptr_Workgroup_v2float %m72 %int_0
-        %272 = OpAccessChain %_ptr_Workgroup_float %271 %int_0
-               OpStore %272 %float_1 None
-        %273 = OpAccessChain %_ptr_Workgroup_v2float %m73 %int_0
-        %274 = OpAccessChain %_ptr_Workgroup_float %273 %int_0
-               OpStore %274 %float_1 None
-        %275 = OpAccessChain %_ptr_Workgroup_v2float %m74 %int_0
-        %276 = OpAccessChain %_ptr_Workgroup_float %275 %int_0
-               OpStore %276 %float_1 None
-        %277 = OpAccessChain %_ptr_Workgroup_v2float %m75 %int_0
-        %278 = OpAccessChain %_ptr_Workgroup_float %277 %int_0
-               OpStore %278 %float_1 None
-        %279 = OpAccessChain %_ptr_Workgroup_v2float %m76 %int_0
-        %280 = OpAccessChain %_ptr_Workgroup_float %279 %int_0
-               OpStore %280 %float_1 None
-        %281 = OpAccessChain %_ptr_Workgroup_v2float %m77 %int_0
-        %282 = OpAccessChain %_ptr_Workgroup_float %281 %int_0
-               OpStore %282 %float_1 None
-        %283 = OpAccessChain %_ptr_Workgroup_v2float %m78 %int_0
-        %284 = OpAccessChain %_ptr_Workgroup_float %283 %int_0
-               OpStore %284 %float_1 None
-        %285 = OpAccessChain %_ptr_Workgroup_v2float %m79 %int_0
-        %286 = OpAccessChain %_ptr_Workgroup_float %285 %int_0
-               OpStore %286 %float_1 None
-        %287 = OpAccessChain %_ptr_Workgroup_v2float %m80 %int_0
-        %288 = OpAccessChain %_ptr_Workgroup_float %287 %int_0
-               OpStore %288 %float_1 None
-        %289 = OpAccessChain %_ptr_Workgroup_v2float %m81 %int_0
-        %290 = OpAccessChain %_ptr_Workgroup_float %289 %int_0
-               OpStore %290 %float_1 None
-        %291 = OpAccessChain %_ptr_Workgroup_v2float %m82 %int_0
-        %292 = OpAccessChain %_ptr_Workgroup_float %291 %int_0
-               OpStore %292 %float_1 None
-        %293 = OpAccessChain %_ptr_Workgroup_v2float %m83 %int_0
-        %294 = OpAccessChain %_ptr_Workgroup_float %293 %int_0
-               OpStore %294 %float_1 None
-        %295 = OpAccessChain %_ptr_Workgroup_v2float %m84 %int_0
-        %296 = OpAccessChain %_ptr_Workgroup_float %295 %int_0
-               OpStore %296 %float_1 None
-        %297 = OpAccessChain %_ptr_Workgroup_v2float %m85 %int_0
-        %298 = OpAccessChain %_ptr_Workgroup_float %297 %int_0
-               OpStore %298 %float_1 None
-        %299 = OpAccessChain %_ptr_Workgroup_v2float %m86 %int_0
-        %300 = OpAccessChain %_ptr_Workgroup_float %299 %int_0
-               OpStore %300 %float_1 None
-        %301 = OpAccessChain %_ptr_Workgroup_v2float %m87 %int_0
-        %302 = OpAccessChain %_ptr_Workgroup_float %301 %int_0
-               OpStore %302 %float_1 None
-        %303 = OpAccessChain %_ptr_Workgroup_v2float %m88 %int_0
-        %304 = OpAccessChain %_ptr_Workgroup_float %303 %int_0
-               OpStore %304 %float_1 None
-        %305 = OpAccessChain %_ptr_Workgroup_v2float %m89 %int_0
-        %306 = OpAccessChain %_ptr_Workgroup_float %305 %int_0
-               OpStore %306 %float_1 None
-        %307 = OpAccessChain %_ptr_Workgroup_v2float %m90 %int_0
-        %308 = OpAccessChain %_ptr_Workgroup_float %307 %int_0
-               OpStore %308 %float_1 None
-        %309 = OpAccessChain %_ptr_Workgroup_v2float %m91 %int_0
-        %310 = OpAccessChain %_ptr_Workgroup_float %309 %int_0
-               OpStore %310 %float_1 None
-        %311 = OpAccessChain %_ptr_Workgroup_v2float %m92 %int_0
-        %312 = OpAccessChain %_ptr_Workgroup_float %311 %int_0
-               OpStore %312 %float_1 None
-        %313 = OpAccessChain %_ptr_Workgroup_v2float %m93 %int_0
-        %314 = OpAccessChain %_ptr_Workgroup_float %313 %int_0
-               OpStore %314 %float_1 None
-        %315 = OpAccessChain %_ptr_Workgroup_v2float %m94 %int_0
-        %316 = OpAccessChain %_ptr_Workgroup_float %315 %int_0
-               OpStore %316 %float_1 None
-        %317 = OpAccessChain %_ptr_Workgroup_v2float %m95 %int_0
-        %318 = OpAccessChain %_ptr_Workgroup_float %317 %int_0
-               OpStore %318 %float_1 None
-        %319 = OpAccessChain %_ptr_Workgroup_v2float %m96 %int_0
-        %320 = OpAccessChain %_ptr_Workgroup_float %319 %int_0
-               OpStore %320 %float_1 None
-        %321 = OpAccessChain %_ptr_Workgroup_v2float %m97 %int_0
-        %322 = OpAccessChain %_ptr_Workgroup_float %321 %int_0
-               OpStore %322 %float_1 None
-        %323 = OpAccessChain %_ptr_Workgroup_v2float %m98 %int_0
-        %324 = OpAccessChain %_ptr_Workgroup_float %323 %int_0
-               OpStore %324 %float_1 None
-        %325 = OpAccessChain %_ptr_Workgroup_v2float %m99 %int_0
-        %326 = OpAccessChain %_ptr_Workgroup_float %325 %int_0
-               OpStore %326 %float_1 None
+        %122 = OpAccessChain %_ptr_Workgroup_v2float %m00 %uint_0
+        %125 = OpAccessChain %_ptr_Workgroup_float %122 %uint_0
+               OpStore %125 %float_1 None
+        %128 = OpAccessChain %_ptr_Workgroup_v2float %m01 %uint_0
+        %129 = OpAccessChain %_ptr_Workgroup_float %128 %uint_0
+               OpStore %129 %float_1 None
+        %130 = OpAccessChain %_ptr_Workgroup_v2float %m02 %uint_0
+        %131 = OpAccessChain %_ptr_Workgroup_float %130 %uint_0
+               OpStore %131 %float_1 None
+        %132 = OpAccessChain %_ptr_Workgroup_v2float %m03 %uint_0
+        %133 = OpAccessChain %_ptr_Workgroup_float %132 %uint_0
+               OpStore %133 %float_1 None
+        %134 = OpAccessChain %_ptr_Workgroup_v2float %m04 %uint_0
+        %135 = OpAccessChain %_ptr_Workgroup_float %134 %uint_0
+               OpStore %135 %float_1 None
+        %136 = OpAccessChain %_ptr_Workgroup_v2float %m05 %uint_0
+        %137 = OpAccessChain %_ptr_Workgroup_float %136 %uint_0
+               OpStore %137 %float_1 None
+        %138 = OpAccessChain %_ptr_Workgroup_v2float %m06 %uint_0
+        %139 = OpAccessChain %_ptr_Workgroup_float %138 %uint_0
+               OpStore %139 %float_1 None
+        %140 = OpAccessChain %_ptr_Workgroup_v2float %m07 %uint_0
+        %141 = OpAccessChain %_ptr_Workgroup_float %140 %uint_0
+               OpStore %141 %float_1 None
+        %142 = OpAccessChain %_ptr_Workgroup_v2float %m08 %uint_0
+        %143 = OpAccessChain %_ptr_Workgroup_float %142 %uint_0
+               OpStore %143 %float_1 None
+        %144 = OpAccessChain %_ptr_Workgroup_v2float %m09 %uint_0
+        %145 = OpAccessChain %_ptr_Workgroup_float %144 %uint_0
+               OpStore %145 %float_1 None
+        %146 = OpAccessChain %_ptr_Workgroup_v2float %m10 %uint_0
+        %147 = OpAccessChain %_ptr_Workgroup_float %146 %uint_0
+               OpStore %147 %float_1 None
+        %148 = OpAccessChain %_ptr_Workgroup_v2float %m11 %uint_0
+        %149 = OpAccessChain %_ptr_Workgroup_float %148 %uint_0
+               OpStore %149 %float_1 None
+        %150 = OpAccessChain %_ptr_Workgroup_v2float %m12 %uint_0
+        %151 = OpAccessChain %_ptr_Workgroup_float %150 %uint_0
+               OpStore %151 %float_1 None
+        %152 = OpAccessChain %_ptr_Workgroup_v2float %m13 %uint_0
+        %153 = OpAccessChain %_ptr_Workgroup_float %152 %uint_0
+               OpStore %153 %float_1 None
+        %154 = OpAccessChain %_ptr_Workgroup_v2float %m14 %uint_0
+        %155 = OpAccessChain %_ptr_Workgroup_float %154 %uint_0
+               OpStore %155 %float_1 None
+        %156 = OpAccessChain %_ptr_Workgroup_v2float %m15 %uint_0
+        %157 = OpAccessChain %_ptr_Workgroup_float %156 %uint_0
+               OpStore %157 %float_1 None
+        %158 = OpAccessChain %_ptr_Workgroup_v2float %m16 %uint_0
+        %159 = OpAccessChain %_ptr_Workgroup_float %158 %uint_0
+               OpStore %159 %float_1 None
+        %160 = OpAccessChain %_ptr_Workgroup_v2float %m17 %uint_0
+        %161 = OpAccessChain %_ptr_Workgroup_float %160 %uint_0
+               OpStore %161 %float_1 None
+        %162 = OpAccessChain %_ptr_Workgroup_v2float %m18 %uint_0
+        %163 = OpAccessChain %_ptr_Workgroup_float %162 %uint_0
+               OpStore %163 %float_1 None
+        %164 = OpAccessChain %_ptr_Workgroup_v2float %m19 %uint_0
+        %165 = OpAccessChain %_ptr_Workgroup_float %164 %uint_0
+               OpStore %165 %float_1 None
+        %166 = OpAccessChain %_ptr_Workgroup_v2float %m20 %uint_0
+        %167 = OpAccessChain %_ptr_Workgroup_float %166 %uint_0
+               OpStore %167 %float_1 None
+        %168 = OpAccessChain %_ptr_Workgroup_v2float %m21 %uint_0
+        %169 = OpAccessChain %_ptr_Workgroup_float %168 %uint_0
+               OpStore %169 %float_1 None
+        %170 = OpAccessChain %_ptr_Workgroup_v2float %m22 %uint_0
+        %171 = OpAccessChain %_ptr_Workgroup_float %170 %uint_0
+               OpStore %171 %float_1 None
+        %172 = OpAccessChain %_ptr_Workgroup_v2float %m23 %uint_0
+        %173 = OpAccessChain %_ptr_Workgroup_float %172 %uint_0
+               OpStore %173 %float_1 None
+        %174 = OpAccessChain %_ptr_Workgroup_v2float %m24 %uint_0
+        %175 = OpAccessChain %_ptr_Workgroup_float %174 %uint_0
+               OpStore %175 %float_1 None
+        %176 = OpAccessChain %_ptr_Workgroup_v2float %m25 %uint_0
+        %177 = OpAccessChain %_ptr_Workgroup_float %176 %uint_0
+               OpStore %177 %float_1 None
+        %178 = OpAccessChain %_ptr_Workgroup_v2float %m26 %uint_0
+        %179 = OpAccessChain %_ptr_Workgroup_float %178 %uint_0
+               OpStore %179 %float_1 None
+        %180 = OpAccessChain %_ptr_Workgroup_v2float %m27 %uint_0
+        %181 = OpAccessChain %_ptr_Workgroup_float %180 %uint_0
+               OpStore %181 %float_1 None
+        %182 = OpAccessChain %_ptr_Workgroup_v2float %m28 %uint_0
+        %183 = OpAccessChain %_ptr_Workgroup_float %182 %uint_0
+               OpStore %183 %float_1 None
+        %184 = OpAccessChain %_ptr_Workgroup_v2float %m29 %uint_0
+        %185 = OpAccessChain %_ptr_Workgroup_float %184 %uint_0
+               OpStore %185 %float_1 None
+        %186 = OpAccessChain %_ptr_Workgroup_v2float %m30 %uint_0
+        %187 = OpAccessChain %_ptr_Workgroup_float %186 %uint_0
+               OpStore %187 %float_1 None
+        %188 = OpAccessChain %_ptr_Workgroup_v2float %m31 %uint_0
+        %189 = OpAccessChain %_ptr_Workgroup_float %188 %uint_0
+               OpStore %189 %float_1 None
+        %190 = OpAccessChain %_ptr_Workgroup_v2float %m32 %uint_0
+        %191 = OpAccessChain %_ptr_Workgroup_float %190 %uint_0
+               OpStore %191 %float_1 None
+        %192 = OpAccessChain %_ptr_Workgroup_v2float %m33 %uint_0
+        %193 = OpAccessChain %_ptr_Workgroup_float %192 %uint_0
+               OpStore %193 %float_1 None
+        %194 = OpAccessChain %_ptr_Workgroup_v2float %m34 %uint_0
+        %195 = OpAccessChain %_ptr_Workgroup_float %194 %uint_0
+               OpStore %195 %float_1 None
+        %196 = OpAccessChain %_ptr_Workgroup_v2float %m35 %uint_0
+        %197 = OpAccessChain %_ptr_Workgroup_float %196 %uint_0
+               OpStore %197 %float_1 None
+        %198 = OpAccessChain %_ptr_Workgroup_v2float %m36 %uint_0
+        %199 = OpAccessChain %_ptr_Workgroup_float %198 %uint_0
+               OpStore %199 %float_1 None
+        %200 = OpAccessChain %_ptr_Workgroup_v2float %m37 %uint_0
+        %201 = OpAccessChain %_ptr_Workgroup_float %200 %uint_0
+               OpStore %201 %float_1 None
+        %202 = OpAccessChain %_ptr_Workgroup_v2float %m38 %uint_0
+        %203 = OpAccessChain %_ptr_Workgroup_float %202 %uint_0
+               OpStore %203 %float_1 None
+        %204 = OpAccessChain %_ptr_Workgroup_v2float %m39 %uint_0
+        %205 = OpAccessChain %_ptr_Workgroup_float %204 %uint_0
+               OpStore %205 %float_1 None
+        %206 = OpAccessChain %_ptr_Workgroup_v2float %m40 %uint_0
+        %207 = OpAccessChain %_ptr_Workgroup_float %206 %uint_0
+               OpStore %207 %float_1 None
+        %208 = OpAccessChain %_ptr_Workgroup_v2float %m41 %uint_0
+        %209 = OpAccessChain %_ptr_Workgroup_float %208 %uint_0
+               OpStore %209 %float_1 None
+        %210 = OpAccessChain %_ptr_Workgroup_v2float %m42 %uint_0
+        %211 = OpAccessChain %_ptr_Workgroup_float %210 %uint_0
+               OpStore %211 %float_1 None
+        %212 = OpAccessChain %_ptr_Workgroup_v2float %m43 %uint_0
+        %213 = OpAccessChain %_ptr_Workgroup_float %212 %uint_0
+               OpStore %213 %float_1 None
+        %214 = OpAccessChain %_ptr_Workgroup_v2float %m44 %uint_0
+        %215 = OpAccessChain %_ptr_Workgroup_float %214 %uint_0
+               OpStore %215 %float_1 None
+        %216 = OpAccessChain %_ptr_Workgroup_v2float %m45 %uint_0
+        %217 = OpAccessChain %_ptr_Workgroup_float %216 %uint_0
+               OpStore %217 %float_1 None
+        %218 = OpAccessChain %_ptr_Workgroup_v2float %m46 %uint_0
+        %219 = OpAccessChain %_ptr_Workgroup_float %218 %uint_0
+               OpStore %219 %float_1 None
+        %220 = OpAccessChain %_ptr_Workgroup_v2float %m47 %uint_0
+        %221 = OpAccessChain %_ptr_Workgroup_float %220 %uint_0
+               OpStore %221 %float_1 None
+        %222 = OpAccessChain %_ptr_Workgroup_v2float %m48 %uint_0
+        %223 = OpAccessChain %_ptr_Workgroup_float %222 %uint_0
+               OpStore %223 %float_1 None
+        %224 = OpAccessChain %_ptr_Workgroup_v2float %m49 %uint_0
+        %225 = OpAccessChain %_ptr_Workgroup_float %224 %uint_0
+               OpStore %225 %float_1 None
+        %226 = OpAccessChain %_ptr_Workgroup_v2float %m50 %uint_0
+        %227 = OpAccessChain %_ptr_Workgroup_float %226 %uint_0
+               OpStore %227 %float_1 None
+        %228 = OpAccessChain %_ptr_Workgroup_v2float %m51 %uint_0
+        %229 = OpAccessChain %_ptr_Workgroup_float %228 %uint_0
+               OpStore %229 %float_1 None
+        %230 = OpAccessChain %_ptr_Workgroup_v2float %m52 %uint_0
+        %231 = OpAccessChain %_ptr_Workgroup_float %230 %uint_0
+               OpStore %231 %float_1 None
+        %232 = OpAccessChain %_ptr_Workgroup_v2float %m53 %uint_0
+        %233 = OpAccessChain %_ptr_Workgroup_float %232 %uint_0
+               OpStore %233 %float_1 None
+        %234 = OpAccessChain %_ptr_Workgroup_v2float %m54 %uint_0
+        %235 = OpAccessChain %_ptr_Workgroup_float %234 %uint_0
+               OpStore %235 %float_1 None
+        %236 = OpAccessChain %_ptr_Workgroup_v2float %m55 %uint_0
+        %237 = OpAccessChain %_ptr_Workgroup_float %236 %uint_0
+               OpStore %237 %float_1 None
+        %238 = OpAccessChain %_ptr_Workgroup_v2float %m56 %uint_0
+        %239 = OpAccessChain %_ptr_Workgroup_float %238 %uint_0
+               OpStore %239 %float_1 None
+        %240 = OpAccessChain %_ptr_Workgroup_v2float %m57 %uint_0
+        %241 = OpAccessChain %_ptr_Workgroup_float %240 %uint_0
+               OpStore %241 %float_1 None
+        %242 = OpAccessChain %_ptr_Workgroup_v2float %m58 %uint_0
+        %243 = OpAccessChain %_ptr_Workgroup_float %242 %uint_0
+               OpStore %243 %float_1 None
+        %244 = OpAccessChain %_ptr_Workgroup_v2float %m59 %uint_0
+        %245 = OpAccessChain %_ptr_Workgroup_float %244 %uint_0
+               OpStore %245 %float_1 None
+        %246 = OpAccessChain %_ptr_Workgroup_v2float %m60 %uint_0
+        %247 = OpAccessChain %_ptr_Workgroup_float %246 %uint_0
+               OpStore %247 %float_1 None
+        %248 = OpAccessChain %_ptr_Workgroup_v2float %m61 %uint_0
+        %249 = OpAccessChain %_ptr_Workgroup_float %248 %uint_0
+               OpStore %249 %float_1 None
+        %250 = OpAccessChain %_ptr_Workgroup_v2float %m62 %uint_0
+        %251 = OpAccessChain %_ptr_Workgroup_float %250 %uint_0
+               OpStore %251 %float_1 None
+        %252 = OpAccessChain %_ptr_Workgroup_v2float %m63 %uint_0
+        %253 = OpAccessChain %_ptr_Workgroup_float %252 %uint_0
+               OpStore %253 %float_1 None
+        %254 = OpAccessChain %_ptr_Workgroup_v2float %m64 %uint_0
+        %255 = OpAccessChain %_ptr_Workgroup_float %254 %uint_0
+               OpStore %255 %float_1 None
+        %256 = OpAccessChain %_ptr_Workgroup_v2float %m65 %uint_0
+        %257 = OpAccessChain %_ptr_Workgroup_float %256 %uint_0
+               OpStore %257 %float_1 None
+        %258 = OpAccessChain %_ptr_Workgroup_v2float %m66 %uint_0
+        %259 = OpAccessChain %_ptr_Workgroup_float %258 %uint_0
+               OpStore %259 %float_1 None
+        %260 = OpAccessChain %_ptr_Workgroup_v2float %m67 %uint_0
+        %261 = OpAccessChain %_ptr_Workgroup_float %260 %uint_0
+               OpStore %261 %float_1 None
+        %262 = OpAccessChain %_ptr_Workgroup_v2float %m68 %uint_0
+        %263 = OpAccessChain %_ptr_Workgroup_float %262 %uint_0
+               OpStore %263 %float_1 None
+        %264 = OpAccessChain %_ptr_Workgroup_v2float %m69 %uint_0
+        %265 = OpAccessChain %_ptr_Workgroup_float %264 %uint_0
+               OpStore %265 %float_1 None
+        %266 = OpAccessChain %_ptr_Workgroup_v2float %m70 %uint_0
+        %267 = OpAccessChain %_ptr_Workgroup_float %266 %uint_0
+               OpStore %267 %float_1 None
+        %268 = OpAccessChain %_ptr_Workgroup_v2float %m71 %uint_0
+        %269 = OpAccessChain %_ptr_Workgroup_float %268 %uint_0
+               OpStore %269 %float_1 None
+        %270 = OpAccessChain %_ptr_Workgroup_v2float %m72 %uint_0
+        %271 = OpAccessChain %_ptr_Workgroup_float %270 %uint_0
+               OpStore %271 %float_1 None
+        %272 = OpAccessChain %_ptr_Workgroup_v2float %m73 %uint_0
+        %273 = OpAccessChain %_ptr_Workgroup_float %272 %uint_0
+               OpStore %273 %float_1 None
+        %274 = OpAccessChain %_ptr_Workgroup_v2float %m74 %uint_0
+        %275 = OpAccessChain %_ptr_Workgroup_float %274 %uint_0
+               OpStore %275 %float_1 None
+        %276 = OpAccessChain %_ptr_Workgroup_v2float %m75 %uint_0
+        %277 = OpAccessChain %_ptr_Workgroup_float %276 %uint_0
+               OpStore %277 %float_1 None
+        %278 = OpAccessChain %_ptr_Workgroup_v2float %m76 %uint_0
+        %279 = OpAccessChain %_ptr_Workgroup_float %278 %uint_0
+               OpStore %279 %float_1 None
+        %280 = OpAccessChain %_ptr_Workgroup_v2float %m77 %uint_0
+        %281 = OpAccessChain %_ptr_Workgroup_float %280 %uint_0
+               OpStore %281 %float_1 None
+        %282 = OpAccessChain %_ptr_Workgroup_v2float %m78 %uint_0
+        %283 = OpAccessChain %_ptr_Workgroup_float %282 %uint_0
+               OpStore %283 %float_1 None
+        %284 = OpAccessChain %_ptr_Workgroup_v2float %m79 %uint_0
+        %285 = OpAccessChain %_ptr_Workgroup_float %284 %uint_0
+               OpStore %285 %float_1 None
+        %286 = OpAccessChain %_ptr_Workgroup_v2float %m80 %uint_0
+        %287 = OpAccessChain %_ptr_Workgroup_float %286 %uint_0
+               OpStore %287 %float_1 None
+        %288 = OpAccessChain %_ptr_Workgroup_v2float %m81 %uint_0
+        %289 = OpAccessChain %_ptr_Workgroup_float %288 %uint_0
+               OpStore %289 %float_1 None
+        %290 = OpAccessChain %_ptr_Workgroup_v2float %m82 %uint_0
+        %291 = OpAccessChain %_ptr_Workgroup_float %290 %uint_0
+               OpStore %291 %float_1 None
+        %292 = OpAccessChain %_ptr_Workgroup_v2float %m83 %uint_0
+        %293 = OpAccessChain %_ptr_Workgroup_float %292 %uint_0
+               OpStore %293 %float_1 None
+        %294 = OpAccessChain %_ptr_Workgroup_v2float %m84 %uint_0
+        %295 = OpAccessChain %_ptr_Workgroup_float %294 %uint_0
+               OpStore %295 %float_1 None
+        %296 = OpAccessChain %_ptr_Workgroup_v2float %m85 %uint_0
+        %297 = OpAccessChain %_ptr_Workgroup_float %296 %uint_0
+               OpStore %297 %float_1 None
+        %298 = OpAccessChain %_ptr_Workgroup_v2float %m86 %uint_0
+        %299 = OpAccessChain %_ptr_Workgroup_float %298 %uint_0
+               OpStore %299 %float_1 None
+        %300 = OpAccessChain %_ptr_Workgroup_v2float %m87 %uint_0
+        %301 = OpAccessChain %_ptr_Workgroup_float %300 %uint_0
+               OpStore %301 %float_1 None
+        %302 = OpAccessChain %_ptr_Workgroup_v2float %m88 %uint_0
+        %303 = OpAccessChain %_ptr_Workgroup_float %302 %uint_0
+               OpStore %303 %float_1 None
+        %304 = OpAccessChain %_ptr_Workgroup_v2float %m89 %uint_0
+        %305 = OpAccessChain %_ptr_Workgroup_float %304 %uint_0
+               OpStore %305 %float_1 None
+        %306 = OpAccessChain %_ptr_Workgroup_v2float %m90 %uint_0
+        %307 = OpAccessChain %_ptr_Workgroup_float %306 %uint_0
+               OpStore %307 %float_1 None
+        %308 = OpAccessChain %_ptr_Workgroup_v2float %m91 %uint_0
+        %309 = OpAccessChain %_ptr_Workgroup_float %308 %uint_0
+               OpStore %309 %float_1 None
+        %310 = OpAccessChain %_ptr_Workgroup_v2float %m92 %uint_0
+        %311 = OpAccessChain %_ptr_Workgroup_float %310 %uint_0
+               OpStore %311 %float_1 None
+        %312 = OpAccessChain %_ptr_Workgroup_v2float %m93 %uint_0
+        %313 = OpAccessChain %_ptr_Workgroup_float %312 %uint_0
+               OpStore %313 %float_1 None
+        %314 = OpAccessChain %_ptr_Workgroup_v2float %m94 %uint_0
+        %315 = OpAccessChain %_ptr_Workgroup_float %314 %uint_0
+               OpStore %315 %float_1 None
+        %316 = OpAccessChain %_ptr_Workgroup_v2float %m95 %uint_0
+        %317 = OpAccessChain %_ptr_Workgroup_float %316 %uint_0
+               OpStore %317 %float_1 None
+        %318 = OpAccessChain %_ptr_Workgroup_v2float %m96 %uint_0
+        %319 = OpAccessChain %_ptr_Workgroup_float %318 %uint_0
+               OpStore %319 %float_1 None
+        %320 = OpAccessChain %_ptr_Workgroup_v2float %m97 %uint_0
+        %321 = OpAccessChain %_ptr_Workgroup_float %320 %uint_0
+               OpStore %321 %float_1 None
+        %322 = OpAccessChain %_ptr_Workgroup_v2float %m98 %uint_0
+        %323 = OpAccessChain %_ptr_Workgroup_float %322 %uint_0
+               OpStore %323 %float_1 None
+        %324 = OpAccessChain %_ptr_Workgroup_v2float %m99 %uint_0
+        %325 = OpAccessChain %_ptr_Workgroup_float %324 %uint_0
+               OpStore %325 %float_1 None
                OpReturn
                OpFunctionEnd
-%tint_symbol = OpFunction %void None %328
-        %329 = OpLabel
-        %330 = OpLoad %uint %tint_symbol_local_invocation_index_Input None
-        %331 = OpFunctionCall %void %tint_symbol_inner %330
+%tint_symbol = OpFunction %void None %327
+        %328 = OpLabel
+        %329 = OpLoad %uint %tint_symbol_local_invocation_index_Input None
+        %330 = OpFunctionCall %void %tint_symbol_inner %329
                OpReturn
                OpFunctionEnd